@gala-chain/gswap-sdk 1.2.0-rc.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +25 -10
  2. package/dist/browser/classes/dex_fees.js.map +1 -1
  3. package/dist/browser/classes/gateway.js.map +1 -1
  4. package/dist/browser/classes/gdex_stream.js.map +1 -1
  5. package/dist/browser/classes/gswap.js.map +1 -1
  6. package/dist/browser/classes/gswap_sdk_error.js.map +1 -1
  7. package/dist/browser/classes/pending_swap_fate.js +2 -0
  8. package/dist/browser/classes/pending_swap_fate.js.map +1 -0
  9. package/dist/browser/classes/pending_swaps.js +1 -1
  10. package/dist/browser/classes/pending_swaps.js.map +1 -1
  11. package/dist/browser/classes/positions.js +1 -1
  12. package/dist/browser/classes/positions.js.map +1 -1
  13. package/dist/browser/classes/shadow_submit.js +1 -1
  14. package/dist/browser/classes/shadow_submit.js.map +1 -1
  15. package/dist/browser/classes/signers.js.map +1 -1
  16. package/dist/browser/classes/storage_adapters.js +2 -0
  17. package/dist/browser/classes/storage_adapters.js.map +1 -0
  18. package/dist/browser/classes/submitted_transaction.js.map +1 -1
  19. package/dist/browser/classes/symbols.js +1 -1
  20. package/dist/browser/classes/symbols.js.map +1 -1
  21. package/dist/browser/index.js +1 -1
  22. package/dist/browser/utils/chain_dto_signing.js.map +1 -1
  23. package/dist/browser/utils/class_key.js +2 -0
  24. package/dist/browser/utils/class_key.js.map +1 -0
  25. package/dist/browser/utils/classification.js +2 -0
  26. package/dist/browser/utils/classification.js.map +1 -0
  27. package/dist/browser/utils/dto_builders.js +1 -1
  28. package/dist/browser/utils/dto_builders.js.map +1 -1
  29. package/dist/browser/utils/eip712.js.map +1 -1
  30. package/dist/browser/utils/failure_classification.js +1 -1
  31. package/dist/browser/utils/failure_classification.js.map +1 -1
  32. package/dist/browser/utils/failure_guards.js +2 -0
  33. package/dist/browser/utils/failure_guards.js.map +1 -0
  34. package/dist/browser/utils/ordering.js +1 -1
  35. package/dist/browser/utils/ordering.js.map +1 -1
  36. package/dist/browser/utils/tick_align.js +2 -0
  37. package/dist/browser/utils/tick_align.js.map +1 -0
  38. package/dist/browser/utils/tick_math.js +2 -0
  39. package/dist/browser/utils/tick_math.js.map +1 -0
  40. package/dist/browser/utils/tick_range.js +2 -0
  41. package/dist/browser/utils/tick_range.js.map +1 -0
  42. package/dist/browser/utils/ticks.js +1 -1
  43. package/dist/browser/utils/ticks.js.map +1 -1
  44. package/dist/browser/utils/transport.js +1 -1
  45. package/dist/browser/utils/transport.js.map +1 -1
  46. package/dist/browser/utils/validation.js +1 -1
  47. package/dist/browser/utils/validation.js.map +1 -1
  48. package/dist/browser/version.js +1 -1
  49. package/dist/browser/version.js.map +1 -1
  50. package/dist/index.cjs +641 -336
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +470 -186
  53. package/dist/index.d.ts +470 -186
  54. package/dist/index.mjs +636 -337
  55. package/dist/index.mjs.map +1 -1
  56. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import BigNumber from "bignumber.js";
2
+ import "decimal.js";
2
3
  //#region src/types/confirm_options.d.ts
3
4
  /**
4
5
  * Controls timeout, polling and cancellation of confirmation.
@@ -176,9 +177,12 @@ export interface QuoteResult {
176
177
  token1Symbol: string;
177
178
  tokenInIsToken0: boolean;
178
179
  feeTier: number;
179
- currentPrice?: BigNumber;
180
- newPrice?: BigNumber;
181
- priceImpact?: BigNumber;
180
+ /** Pool price before the trade, token out per token in (always set by `Quoting`). */
181
+ currentPrice: BigNumber;
182
+ /** Pool price after the trade, in the same orientation (always set by `Quoting`). */
183
+ newPrice: BigNumber;
184
+ /** `(newPrice - currentPrice) / currentPrice` as a fraction (`-0.01` is 1% adverse), always set by `Quoting`. */
185
+ priceImpact: BigNumber;
182
186
  }
183
187
  /** The executed trade as reported by the ApplyRequests result (contract Trade response). */
