Instruction file imported from JKorf/Aster.Net (
.cursor/rules/aster-net.mdc). Copyright stays with the author.
Aster.Net Conventions
This codebase uses Aster.Net for Aster DEX exchange access. Do not write raw HttpClient calls to Aster endpoints.
Client setup pattern
using Aster.Net;
using Aster.Net.Clients;
using Aster.Net.Objects;
var restClient = new AsterRestClient(options =>
{
options.ApiCredentials = new AsterCredentials()
.WithV3("USER_PRIVATE_KEY", "SIGNER_PRIVATE_KEY");
});
For public market data only, no credentials are needed: new AsterRestClient().
Result pattern
All methods return WebCallResult<T> (REST) or CallResult<T> (WebSocket). Always check .Success before reading .Data:
var ticker = await restClient.SpotV3Api.ExchangeData.GetTickerAsync("BTCUSDT");
if (!ticker.Success) { /* ticker.Error */ return; }
var price = ticker.Data.LastPrice;
API surface
Prefer the V3 API branches for new code:
restClient.SpotV3Api.{ExchangeData|Account|Trading}restClient.FuturesV3Api.{ExchangeData|Account|Trading}socketClient.SpotV3Apifor Spot WebSocket subscriptionssocketClient.FuturesV3Apifor Futures WebSocket subscriptions
V1 branches (SpotApi, FuturesApi) exist for compatibility, but AI-generated examples should use V3 unless the user explicitly asks otherwise.
Order placement
Let the library auto-generate clientOrderId. Do not pass a custom one unless required for an existing operational flow:
var order = await restClient.SpotV3Api.Trading.PlaceOrderAsync(
"BTCUSDT", OrderSide.Buy, OrderType.Limit,
quantity: 0.001m, price: 50000m, timeInForce: TimeInForce.GoodTillCanceled);
WebSocket pattern
var socketClient = new AsterSocketClient();
var sub = await socketClient.SpotV3Api.SubscribeToTickerUpdatesAsync(
"BTCUSDT",
update => { /* update.Data.LastPrice */ });
if (!sub.Success) { /* sub.Error */ return; }
// On shutdown:
await socketClient.UnsubscribeAsync(sub.Data);
Multi-exchange code
For exchange-agnostic code, use CryptoExchange.Net.SharedApis:
using CryptoExchange.Net.SharedApis;
var shared = new AsterRestClient().SpotV3Api.SharedClient;
var ticker = await shared.GetSpotTickerAsync(
new GetTickerRequest(new SharedSymbol(TradingMode.Spot, "BTC", "USDT")));
Same pattern works against BinanceRestClient().SpotApi.SharedClient, OKXRestClient().UnifiedApi.SharedClient, BybitRestClient().V5Api.SharedClient, and other CryptoExchange.Net libraries.
For shared V3 symbol discovery, use ISpotSymbolRestClient.GetSpotSymbolsAsync(...) or IFuturesSymbolRestClient.GetFuturesSymbolsAsync(...). These methods honor GetSymbolsRequest asset-type filters and populate display/asset metadata. Only read SpotSymbolCatalog or FuturesSymbolCatalog after the corresponding symbol query has succeeded.
Shared book ticker, position, and user trade quantities use SharedOrderQuantity; select QuantityInBaseAsset, QuantityInQuoteAsset, or QuantityInContracts instead of treating them as decimal. Aster shared order books use SharedQuantityType.BaseAsset.
Hard rules
- Never write raw
HttpClientto Aster endpoints. - Never use
.Resultor.Wait(); use async all the way. - Never instantiate clients per request; reuse them or use DI.
- Never skip checking
WebCallResult.Success. - Prefer
AsterRestClientandAsterSocketClient. - Prefer V3 API roots:
SpotV3ApiandFuturesV3Api. - Never pass a custom
clientOrderIdtoPlaceOrderAsyncunless required. - Always use
AsterCredentials().WithV3("userPrivateKey", "signerPrivateKey")ornew AsterCredentials(new AsterV3Credential(...))for V3, not genericApiCredentials. - Always store WebSocket subscriptions and unsubscribe on shutdown.
- Always use
.SharedClientfrom V3 branches for cross-exchange code.
Reference
- Skill:
AGENTS.mdin repo root has fuller examples llms.txtin repo root for AI context- Examples:
Examples/ai-friendly/