184
188
  export interface TradeExecution {
@@ -1310,6 +1314,11 @@ export declare const gswapErrorTemplates: { readonly [C in GSwapErrorCode]: stri
1310
1314
  export declare function renderGSwapErrorTemplate(template: string, params: Readonly<Record<string, unknown>>): string;
1311
1315
  //#endregion
1312
1316
  //#region src/types/token.d.ts
1317
+ /**
1318
+ * The four parts of a GalaChain token class key, as the chain keys a token (for example
1319
+ * `GALA|Unit|none|none` is collection `GALA`, category `Unit`, type `none`, additionalKey `none`).
1320
+ * It carries no trading symbol: a collection and a symbol disagree for many tokens.
1321
+ */
1313
1322
  export interface GalaChainTokenClassKey {
1314
1323
  collection: string;
1315
1324
  category: string;
@@ -1424,6 +1433,7 @@ export declare class GSwapSDKError<C extends GSwapErrorCode = GSwapErrorCode> ex
1424
1433
  readonly code: C;
1425
1434
  /** The named placeholders of the error: a flat object of primitives, safe to localize with. */
1426
1435
  readonly params: GSwapErrorParams<C>;
1436
+ /** The server's `Retry-After` in milliseconds (a `RATE_LIMITED` answer), when it sent one. */
1427
1437
  readonly retryAfterMs: number | undefined;
1428
1438
  /** The HTTP status of the response that caused this error, when there was one. */
1429
1439
  readonly status: number | undefined;
@@ -1832,7 +1842,7 @@ export declare function createLazyPrivateKeySigner(getPrivateKey: PrivateKeyProv
1832
1842
  *
1833
1843
  * `scheme: 'personal-sign'` calls
1834
1844
  * `gala_signChainDto([serialize({ ...dto, prefix }), walletAddress, methodName])` and REQUIRES
1835
- * a wallet build that contains wallet_extension commit 3ad7ae6 (strips the embedded `prefix`
1845
+ * a wallet build that contains wallet_extension commit 34ca4e4 (strips the embedded `prefix`
1836
1846
  * field and hashes `prefix` + the prefix-less canonical body, the chain's scheme). Wallets
1837
1847
  * released before that fix hash the string with the `prefix` field still inside it and the
1838
1848
  * signature recovers to an address nobody holds, so only opt in once the fixed wallet is
@@ -1857,7 +1867,7 @@ export declare class GalaWalletSigner implements GalaChainSigner {
1857
1867
  * to the same check); a GalaChain id is `client|` plus 24 hex digits, or the bare 24 hex digits
1858
1868
  * frontend_v2 keeps for a direct `client|` login, and is passed through unchanged.
1859
1869
  * @param options - Select native signing (default) or personal-sign explicitly.
1860
- * `'personal-sign'` requires a Gala Wallet build with wallet_extension commit 3ad7ae6.
1870
+ * `'personal-sign'` requires a Gala Wallet build with wallet_extension commit 34ca4e4.
1861
1871
  * `selectAddress` is the identity (`client|...` / `eth|...`) Gala Wallet is switched to with
1862
1872
  * `window.gala.setAddress` before every signature, when the wallet offers it.
1863
1873
  */
@@ -1916,6 +1926,7 @@ export declare class BrowserWalletSigner implements GalaChainSigner {
1916
1926
  constructor(provider: BrowserWalletProvider, walletAddress: string, options?: {
1917
1927
  scheme?: 'personal-sign' | 'eip712';
1918
1928
  });
1929
+ /** The selected `0x` Ethereum account every signature is requested for. */
1919
1930
  readonly walletAddress: string;
1920
1931
  private readonly scheme;
1921
1932
  /**
@@ -1938,6 +1949,7 @@ export declare class BrowserWalletSigner implements GalaChainSigner {
1938
1949
  //#region src/classes/dex_fees.d.ts
1939
1950
  /** DEX methods the backend accepts a fee quote for (its allow-list enumerates the same six). */
1940
1951
  export declare const DEX_FEE_METHODS: readonly ['Swap', 'RequestTrade', 'AddLiquidity', 'RemoveLiquidity', 'CollectPositionFees', 'CreatePool'];
1952
+ /** A chain method whose network fee `DexFees.quote` can price (see `isDexFeeMethod`). */
1941
1953
  export type DexFeeMethod = (typeof DEX_FEE_METHODS)[number];
1942
1954
  /** Which pool contract the DTO being quoted targets: legacy (V3) or current (GalaChainDex). */
1943
1955
  export type DexFeeContract = 'dexv3-contract' | 'dex-contract';
@@ -2054,18 +2066,19 @@ export interface ShadowSubmitResult {
2054
2066
  *
2055
2067
  * - `SHADOW_UNAVAILABLE` (503): marking failed or infra not configured; retryable. Never fall back
2056
2068
  * silently to a public swap.
2057
- * - `SHADOW_DISABLED` (400): the feature is off for this environment.
2058
2069
  * - `SHADOW_UNSUPPORTED_TYPE` (400): shadow requested on a non-swap method.
2059
2070
  * - `SHADOW_RELAY_REJECTED`: terminal business rejection (slippage, balance, ...), not retryable;
2060
2071
  * `message` is the gateway's verbatim string.
2061
2072
  */
2062
- export declare const SHADOW_SUBMIT_CODES: readonly ['SHADOW_UNAVAILABLE', 'SHADOW_DISABLED', 'SHADOW_UNSUPPORTED_TYPE', 'SHADOW_RELAY_REJECTED'];
2073
+ export declare const SHADOW_SUBMIT_CODES: readonly ['SHADOW_UNAVAILABLE', 'SHADOW_UNSUPPORTED_TYPE', 'SHADOW_RELAY_REJECTED'];
2063
2074
  /** One member of {@link SHADOW_SUBMIT_CODES}. */
2064
2075
  export type ShadowSubmitCode = (typeof SHADOW_SUBMIT_CODES)[number];
2065
2076
  /**
2066
2077
  * Every `kind` of a failed {@link ShadowSubmitOutcome}, for an app that maps each to its own text
2067
- * (`Record<ShadowFailureKind, string>`): `unavailable` (retryable), `disabled`, `rejected` (carries
2068
- * the gateway's `message`) and `unknown`.
2078
+ * (`Record<ShadowFailureKind, string>`): `unavailable` (retryable), `disabled` (the shadow route
2079
+ * answered 400: the request is not a dark-swappable one, e.g. `SHADOW_UNSUPPORTED_TYPE`; Shadow
2080
+ * Swaps themselves are enabled in every environment), `rejected` (carries the gateway's `message`)
2081
+ * and `unknown`.
2069
2082
  */
2070
2083
  export declare const SHADOW_FAILURE_KINDS: readonly ['unavailable', 'disabled', 'rejected', 'unknown'];
2071
2084
  /** One member of {@link SHADOW_FAILURE_KINDS}. */
@@ -2122,7 +2135,7 @@ export declare function classifyShadowSubmitStatus(status: number): ShadowFailur
2122
2135
  /**
2123
2136
  * Prefers the body `code` (stable across status remaps) and falls back to the HTTP status.
2124
2137
  * `SHADOW_UNAVAILABLE` is the only retryable case; `SHADOW_RELAY_REJECTED` is a terminal gateway
2125
- * rejection; the two other 400 codes and any unknown 400 map to "disabled".
2138
+ * rejection; `SHADOW_UNSUPPORTED_TYPE` and any other 400 map to "disabled".
2126
2139
  */
2127
2140
  export declare function classifyShadowSubmitError(status: number, code?: string): ShadowFailureKind;
2128
2141
  /**
@@ -2195,9 +2208,13 @@ export type PositionConfirmationResult = {
2195
2208
  };
2196
2209
  /** A submitted v2 transaction whose confirmation mode is explicit in the gateway response. */
2197
2210
  export declare class SubmittedTransaction<TConfirmation = AppliedTrade | Position | null> {
2211
+ /** The chain method that was submitted (`RequestTrade`, `AddLiquidity`, ...). */
2198
2212
  readonly method: string;
2213
+ /** The write's durable correlation key: persist it, and confirm from it alone later. */
2199
2214
  readonly uniqueKey: string;
2215
+ /** The request transaction id the gateway reported, or `null` when it gave none. */
2200
2216
  readonly transactionId: string | null;
2217
+ /** The block of the transaction, when the answer carried one; otherwise `null`. */
2201
2218
  readonly blockNumber: number | null;
2202
2219
  /** The gateway's `data.mode`: `'sync'` (executed, `result` is the chain result) or `'queued'`. */
2203
2220
  readonly mode: 'sync' | 'queued';
@@ -2357,7 +2374,9 @@ export declare class ChainGateway {
2357
2374
  private readonly chainCallTimeoutMs;
2358
2375
  private readonly isTransportFailure;
2359
2376
  private readonly answerOfRejectionHook;
2377
+ /** The request timeout in milliseconds (`Infinity` when no timer is armed). */
2360
2378
  readonly requestTimeoutMs: number;
2379
+ /** The swap backend base URL every request is sent to, without a trailing slash. */
2361
2380
  readonly dexBackendBaseUrl: string;
2362
2381
  /** Wire format shared by the read services built on this gateway. */
2363
2382
  readonly wire: WireOptions;
@@ -2382,7 +2401,7 @@ export declare class ChainGateway {
2382
2401
  *
2383
2402
  * Unlike `submit`, EVERY HTTP status resolves: the result is the raw `{ httpStatus, body }`,
2384
2403
  * because shadow failures are classified from the status together with the body's `code`
2385
- * (`SHADOW_UNAVAILABLE`, `SHADOW_DISABLED`, `SHADOW_UNSUPPORTED_TYPE`, `SHADOW_RELAY_REJECTED`);
2404
+ * (`SHADOW_UNAVAILABLE`, `SHADOW_UNSUPPORTED_TYPE`, `SHADOW_RELAY_REJECTED`);
2386
2405
  * see `readShadowSubmitOutcome`. Only a failure to get an answer rejects, and it rejects with
2387
2406
  * `SUBMISSION_OUTCOME_UNKNOWN` (`params.reason` `'timeout'` or `'transport'`): the request may
2388
2407
  * have been accepted. Every error it throws has `error.shadow === true`, and a non-SDK object
@@ -2517,7 +2536,9 @@ export interface GdexSubscription {
2517
2536
  }
2518
2537
  /** A JSON-RPC error answered by the stream. */
2519
2538
  export declare class GdexStreamError extends Error {
2539
+ /** The JSON-RPC error code. */
2520
2540
  readonly code: number;
2541
+ /** The error's optional `data` member, as the server sent it. */
2521
2542
  readonly data?: unknown;
2522
2543
  constructor(code: number, message: string, data?: unknown);
2523
2544
  }
@@ -2555,17 +2576,26 @@ export declare class GdexStreamService {
2555
2576
  connect(): Promise<void>;
2556
2577
  /** Close the connection and stop reconnecting. */
2557
2578
  disconnect(): void;
2579
+ /** `true` while the socket is open (false while connecting, reconnecting or after `disconnect()`). */
2558
2580
  isConnected(): boolean;
2559
2581
  /** Raw JSON-RPC escape hatch. */
2560
2582
  request<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
2561
2583
  private send;
2584
+ /** `gdex_serverInfo`: the server's own description of itself, as it sends it. */
2562
2585
  serverInfo(): Promise<Record<string, unknown>>;
2586
+ /** `gdex_ping`: a round trip that answers `{ pong, serverTime }`. */
2563
2587
  ping(): Promise<{
2564
2588
  pong: boolean;
2565
2589
  serverTime: string;
2566
2590
  }>;
2591
+ /** `gdex_getPool`: the current state of one pool, selected by its key or hash. */
2567
2592
  getPool(selector: GdexPoolSelector): Promise<Record<string, unknown>>;
2593
+ /** `gdex_getBalance`: an owner's balances, or only the one of `tokenClassKey` when given. */
2568
2594
  getBalance(owner: string, tokenClassKey?: string): Promise<Record<string, unknown>>;
2595
+ /**
2596
+ * `gdex_getPositions`: an owner's positions, optionally in one pool, a page at a time. Pass the
2597
+ * returned `bookmark` back in as `bookmark` for the next page.
2598
+ */
2569
2599
  getPositions(opts: {
2570
2600
  owner: string;
2571
2601
  pool?: GdexPoolKey;
@@ -2576,10 +2606,12 @@ export declare class GdexStreamService {
2576
2606
  positions: Record<string, unknown>[];
2577
2607
  bookmark: string;
2578
2608
  }>;
2609
+ /** `gdex_getBlockHeight`: the block number the server reports, with its timestamp. */
2579
2610
  getBlockHeight(): Promise<{
2580
2611
  blockNumber: number;
2581
2612
  timestamp: string;
2582
2613
  }>;
2614
+ /** `gdex_quote`: a quote over the stream; give exactly one of `amountIn` or `amountOut`. */
2583
2615
  quote(params: {
2584
2616
  tokenIn: string;
2585
2617
  tokenOut: string;
@@ -2587,6 +2619,7 @@ export declare class GdexStreamService {
2587
2619
  amountIn?: string;
2588
2620
  amountOut?: string;
2589
2621
  }): Promise<Record<string, unknown>>;
2622
+ /** `gdex_getToken`: the server's record of one token class, as it sends it. */
2590
2623
  getToken(tokenClassKey: string): Promise<Record<string, unknown>>;
2591
2624
  /** One event per committed swap. Omit the pool to receive every pool's swaps. */
2592
2625
  subscribeSwaps(cb: (event: Record<string, unknown>) => void, opts?: GdexSubscribeOptions & {
@@ -2695,8 +2728,6 @@ export declare function readOrderedSymbols(value: unknown): {
2695
2728
  token0: string;
2696
2729
  token1: string;
2697
2730
  };
2698
- /** Return the `$`-joined composite key used by GalaChain object identities. */
2699
- export declare function compositeKeyOf(token: GalaChainTokenClassKey): string;
2700
2731
  /**
2701
2732
  * Parse a pipe- or dollar-separated token class key.
2702
2733
  *
@@ -2712,42 +2743,6 @@ export declare function compositeKeyOf(token: GalaChainTokenClassKey): string;
2712
2743
  * ```
2713
2744
  */
2714
2745
  export declare function parseTokenClassKey(tokenClassKey: TokenRef): GalaChainTokenClassKey;
2715
- /**
2716
- * The non-throwing {@link parseTokenClassKey}: the class key, or `undefined` when `value` is not
2717
- * one. A string is split exactly as `parseTokenClassKey` splits it (`|` form when it contains a
2718
- * `|`, else `$`, from the right, all four parts non-empty). Unlike `parseTokenClassKey`, an
2719
- * object is VALIDATED, not just copied: all four fields must be non-empty strings. Anything else
2720
- * (`undefined`, `null`, a number, an array) is `undefined`, so it is safe on untrusted input (a
2721
- * stored token, a URL parameter, a wallet row) without a `try`/`catch`.
2722
- *
2723
- * Use {@link tryParseCompositeKey} instead when only the `$` form is valid input.
2724
- *
2725
- * @example
2726
- * ```ts
2727
- * const key = tryParseTokenClassKey(row.compositeKey);
2728
- * if (key === undefined) return failClosed(); // no class is known: never invent one from a symbol
2729
- * ```
2730
- */
2731
- export declare function tryParseTokenClassKey(value: unknown): GalaChainTokenClassKey | undefined;
2732
- /**
2733
- * Parses a `$`-joined composite key (`Collection$Category$Type$AdditionalKey`, what
2734
- * {@link compositeKeyOf} writes) and nothing else, or `undefined`. It is {@link tryParseTokenClassKey}
2735
- * for a string that may ONLY be in the `$` form: a key that contains `|` is NOT read as the pipe
2736
- * form here (it stays part of a segment), and only a string is accepted. The split is from the
2737
- * right, so a collection that itself contains `$` (production's `$GMUSIC`, stage's
2738
- * `$GMUSIC_TEST1`) stays whole; `'GALA'`, `'GALA$Unit$none'`, `'ETIME$$$'`, `'GALA$Unit$none$'` and
2739
- * `'$$$$'` are `undefined`.
2740
- *
2741
- * It replaces an app's own `parseCompositeKey(key): Components | null` (`?? null`), which had
2742
- * exactly these semantics.
2743
- *
2744
- * @example
2745
- * ```ts
2746
- * tryParseCompositeKey('$GMUSIC_TEST1$Unit$none$none')?.collection; // '$GMUSIC_TEST1'
2747
- * tryParseCompositeKey('GALA$Unit$none'); // undefined
2748
- * ```
2749
- */
2750
- export declare function tryParseCompositeKey(value: unknown): GalaChainTokenClassKey | undefined;
2751
2746
  //#endregion
2752
2747
  //#region src/classes/symbols.d.ts
2753
2748
  /** Symbol registry client for the current GalaChainDex contract. */
@@ -2970,10 +2965,22 @@ interface Branding<BrandT> {
2970
2965
  type Brand<T, BrandT> = T & Branding<BrandT>;
2971
2966
  //#endregion
2972
2967
  //#region src/types/amounts.d.ts
2968
+ /** A decimal amount: a string or a `BigNumber`, never a JavaScript number. */
2973
2969
  export type NumericAmount = string | BigNumber;
2970
+ /** A calculated square-root price (always a `BigNumber`, branded so it is never mistaken for a price). */
2974
2971
  export type SqrtPrice = Brand<BigNumber, 'SqrtPrice'>;
2972
+ /**
2973
+ * A square-root price an API accepts: a calculated {@link SqrtPrice}, or a decimal string /
2974
+ * `BigNumber` the caller brands with `as SqrtPriceIn` to declare what it is.
2975
+ */
2975
2976
  export type SqrtPriceIn = Brand<NumericAmount, 'SqrtPriceIn'> | SqrtPrice;
2977
+ /** A calculated price (always a `BigNumber`, branded so it is never mistaken for a square-root price). */
2976
2978
  export type Price = Brand<BigNumber, 'Price'>;
2979
+ /**
2980
+ * A price an API accepts (for example `addLiquidityByPrice`'s `minPrice` / `maxPrice`): a calculated
2981
+ * {@link Price}, or a decimal string / `BigNumber` the caller brands with `as PriceIn` to declare
2982
+ * what it is. An unbranded string does not compile.
2983
+ */
2977
2984
  export type PriceIn = Brand<NumericAmount, 'PriceIn'> | Price;
2978
2985
  /**
2979
2986
  * What a swap trades: exactly one of `exactIn` (sell this much of the input token) or `exactOut`
@@ -3720,10 +3727,18 @@ export declare const GSWAP_ENVIRONMENTS: Readonly<Record<GSwapEnv, GSwapEnvironm
3720
3727
  //#region src/classes/gswap.d.ts
3721
3728
  /** Options for constructing a backend-routed SDK client. */
3722
3729
  export interface GSwapOptions {
3730
+ /** Signs every write. Without one, reads work and any write throws `NO_SIGNER`. */
3723
3731
  signer?: GalaChainSigner | undefined;
3732
+ /**
3733
+ * The selected account, sent as `X-Wallet-Address` on writes (attribution only; the chain
3734
+ * recovers the signer from the signature). Required for shadow writes.
3735
+ */
3724
3736
  walletAddress?: string | undefined;
3737
+ /** `'stage'` or `'prod'` swap backend preset; defaults to `'prod'`. */
3725
3738
  env?: GSwapEnv | undefined;
3739
+ /** Overrides the preset's swap backend base URL (a test or private deployment). */
3726
3740
  dexBackendBaseUrl?: string | undefined;
3741
+ /** HTTP transport for every request; defaults to the global `fetch`. */
3727
3742
  httpRequestor?: HttpRequestor | undefined;
3728
3743
  /** Request timeout in milliseconds (default 30 000); `Infinity` arms no timer. */
3729
3744
  chainCallTimeoutMs?: number | undefined;
@@ -3757,27 +3772,43 @@ export interface GSwapOptions {
3757
3772
  */
3758
3773
  uniqueKeyPrefix?: string | undefined;
3759
3774
  }
3760
- /** Main entry point for the current GalaChainDex SDK. */
3775
+ /**
3776
+ * Main entry point for the current GalaChainDex SDK: one client bundling the services that read
3777
+ * and write through the swap backend (`quoting`, `swaps`, `pools`, `positions`, `assets`,
3778
+ * `symbols`, `fees`, `stream`). See {@link GSwapOptions} for configuration.
3779
+ */
3761
3780
  export declare class GSwap {
3781
+ /** The swap backend base URL every request goes to, without a trailing slash. */
3762
3782
  readonly dexBackendBaseUrl: string;
3783
+ /** The request timeout in milliseconds (default 30 000; `Infinity` arms no timer). */
3763
3784
  readonly chainCallTimeoutMs: number;
3785
+ /** The signer given at construction, if any. */
3764
3786
  readonly signer: GalaChainSigner | undefined;
3787
+ /** The account given at construction, if any. */
3765
3788
  readonly walletAddress: string | undefined;
3789
+ /** The chain-gateway client every other service reads and writes through. */
3766
3790
  readonly gateway: ChainGateway;
3791
+ /** The trading-symbol registry. */
3767
3792
  readonly symbols: Symbols;
3793
+ /** Read-only exact-input and exact-output quotes. */
3768
3794
  readonly quoting: Quoting;
3795
+ /** Pool, slot0 and composite-pool reads. */
3769
3796
  readonly pools: Pools;
3797
+ /** Position reads, liquidity estimates and liquidity / pool-creation writes. */
3770
3798
  readonly positions: Positions;
3799
+ /** Queued swaps (`RequestTrade`), dark swaps and swap confirmation. */
3771
3800
  readonly swaps: Swaps;
3801
+ /** User token balances. */
3772
3802
  readonly assets: Assets;
3773
3803
  /** Network-fee quotes (DryRun) signed with this client's signer. */
3774
3804
  readonly fees: DexFees;
3805
+ /** The realtime stream endpoint {@link GSwap.stream} connects to. */
3775
3806
  readonly dexBackendWsUrl: string;
3776
3807
  private readonly webSocketImpl;
3777
3808
  private readonly streamApiKey;
3778
3809
  private streamClient;
3779
3810
  /**
3780
- * Create an SDK client for prod or stage.
3811
+ * Create an SDK client for prod (the default) or stage, or for a `dexBackendBaseUrl` of your own.
3781
3812
  *
3782
3813
  * @example
3783
3814
  * ```typescript
@@ -4058,27 +4089,66 @@ export declare const GSWAP_ERROR_PHASE_BY_CODE: {
4058
4089
  readonly INVALID_LIMIT: 'pre_send';
4059
4090
  };
4060
4091
  //#endregion
4061
- //#region src/classes/pending_swaps.d.ts
4062
- /** Key the wallet_extension has always used; its storage value is a plain array of entries. */
4063
- export declare const PENDING_SWAPS_STORAGE_KEY = "pendingSwaps.v1";
4064
- /** Entries older than this are dropped the next time a wallet's swaps are listed. */
4065
- export declare const PENDING_SWAP_EXPIRY_MS: number;
4092
+ //#region src/classes/pending_swap_fate.d.ts
4093
+ /**
4094
+ * What to do with a pending swap after confirming it failed (the answer of
4095
+ * {@link pendingSwapFateFor}).
4096
+ *
4097
+ * - `forget`: the chain REFUSED the trade, so it did not happen. Drop it AND tell the user.
4098
+ * - `forget_quietly`: the confirmation can never succeed (the key is refused: `invalid_input`).
4099
+ * Drop it without claiming anything about the trade.
4100
+ * - `keep`: the trade may still have been applied (a timeout, a broken connection, a gateway
4101
+ * hiccup, anything not proven). Leave it pending and look again later.
4102
+ *
4103
+ * This module holds the decision and nothing of the store, so an app shell that only needs the
4104
+ * fate pays for `classifyFailure` and this table, not for `PendingSwapStore`.
4105
+ */
4106
+ export declare const PENDING_SWAP_FATES: readonly ['forget', 'forget_quietly', 'keep'];
4107
+ /** One member of {@link PENDING_SWAP_FATES}. */
4108
+ export type PendingSwapFate = (typeof PENDING_SWAP_FATES)[number];
4109
+ /**
4110
+ * {@link pendingSwapFateFor} from an outcome the app already holds (for example the
4111
+ * `classifyFailure(error).outcome` it stored on its own failure wrapper). An outcome this SDK
4112
+ * version does not know (a newer SDK at run time) is `keep`: never forget what may have happened.
4113
+ */
4114
+ export declare function pendingSwapFateOfOutcome(outcome: FailureOutcome): PendingSwapFate;
4115
+ /**
4116
+ * The fate of a queued swap whose confirmation (`confirmAppliedTrade`) just failed with `error`,
4117
+ * from the SDK's classification alone: `forget` for a chain rejection (`rejected`), `forget_quietly`
4118
+ * for a key that can never be confirmed (`invalid_input`), `keep` for every other outcome
4119
+ * (`unknown`, `not_queued`, `not_sent`, `transient`) and for any value the SDK cannot judge. It
4120
+ * accepts an SDK error or a plain-object view of one (see `FailureView`). It replaces the wallet's
4121
+ * `pendingSwapActionFor` and frontend_v2's `confirmationStanceOf`.
4122
+ *
4123
+ * @example
4124
+ * ```ts
4125
+ * try {
4126
+ * await confirmAppliedTrade(client, swap);
4127
+ * } catch (error) {
4128
+ * if ((await store.settle(swap.uniqueKey, error)) === 'forget') tellTheUserItFailed();
4129
+ * }
4130
+ * ```
4131
+ */
4132
+ export declare function pendingSwapFateFor(error: unknown): PendingSwapFate;
4133
+ //#endregion
4134
+ //#region src/classes/storage_adapters.d.ts
4066
4135
  /**
4067
4136
  * Async key/value storage the pending-swap store persists through. It stores STRUCTURED VALUES
4068
4137
  * (the store never serializes), so each platform decides how a value lands on disk:
4069
4138
  *
4070
4139
  * - `chrome.storage.local`: `get: async (k) => (await chrome.storage.local.get(k))[k]`,
4071
4140
  * `set: (k, v) => chrome.storage.local.set({ [k]: v })`. This is the wallet's stored shape.
4072
- * - `localStorage` (frontend_v2): `get: async (k) => { const raw = localStorage.getItem(k);
4073
- * if (raw === null) return undefined; try { return JSON.parse(raw); } catch { return raw; } }`,
4074
- * `set: async (k, v) => localStorage.setItem(k, JSON.stringify(v))`. Corrupt JSON MUST come back
4075
- * as a value (here the raw string), not as a rejection: a value that is not an array reads as
4076
- * "no entries" and the next write repairs it, whereas a `get` that rejects forever makes every
4077
- * `remember` a no-op.
4141
+ * {@link storageAdapterFromChromeStorage} builds it.
4142
+ * - `localStorage` (frontend_v2): JSON text under the key. {@link webStorageAdapter} builds it,
4143
+ * and returns CORRUPT JSON as a value (the raw string), not as a rejection: a value that is not
4144
+ * an array reads as "no entries" and the next write repairs it, whereas a `get` that rejects
4145
+ * forever makes every `remember` a no-op.
4078
4146
  * - React Native: AsyncStorage with the same JSON wrapping and the same corrupt-JSON rule.
4079
4147
  *
4080
4148
  * `get` resolves `undefined` for a missing key. Either method may reject; the store treats that
4081
- * as "storage unavailable" and never lets it surface (see {@link PendingSwapStore}).
4149
+ * as "storage unavailable" and never lets it surface (see `PendingSwapStore`).
4150
+ *
4151
+ * This module imports nothing, so an app shell that only builds an adapter pays for the adapter.
4082
4152
  */
4083
4153
  export interface StorageAdapter {
4084
4154
  get(key: string): Promise<unknown>;
@@ -4113,6 +4183,41 @@ export interface ChromeStorageAreaLike {
4113
4183
  * ```
4114
4184
  */
4115
4185
  export declare function storageAdapterFromChromeStorage(area: ChromeStorageAreaLike | (() => ChromeStorageAreaLike)): StorageAdapter;
4186
+ /**
4187
+ * The part of a Web Storage area ({@link webStorageAdapter}) the adapter uses, written
4188
+ * structurally so the SDK needs no DOM types: `localStorage`, `sessionStorage` and any object with
4189
+ * these two synchronous methods (a React Native MMKV wrapper, a test double) satisfy it.
4190
+ */
4191
+ export interface WebStorageLike {
4192
+ getItem(key: string): string | null;
4193
+ setItem(key: string, value: string): void;
4194
+ }
4195
+ /**
4196
+ * A {@link StorageAdapter} over a Web Storage area (`localStorage`, `sessionStorage`), the shape
4197
+ * frontend_v2 stores pending swaps in: the value lands under the key as JSON text. A missing key
4198
+ * resolves `undefined`. CORRUPT JSON resolves as the raw string, never a rejection (the store
4199
+ * reads a value that is not an array as "no entries" and the next write repairs it, whereas a
4200
+ * `get` that rejects forever would make every `remember` a no-op). A throwing area (storage blocked
4201
+ * by the browser, quota exceeded on `setItem`) rejects, which the store treats as "storage
4202
+ * unavailable".
4203
+ *
4204
+ * Pass a FUNCTION that returns the area to look it up at each call instead of when the adapter is
4205
+ * built: where `localStorage` does not exist (server rendering, a test, a blocked context)
4206
+ * the access throws inside the function, which is the same "storage unavailable" rejection, and
4207
+ * the module that builds the adapter still loads.
4208
+ *
4209
+ * @example
4210
+ * ```ts
4211
+ * const store = new PendingSwapStore(webStorageAdapter(() => localStorage));
4212
+ * ```
4213
+ */
4214
+ export declare function webStorageAdapter(area: WebStorageLike | (() => WebStorageLike)): StorageAdapter;
4215
+ //#endregion
4216
+ //#region src/classes/pending_swaps.d.ts
4217
+ /** Key the wallet_extension has always used; its storage value is a plain array of entries. */
4218
+ export declare const PENDING_SWAPS_STORAGE_KEY = "pendingSwaps.v1";
4219
+ /** Entries older than this are dropped the next time a wallet's swaps are listed. */
4220
+ export declare const PENDING_SWAP_EXPIRY_MS: number;
4116
4221
  /** A RequestTrade that was accepted by the gateway but whose outcome has not been read yet. */
4117
4222
  export interface PendingSwap {
4118
4223
  uniqueKey: string;
@@ -4142,43 +4247,6 @@ export interface PendingSwap {
4142
4247
  export declare const PENDING_SWAP_PRUNE_REASONS: readonly ['expired', 'invalid_unique_key', 'chain_rejected', 'unconfirmable'];
4143
4248
  /** One member of {@link PENDING_SWAP_PRUNE_REASONS}. */
4144
4249
  export type PendingSwapPruneReason = (typeof PENDING_SWAP_PRUNE_REASONS)[number];
4145
- /**
4146
- * What to do with a pending swap after confirming it failed (the answer of
4147
- * {@link pendingSwapFateFor}).
4148
- *
4149
- * - `forget`: the chain REFUSED the trade, so it did not happen. Drop it AND tell the user.
4150
- * - `forget_quietly`: the confirmation can never succeed (the key is refused: `invalid_input`).
4151
- * Drop it without claiming anything about the trade.
4152
- * - `keep`: the trade may still have been applied (a timeout, a broken connection, a gateway
4153
- * hiccup, anything not proven). Leave it pending and look again later.
4154
- */
4155
- export declare const PENDING_SWAP_FATES: readonly ['forget', 'forget_quietly', 'keep'];
4156
- /** One member of {@link PENDING_SWAP_FATES}. */
4157
- export type PendingSwapFate = (typeof PENDING_SWAP_FATES)[number];
4158
- /**
4159
- * {@link pendingSwapFateFor} from an outcome the app already holds (for example the
4160
- * `classifyFailure(error).outcome` it stored on its own failure wrapper). An outcome this SDK
4161
- * version does not know (a newer SDK at run time) is `keep`: never forget what may have happened.
4162
- */
4163
- export declare function pendingSwapFateOfOutcome(outcome: FailureOutcome): PendingSwapFate;
4164
- /**
4165
- * The fate of a queued swap whose confirmation (`confirmAppliedTrade`) just failed with `error`,
4166
- * from the SDK's classification alone: `forget` for a chain rejection (`rejected`), `forget_quietly`
4167
- * for a key that can never be confirmed (`invalid_input`), `keep` for every other outcome
4168
- * (`unknown`, `not_queued`, `not_sent`, `transient`) and for any value the SDK cannot judge. It
4169
- * accepts an SDK error or a plain-object view of one (see `FailureView`). It replaces the wallet's
4170
- * `pendingSwapActionFor` and frontend_v2's `confirmationStanceOf`.
4171
- *
4172
- * @example
4173
- * ```ts
4174
- * try {
4175
- * await confirmAppliedTrade(client, swap);
4176
- * } catch (error) {
4177
- * if ((await store.settle(swap.uniqueKey, error)) === 'forget') tellTheUserItFailed();
4178
- * }
4179
- * ```
4180
- */
4181
- export declare function pendingSwapFateFor(error: unknown): PendingSwapFate;
4182
4250
  /** A pending swap the store dropped, and why. */
4183
4251
  export interface PrunedPendingSwap {
4184
4252
  swap: PendingSwap;
@@ -4468,6 +4536,7 @@ export declare function tokenClassDollarKey(token: Record<string, unknown> | nul
4468
4536
  export declare function canonicalDecimalString(value: string | number): string;
4469
4537
  //#endregion
4470
4538
  //#region src/utils/eip712.d.ts
4539
+ /** EIP-712 `types`: each struct name mapped to its ordered `{ name, type }` fields. */
4471
4540
  type EIP712Types = Record<string, Array<{
4472
4541
  name: string;
4473
4542
  type: string;
@@ -4558,8 +4627,9 @@ type RequestTradeInput = {
4558
4627
  /**
4559
4628
  * Builds the RequestTrade DTO: `exactIn` sells that much of the input token (`sell0Qty` or
4560
4629
  * `sell1Qty`), `exactOut` buys that much of the output token (`buy1Qty` or `buy0Qty`), plus the
4561
- * side's slippage bound and an optional `priceLimit`. Key order: `token0, token1, fee, uniqueKey,
4562
- * <quantity>, amountOutMinimum | amountInMaximum, priceLimit`.
4630
+ * side's slippage bound and an optional `priceLimit`. Key order is
4631
+ * `token0, token1, fee, uniqueKey`, then the one quantity, then the slippage bound, then
4632
+ * `priceLimit`.
4563
4633
  *
4564
4634
  * @example
4565
4635
  * ```ts
@@ -4824,8 +4894,14 @@ export declare function isConfirmationTimeout(error: unknown): boolean;
4824
4894
  */
4825
4895
  export declare function isFetchTransportFailure(error: unknown): boolean;
4826
4896
  //#endregion
4827
- //#region src/utils/failure_classification.d.ts
4828
- /** The result of {@link classifyFailure}. */
4897
+ //#region src/utils/classification.d.ts
4898
+ /**
4899
+ * The classification values an app shell may need on their own: what an outcome allows. This module
4900
+ * is deliberately tiny and imports nothing at run time (the outcome type is erased), so an app
4901
+ * shell that builds `classification('not_sent')` or reads `NOT_QUEUED_FINAL` loads a few hundred
4902
+ * bytes, not the table of error codes that lives with `classifyFailure`.
4903
+ */
4904
+ /** The result of `classifyFailure`. */
4829
4905
  export interface FailureClassification {
4830
4906
  readonly outcome: FailureOutcome;
4831
4907
  /**
@@ -4845,10 +4921,10 @@ export interface FailureClassification {
4845
4921
  * object, safe to mutate or freeze.
4846
4922
  *
4847
4923
  * `options.retryable: false` WITHHOLDS Retry from an outcome that would otherwise allow it: the
4848
- * SDK's own `not_queued` for a refusal the gateway will repeat is `classification('not_queued',
4849
- * { retryable: false })` (also exported, frozen, as {@link NOT_QUEUED_FINAL}). An app may take
4850
- * Retry away from an outcome but never grant it to one that cannot have it, so only `false` is
4851
- * accepted.
4924
+ * SDK's own `not_queued` for a refusal the gateway will repeat is
4925
+ * `classification('not_queued', { retryable: false })` (also exported, frozen, as
4926
+ * {@link NOT_QUEUED_FINAL}). An app may take Retry away from an outcome but never grant it to one
4927
+ * that cannot have it, so only `false` is accepted.
4852
4928
  *
4853
4929
  * @example
4854
4930
  * ```ts
@@ -4874,6 +4950,105 @@ export declare const NOT_QUEUED_FINAL: Readonly<FailureClassification>;
4874
4950
  * sent (a quote refresh, a balance read), so nothing is pending and a repeat is safe.
4875
4951
  */
4876
4952
  export declare function notSentClassification(): FailureClassification;
4953
+ //#endregion
4954
+ //#region src/utils/failure_classification.d.ts
4955
+ /**
4956
+ * Classifies any thrown value from its code (and, for two codes, its HTTP status), never from
4957
+ * message text, so an app does not have to re-derive "may I offer Retry?" and "is the outcome
4958
+ * unknown?" for every code. The decision for each code is in this module's table; a new catalog
4959
+ * code cannot be added without one.
4960
+ *
4961
+ * A failure BEFORE the request left (`error.phase === 'pre_send'`, `isPreSendError`) can never be
4962
+ * `unknown` or `rejected`: it is `invalid_input` (the input has to change) or `not_sent` (nothing
4963
+ * was transmitted; a repeat is safe). Every app-supplied callback the SDK calls before it sends
4964
+ * (the signer, the key provider, a token resolver) has its failure wrapped into such an error
4965
+ * (`SIGNING_FAILED`, `KEY_PROVIDER_FAILED`, `TOKEN_RESOLUTION_FAILED`, the original as `cause`),
4966
+ * so an app NEVER needs an error class of its own to say "nothing was sent": a locked wallet,
4967
+ * a declined signature and a failed lookup all arrive as `not_sent`, retryable.
4968
+ *
4969
+ * It accepts a `GSwapSDKError` or a plain-object VIEW of one ({@link FailureView}: `{ code,
4970
+ * params?, status?, uniqueKey?, ... }`, the shape of the wrapper an app builds from an SDK error;
4971
+ * `toFailureView` reads any value), and decides from the same fields, so an app does not need to
4972
+ * keep the original error to ask. `{ afterQueued: true }` says the write is already queued (the
4973
+ * step being classified is a confirmation): `retryable` is then always `false`.
4974
+ *
4975
+ * Anything that is not an SDK error or such a view, or a view whose `code` the catalog does not
4976
+ * define, is `{ outcome: 'unknown', retryable: false }`: the SDK
4977
+ * cannot say what happened, and refusing Retry is the safe answer. That is only what escapes AFTER
4978
+ * the request left (an app requestor that rejects with its own error, a callback of yours that
4979
+ * throws once bytes were sent). An error your own code raises BEFORE it calls the SDK says so
4980
+ * itself: give it a code of its own and `outcome` (`{ code: 'POSITION_STALE', outcome: 'not_sent'
4981
+ * }`), and the SDK answers with that outcome's classification and `mayHaveBeenQueued` is `false`.
4982
+ * The declared `outcome` is read only for a code the catalog does not define.
4983
+ *
4984
+ * A failure is a WRITE's unless it states `write: false` (`GSwapSDKError.write`, set for every
4985
+ * SDK read): see {@link FailureView}. A view that lost its `uniqueKey` is therefore still judged as
4986
+ * a write (a 5xx stays `unknown`), never as a retryable read.
4987
+ *
4988
+ * To learn that a failure came from the dark (shadow) path, read `error.shadow` (a typed field of
4989
+ * every `GSwapSDKError`) or call `isShadowError(error)`, which also covers a non-SDK object that
4990
+ * escaped `swapShadow` / `submitSwapShadow` / `ChainGateway.submitShadow`. The classification is
4991
+ * the same as on the public path; an app that withholds Retry or a public fallback after a dark
4992
+ * swap applies that policy on top of `retryable`.
4993
+ *
4994
+ * @example
4995
+ * ```ts
4996
+ * try {
4997
+ * await swaps.swap('GALA', 'GUSDC', 3000, { exactIn: '100' });
4998
+ * } catch (error) {
4999
+ * const { outcome, retryable } = classifyFailure(error);
5000
+ * if (outcome === 'unknown') keepPendingAndConfirm(error); // never a second swap
5001
+ * else if (retryable) offerRetry(); // a new request under a fresh key
5002
+ * }
5003
+ * ```
5004
+ */
5005
+ export declare function classifyFailure(error: unknown, options?: ClassifyFailureOptions): FailureClassification;
5006
+ /** Options of {@link classifyFailure}. */
5007
+ export interface ClassifyFailureOptions {
5008
+ /**
5009
+ * The write is ALREADY queued (the gateway acknowledged it with this `uniqueKey`), and what is
5010
+ * being classified is a later step: confirming it, reading its apply result. Whatever the
5011
+ * outcome, `retryable` is then `false`: a NEW request would be a second trade, so the app
5012
+ * confirms the same key (or forgets it) and never offers "Try again". `outcome` is unchanged.
5013
+ *
5014
+ * The one exception is `rejected`: the chain evaluated the queued write and refused it (an
5015
+ * apply result of `Status: 0`, `CHAIN_REJECTED`; a 422 dispatch). That PROVES it was not
5016
+ * applied, so a new request under a fresh key cannot make a second trade, and `retryable`
5017
+ * keeps the answer it has without this option (`true`). Every outcome that does not prove
5018
+ * "not applied" (`unknown`, `transient`, `not_queued`, ...) is `false`.
5019
+ */
5020
+ afterQueued?: boolean | undefined;
5021
+ }
5022
+ /**
5023
+ * True when the failed call was a WRITE that may nevertheless have been queued: its outcome is
5024
+ * `unknown` (`classifyFailure(error).outcome === 'unknown'`: a timeout or broken connection after
5025
+ * the request left, an acknowledgement that proves nothing, a gateway 409 or 5xx, a failed
5026
+ * confirmation). The app must keep `error.uniqueKey` and confirm it, and must NOT submit again
5027
+ * under a fresh key. Every other outcome (`rejected`, `not_queued`, `not_sent`, `invalid_input`,
5028
+ * `transient`) proves the write is not pending.
5029
+ *
5030
+ * A value the SDK cannot judge (an app requestor's own rejection after the request left) is
5031
+ * `unknown` too, so it is `true`; handle errors your own code raised BEFORE calling the SDK first.
5032
+ * Meant for the catch of a write; a read never has a pending key to keep.
5033
+ *
5034
+ * @example
5035
+ * ```ts
5036
+ * try {
5037
+ * await swaps.swap('GALA', 'GUSDC', 3000, { exactIn: '100' });
5038
+ * } catch (error) {
5039
+ * if (mayHaveBeenQueued(error)) keepPendingAndConfirm(error);
5040
+ * }
5041
+ * ```
5042
+ */
5043
+ export declare function mayHaveBeenQueued(error: unknown): boolean;
5044
+ //#endregion
5045
+ //#region src/utils/failure_guards.d.ts
5046
+ /**
5047
+ * The yes/no questions an app asks about a failure from its CODE alone. They read only the failure
5048
+ * view and a short list of codes: no table of every code (that is `classifyFailure`'s, in
5049
+ * `failure_classification.ts`), no error class and no catalog (the imports above are types, erased
5050
+ * at build time). An app shell that imports one of them pays for this module and nothing else.
5051
+ */
4877
5052
  /**
4878
5053
  * True when the gateway answered that the write's `uniqueKey` was ALREADY CONSUMED: a
4879
5054
  * `CHAIN_DISPATCH_FAILED` with HTTP status 409. The first attempt under that key may be applied
@@ -4940,72 +5115,24 @@ export type RelayableCode = 'GATEWAY_REPORTED_ERROR' | 'METHOD_NOT_ALLOWED' | 'S
4940
5115
  */
4941
5116
  export declare function isUninterpretedAnswer(error: unknown): boolean;
4942
5117
  /**
4943
- * Classifies any thrown value from its code (and, for two codes, its HTTP status), never from
4944
- * message text, so an app does not have to re-derive "may I offer Retry?" and "is the outcome
4945
- * unknown?" for every code. The decision for each code is in this module's table; a new catalog
4946
- * code cannot be added without one.
4947
- *
4948
- * A failure BEFORE the request left (`error.phase === 'pre_send'`, `isPreSendError`) can never be
4949
- * `unknown` or `rejected`: it is `invalid_input` (the input has to change) or `not_sent` (nothing
4950
- * was transmitted; a repeat is safe). Every app-supplied callback the SDK calls before it sends
4951
- * (the signer, the key provider, a token resolver) has its failure wrapped into such an error
4952
- * (`SIGNING_FAILED`, `KEY_PROVIDER_FAILED`, `TOKEN_RESOLUTION_FAILED`, the original as `cause`),
4953
- * so an app NEVER needs an error class of its own to say "nothing was sent": a locked wallet,
4954
- * a declined signature and a failed lookup all arrive as `not_sent`, retryable.
4955
- *
4956
- * It accepts a `GSwapSDKError` or a plain-object VIEW of one ({@link FailureView}: `{ code,
4957
- * params?, status?, uniqueKey?, ... }`, the shape of the wrapper an app builds from an SDK error;
4958
- * `toFailureView` reads any value), and decides from the same fields, so an app does not need to
4959
- * keep the original error to ask. `{ afterQueued: true }` says the write is already queued (the
4960
- * step being classified is a confirmation): `retryable` is then always `false`.
4961
- *
4962
- * Anything that is not an SDK error or such a view, or a view whose `code` the catalog does not
4963
- * define, is `{ outcome: 'unknown', retryable: false }`: the SDK
4964
- * cannot say what happened, and refusing Retry is the safe answer. That is only what escapes AFTER
4965
- * the request left (an app requestor that rejects with its own error, a callback of yours that
4966
- * throws once bytes were sent). An error your own code raises BEFORE it calls the SDK says so
4967
- * itself: give it a code of its own and `outcome` (`{ code: 'POSITION_STALE', outcome: 'not_sent'
4968
- * }`), and the SDK answers with that outcome's classification and `mayHaveBeenQueued` is `false`.
4969
- * The declared `outcome` is read only for a code the catalog does not define.
5118
+ * The chain's own machine-readable `ErrorKey` of a failure (`'TOKEN_NOT_FOUND'`,
5119
+ * `'NOT_ENOUGH_LIQUIDITY'`, ...), for an app that maps a chain refusal to its own copy: the
5120
+ * `params.errorKey` of a `CHAIN_REJECTED` (an apply result, or a body that carries the chain's
5121
+ * error) and of a `CHAIN_DISPATCH_FAILED` (the gateway adds the chain's key to the body it
5122
+ * answered). `undefined` when the failure is neither, or when it carries no key (the gateway sent
5123
+ * none: the SDK writes `''`, which is not a key). Map the KEY, never the message text.
4970
5124
  *
4971
- * A failure is a WRITE's unless it states `write: false` (`GSwapSDKError.write`, set for every
4972
- * SDK read): see {@link FailureView}. A view that lost its `uniqueKey` is therefore still judged as
4973
- * a write (a 5xx stays `unknown`), never as a retryable read.
4974
- *
4975
- * To learn that a failure came from the dark (shadow) path, read `error.shadow` (a typed field of
4976
- * every `GSwapSDKError`) or call `isShadowError(error)`, which also covers a non-SDK object that
4977
- * escaped `swapShadow` / `submitSwapShadow` / `ChainGateway.submitShadow`. The classification is
4978
- * the same as on the public path; an app that withholds Retry or a public fallback after a dark
4979
- * swap applies that policy on top of `retryable`.
5125
+ * Accepts an SDK error or a plain-object view ({@link FailureView}: `code` and `params`); every
5126
+ * other value is `undefined`. Other codes are `undefined` even when they have an `errorKey`-named
5127
+ * param, so a stray field cannot pass for a chain verdict.
4980
5128
  *
4981
5129
  * @example
4982
5130
  * ```ts
4983
- * try {
4984
- * await swaps.swap('GALA', 'GUSDC', 3000, { exactIn: '100' });
4985
- * } catch (error) {
4986
- * const { outcome, retryable } = classifyFailure(error);
4987
- * if (outcome === 'unknown') keepPendingAndConfirm(error); // never a second swap
4988
- * else if (retryable) offerRetry(); // a new request under a fresh key
4989
- * }
5131
+ * const key = chainErrorKeyOf(error);
5132
+ * if (key === 'NOT_ENOUGH_LIQUIDITY') showTooThin(); else showGeneric(error);
4990
5133
  * ```
4991
5134
  */
4992
- export declare function classifyFailure(error: unknown, options?: ClassifyFailureOptions): FailureClassification;
4993
- /** Options of {@link classifyFailure}. */
4994
- export interface ClassifyFailureOptions {
4995
- /**
4996
- * The write is ALREADY queued (the gateway acknowledged it with this `uniqueKey`), and what is
4997
- * being classified is a later step: confirming it, reading its apply result. Whatever the
4998
- * outcome, `retryable` is then `false`: a NEW request would be a second trade, so the app
4999
- * confirms the same key (or forgets it) and never offers "Try again". `outcome` is unchanged.
5000
- *
5001
- * The one exception is `rejected`: the chain evaluated the queued write and refused it (an
5002
- * apply result of `Status: 0`, `CHAIN_REJECTED`; a 422 dispatch). That PROVES it was not
5003
- * applied, so a new request under a fresh key cannot make a second trade, and `retryable`
5004
- * keeps the answer it has without this option (`true`). Every outcome that does not prove
5005
- * "not applied" (`unknown`, `transient`, `not_queued`, ...) is `false`.
5006
- */
5007
- afterQueued?: boolean | undefined;
5008
- }
5135
+ export declare function chainErrorKeyOf(error: unknown): string | undefined;
5009
5136
  /**
5010
5137
  * True when a failure means "there is no market to trade this pair": `NO_POOL_AVAILABLE` (no pool
5011
5138
  * at any fee tier), `INSUFFICIENT_LIQUIDITY` (a pool too thin to quote), `UNKNOWN_TOKEN` (the DEX
@@ -5023,28 +5150,52 @@ export interface ClassifyFailureOptions {
5023
5150
  * ```
5024
5151
  */
5025
5152
  export declare function isNoMarket(error: unknown): boolean;
5153
+ //#endregion
5154
+ //#region src/utils/class_key.d.ts
5026
5155
  /**
5027
- * True when the failed call was a WRITE that may nevertheless have been queued: its outcome is
5028
- * `unknown` (`classifyFailure(error).outcome === 'unknown'`: a timeout or broken connection after
5029
- * the request left, an acknowledgement that proves nothing, a gateway 409 or 5xx, a failed
5030
- * confirmation). The app must keep `error.uniqueKey` and confirm it, and must NOT submit again
5031
- * under a fresh key. Every other outcome (`rejected`, `not_queued`, `not_sent`, `invalid_input`,
5032
- * `transient`) proves the write is not pending.
5156
+ * Token class keys that never throw: the `$`-joined composite key and the non-throwing parsers.
5157
+ * This module imports nothing at run time (the key type is erased), so an app shell that reads a
5158
+ * stored key pays for a few hundred bytes, never for the error class or the catalog. The parser
5159
+ * that THROWS an SDK error on a bad key (`parseTokenClassKey`) lives in `ordering.ts`.
5160
+ */
5161
+ /** Return the `$`-joined composite key used by GalaChain object identities. */
5162
+ export declare function compositeKeyOf(token: GalaChainTokenClassKey): string;
5163
+ /**
5164
+ * The non-throwing `parseTokenClassKey`: the class key, or `undefined` when `value` is not
5165
+ * one. A string is split exactly as `parseTokenClassKey` splits it (`|` form when it contains a
5166
+ * `|`, else `$`, from the right, all four parts non-empty). Unlike `parseTokenClassKey`, an
5167
+ * object is VALIDATED, not just copied: all four fields must be non-empty strings. Anything else
5168
+ * (`undefined`, `null`, a number, an array) is `undefined`, so it is safe on untrusted input (a
5169
+ * stored token, a URL parameter, a wallet row) without a `try`/`catch`.
5033
5170
  *
5034
- * A value the SDK cannot judge (an app requestor's own rejection after the request left) is
5035
- * `unknown` too, so it is `true`; handle errors your own code raised BEFORE calling the SDK first.
5036
- * Meant for the catch of a write; a read never has a pending key to keep.
5171
+ * Use {@link tryParseCompositeKey} instead when only the `$` form is valid input.
5037
5172
  *
5038
5173
  * @example
5039
5174
  * ```ts
5040
- * try {
5041
- * await swaps.swap('GALA', 'GUSDC', 3000, { exactIn: '100' });
5042
- * } catch (error) {
5043
- * if (mayHaveBeenQueued(error)) keepPendingAndConfirm(error);
5044
- * }
5175
+ * const key = tryParseTokenClassKey(row.compositeKey);
5176
+ * if (key === undefined) return failClosed(); // no class is known: never invent one from a symbol
5045
5177
  * ```
5046
5178
  */
5047
- export declare function mayHaveBeenQueued(error: unknown): boolean;
5179
+ export declare function tryParseTokenClassKey(value: unknown): GalaChainTokenClassKey | undefined;
5180
+ /**
5181
+ * Parses a `$`-joined composite key (`Collection$Category$Type$AdditionalKey`, what
5182
+ * {@link compositeKeyOf} writes) and nothing else, or `undefined`. It is {@link tryParseTokenClassKey}
5183
+ * for a string that may ONLY be in the `$` form: a key that contains `|` is NOT read as the pipe
5184
+ * form here (it stays part of a segment), and only a string is accepted. The split is from the
5185
+ * right, so a collection that itself contains `$` (production's `$GMUSIC`, stage's
5186
+ * `$GMUSIC_TEST1`) stays whole; `'GALA'`, `'GALA$Unit$none'`, `'ETIME$$$'`, `'GALA$Unit$none$'` and
5187
+ * `'$$$$'` are `undefined`.
5188
+ *
5189
+ * It replaces an app's own `parseCompositeKey(key): Components | null` (`?? null`), which had
5190
+ * exactly these semantics.
5191
+ *
5192
+ * @example
5193
+ * ```ts
5194
+ * tryParseCompositeKey('$GMUSIC_TEST1$Unit$none$none')?.collection; // '$GMUSIC_TEST1'
5195
+ * tryParseCompositeKey('GALA$Unit$none'); // undefined
5196
+ * ```
5197
+ */
5198
+ export declare function tryParseCompositeKey(value: unknown): GalaChainTokenClassKey | undefined;
5048
5199
  //#endregion
5049
5200
  //#region src/utils/shadow_errors.d.ts
5050
5201
  /**
@@ -5065,7 +5216,71 @@ export declare function mayHaveBeenQueued(error: unknown): boolean;
5065
5216
  */
5066
5217
  export declare function isShadowError(value: unknown): boolean;
5067
5218
  //#endregion
5068
- //#region src/utils/ticks.d.ts
5219
+ //#region src/utils/tick_align.d.ts
5220
+ /**
5221
+ * {@link alignTickDown} that answers `NaN` instead of throwing: the greatest multiple of `spacing`
5222
+ * that is no greater than `tick`, or `NaN` when `spacing` is not a positive integer (a pool whose
5223
+ * spacing has not loaded yet) or `tick` is not a number. For an app shell and for a drag handler,
5224
+ * which must not throw while the spacing is missing. `alignTickDown` (the SDK's own call sites use
5225
+ * it) gives the same value and throws for the bad spacing.
5226
+ *
5227
+ * @example
5228
+ * ```ts
5229
+ * alignTickDownOrNaN(-61, 60); // -120: it floors, it does not truncate toward zero
5230
+ * alignTickDownOrNaN(100, 0); // NaN
5231
+ * ```
5232
+ */
5233
+ export declare function alignTickDownOrNaN(tick: number, spacing: number): number;
5234
+ /**
5235
+ * {@link alignTickUp} that answers `NaN` instead of throwing: the least multiple of `spacing` that
5236
+ * is no less than `tick`, or `NaN` for a spacing that is not a positive integer. See
5237
+ * {@link alignTickDownOrNaN}.
5238
+ */
5239
+ export declare function alignTickUpOrNaN(tick: number, spacing: number): number;
5240
+ //#endregion
5241
+ //#region src/utils/tick_range.d.ts
5242
+ /**
5243
+ * Whether a pool's current tick lies inside a position's range, by the contract's own rule. This
5244
+ * module imports nothing, so an app shell (a position badge, a filter) pays for a few dozen bytes.
5245
+ */
5246
+ /** A tick as the chain and the backends write it: a number, or the decimal string of one. */
5247
+ type TickInput = number | string;
5248
+ /**
5249
+ * True when a position over `[tickLower, tickUpper)` is IN RANGE at `currentTick`: the lower tick
5250
+ * is INCLUSIVE and the upper tick is EXCLUSIVE. That is the GalaChainDex contract's rule
5251
+ * (`DexV3Pool`: `tickCurrent >= tickLower && tickCurrent < tickUpper` is the case in which a
5252
+ * position holds both tokens and earns fees). A pool whose tick equals `tickUpper` is already out
5253
+ * of range: the position is entirely token1 there, and a swap through the tick has crossed it.
5254
+ *
5255
+ * `currentTick` is the pool's tick (`slot0.tick`, the greatest tick whose price is no greater than
5256
+ * the pool's price), not a rounded display value. A tick may be a number or the decimal string a
5257
+ * backend returns. Anything that is not an integer (`NaN`, `undefined`-like, an empty string, a
5258
+ * fraction) makes the answer `false`: an app that must tell "not loaded yet" from "out of range"
5259
+ * checks for the missing value itself first.
5260
+ *
5261
+ * Do NOT decide range by comparing a price with a tick's price (`tickToPrice`) using `<=` on both
5262
+ * ends, or by mixing a square-root price with a price. A price exactly on a tick's boundary is
5263
+ * then in range at the upper edge (the contract says it is not), and two representations of the
5264
+ * same boundary can round to opposite sides. For a pool price use {@link isSqrtPriceInRange}, which
5265
+ * derives the tick the way the contract does and then applies this rule.
5266
+ *
5267
+ * @example
5268
+ * ```ts
5269
+ * isTickInRange(-60, -60, 60); // true: the lower tick is inclusive
5270
+ * isTickInRange(60, -60, 60); // false: the upper tick is exclusive
5271
+ * ```
5272
+ */
5273
+ export declare function isTickInRange(currentTick: TickInput, tickLower: TickInput, tickUpper: TickInput): boolean;
5274
+ //#endregion
5275
+ //#region src/utils/tick_math.d.ts
5276
+ /**
5277
+ * Tick and price arithmetic that never throws an SDK error: the contract's tick bounds, the
5278
+ * conversions between ticks and prices, and nothing that validates a range. It imports only the
5279
+ * two number libraries it computes with, never the `GSwapSDKError` class or the error catalog
5280
+ * (functions that must throw, `alignTickDown` and `assertTickRange`, are in `ticks.ts`), so an
5281
+ * app shell that prices a tick pays for the libraries and these few functions, not for ~25 kB of
5282
+ * error templates. A value that cannot be computed is `NaN`, never an exception.
5283
+ */
5069
5284
  /** Minimum tick supported by GalaChainDex. */
5070
5285
  export declare const GC_MIN_TICK = -887272;
5071
5286
  /** Maximum tick supported by GalaChainDex. */
@@ -5084,8 +5299,26 @@ export declare function sqrtPriceToTick(sqrtPrice: BigNumber.Value): number;
5084
5299
  * the last digits of a double: that expression multiplies in floating point first).
5085
5300
  */
5086
5301
  export declare function tickToPrice(tick: number): BigNumber;
5302
+ /**
5303
+ * {@link isTickInRange} for a pool's square-root price instead of its tick (a position row that
5304
+ * carries `sqrtPrice`, `tickLower` and `tickUpper`). The tick is derived from the price exactly as
5305
+ * the contract does (`sqrtPriceToTick`: the greatest tick whose square-root price is no greater
5306
+ * than the price, exact to 60 digits), then the contract's rule applies: lower tick inclusive,
5307
+ * upper tick exclusive. So a pool sitting exactly on `tickLower`'s price is in range, and exactly
5308
+ * on `tickUpper`'s price is not, and no float rounding can flip either.
5309
+ *
5310
+ * `false` for a price that is not positive and finite (not loaded, zero, `NaN`): it says nothing
5311
+ * about the position, so an app that must show a neutral state checks for the missing price
5312
+ * itself first. `tickLower` and `tickUpper` follow {@link isTickInRange}.
5313
+ *
5314
+ * @example
5315
+ * ```ts
5316
+ * const inRange = isSqrtPriceInRange(position.sqrtPrice, position.tickLower, position.tickUpper);
5317
+ * ```
5318
+ */
5319
+ export declare function isSqrtPriceInRange(sqrtPrice: BigNumber.Value, tickLower: TickInput, tickUpper: TickInput): boolean;
5087
5320
  /** How {@link tickFromPrice} turns the exact logarithm into an integer tick. */
5088
- export interface TickFromPriceOptions {
5321
+ interface TickFromPriceOptions {
5089
5322
  /**
5090
5323
  * `'floor'` (default): the greatest tick whose price is no greater than `price`, which is how
5091
5324
  * the contract places a price. `'nearest'`: the closest tick, a half rounding away from zero.
@@ -5100,6 +5333,14 @@ export interface TickFromPriceOptions {
5100
5333
  * is not positive and finite.
5101
5334
  */
5102
5335
  export declare function tickFromPrice(price: BigNumber.Value, options?: TickFromPriceOptions): number;
5336
+ //#endregion
5337
+ //#region src/utils/ticks.d.ts
5338
+ /**
5339
+ * The tick functions that THROW an SDK error on a bad input (`alignTickDown`, `alignTickUp`,
5340
+ * `assertTickRange`, `frameSlot0`). The arithmetic that never throws (`tickToPrice`,
5341
+ * `tickFromPrice`, `tickToSqrtPrice`, `sqrtPriceToTick`, the bounds) is in `tick_math.ts`, which
5342
+ * does not import the error class or the catalog; import it from the package entry as usual.
5343
+ */
5103
5344
  /** Align a tick down to the nearest multiple of a positive spacing. */
5104
5345
  export declare function alignTickDown(tick: number, spacing: number): number;
5105
5346
  /** Align a tick up to the nearest multiple of a positive spacing. */
@@ -5147,12 +5388,55 @@ export declare function frameSlot0(slot0: {
5147
5388
  export declare function isValidUniqueKey(uniqueKey: unknown): uniqueKey is string;
5148
5389
  //#endregion
5149
5390
  //#region src/utils/validation.d.ts
5391
+ /**
5392
+ * Validates a decimal amount: a string or `BigNumber`, never a JavaScript number.
5393
+ *
5394
+ * @param amount - The amount to check.
5395
+ * @param parameterName - The field name reported in the error's `params.field`.
5396
+ * @param allowZero - Accept zero (default `false`).
5397
+ * @throws GSwapSDKError `AMOUNT_IS_JS_NUMBER`, `AMOUNT_NOT_FINITE`, `AMOUNT_NOT_POSITIVE` (zero
5398
+ * when `allowZero` is false) or `AMOUNT_NEGATIVE`.
5399
+ */
5150
5400
  export declare function validateNumericAmount(amount: NumericAmount, parameterName: string, allowZero?: boolean): void;
5401
+ /**
5402
+ * Validates a spot price and a lower/upper price range: none a JavaScript number, all positive and
5403
+ * finite (a non-finite upper bound counts as an unbounded `1e18`), and `lowerPrice <= upperPrice`.
5404
+ *
5405
+ * @throws GSwapSDKError `PRICE_VALUES_IS_JS_NUMBER`, `INVALID_PRICE_VALUES` or `INVALID_PRICE_RANGE`.
5406
+ */
5151
5407
  export declare function validatePriceValues(spotPrice: NumericAmount, lowerPrice: NumericAmount, upperPrice: NumericAmount): void;
5408
+ /**
5409
+ * Validates a token's decimals: a non-negative integer.
5410
+ *
5411
+ * @throws GSwapSDKError `INVALID_TOKEN_DECIMALS` (`params.field` is `parameterName`).
5412
+ */
5152
5413
  export declare function validateTokenDecimals(decimals: number, parameterName: string): void;
5414
+ /**
5415
+ * Validates a position's tick range: two integers with `tickLower < tickUpper`, both within
5416
+ * `GC_MIN_TICK`..`GC_MAX_TICK`. It does not check alignment to a fee tier's spacing (see
5417
+ * `assertTickRange`).
5418
+ *
5419
+ * @throws GSwapSDKError `TICKS_NOT_INTEGERS`, `INVALID_TICK_RANGE` or `TICKS_OUT_OF_BOUNDS`.
5420
+ */
5153
5421
  export declare function validateTickRange(tickLower: number, tickUpper: number): void;
5422
+ /**
5423
+ * Asserts that `fee` is one of the fee tiers in `ALL_FEE_TIERS` (`0`, `500`, `3000`, `10000`).
5424
+ *
5425
+ * @throws GSwapSDKError `INVALID_FEE` (`params.field` `'fee'`, `params.allowed` the tiers).
5426
+ */
5154
5427
  export declare function validateFee(fee: number): asserts fee is FEE_TIER;
5428
+ /**
5429
+ * Validates a tick spacing: a positive integer.
5430
+ *
5431
+ * @throws GSwapSDKError `INVALID_TICK_SPACING`.
5432
+ */
5155
5433
  export declare function validateTickSpacing(tickSpacing: number): void;
5434
+ /**
5435
+ * Asserts that a wallet address was given and is a non-blank string. It does not check the address
5436
+ * format.
5437
+ *
5438
+ * @throws GSwapSDKError `MISSING_WALLET_ADDRESS` (undefined) or `INVALID_WALLET_ADDRESS` (blank).
5439
+ */
5156
5440
  export declare function validateWalletAddress(address?: string): asserts address is string;
5157
5441
  /**
5158
5442
  * True when `symbol` is acceptable to propose into the trading-symbol registry: ASCII letters and
@@ -5221,5 +5505,5 @@ export declare function isWalletUserRejection(value: unknown): boolean;
5221
5505
  */
5222
5506
  export declare function walletDeclineCode(value: unknown): number | string | undefined;
5223
5507
  //#endregion
5224
- export type { AddLiquidityInput, ConfirmationState, CreatePoolInput, EIP712DomainValue, EIP712Types, EntryParse, FailureOutcome, FailureView, GSwapErrorCode, GSwapErrorParams, GSwapErrorPhase, GSwapErrorShape, InvalidEntry, InvalidEntryHandler, InvalidPrivateKeyReason, PersonalSignChainDtoPayload, PoolPositionInput, PrivateKeyInput, RemoveLiquidityInput, RequestTradeInput, SigningFailureReason, SubmissionOutcomeUnknownReason, TypedDataPayload, V2WriteMethod };
5508
+ export type { AddLiquidityInput, ConfirmationState, CreatePoolInput, EIP712DomainValue, EIP712Types, EntryParse, FailureOutcome, FailureView, GSwapErrorCode, GSwapErrorParams, GSwapErrorPhase, GSwapErrorShape, InvalidEntry, InvalidEntryHandler, InvalidPrivateKeyReason, PersonalSignChainDtoPayload, PoolPositionInput, PrivateKeyInput, RemoveLiquidityInput, RequestTradeInput, SigningFailureReason, SubmissionOutcomeUnknownReason, TickFromPriceOptions, TickInput, TypedDataPayload, V2WriteMethod };
5225
5509
  //# sourceMappingURL=index.d.cts.map