@gala-chain/gswap-sdk 2.1.0-beta.4 → 2.1.0-beta.5
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.
- package/dist/browser/classes/dex_fees.js +1 -1
- package/dist/browser/classes/dex_fees.js.map +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/index.cjs +22 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.mjs +22 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e from"../_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/defineProperty.js";import{GSwapSDKError as t}from"./gswap_sdk_error.js";import{buildRequestHeaders as n,createUniqueKey as r,fetchRequestor as i,readResponseBody as a,requestWithTimeout as o,signPreSend as s}from"@gala-chain/gala-core-sdk";const c=[`Swap`,`RequestTrade`,`AddLiquidity`,`RemoveLiquidity`,`CollectPositionFees`,`CreatePool`],l=`DryRun`,u=`galaconnect-operation-`;function d(e){return typeof e==`string`&&c.includes(e)}function f(e,t){return d(t)&&typeof e?.token0==`string`&&typeof e.token1==`string`}function p(e){let t={...e};for(let e of[`signature`,`prefix`,`types`,`domain`,`dtoOperation`,`trace`])delete t[e];return t}function
|
|
1
|
+
import e from"../_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/defineProperty.js";import{GSwapSDKError as t}from"./gswap_sdk_error.js";import{buildRequestHeaders as n,createUniqueKey as r,fetchRequestor as i,readResponseBody as a,requestWithTimeout as o,signPreSend as s}from"@gala-chain/gala-core-sdk";const c=[`Swap`,`RequestTrade`,`AddLiquidity`,`RemoveLiquidity`,`CollectPositionFees`,`CreatePool`],l=`DryRun`,u=`galaconnect-operation-`;function d(e){return typeof e==`string`&&c.includes(e)}function f(e,t){return d(t)&&typeof e?.token0==`string`&&typeof e.token1==`string`}function p(e){return e.replace(/(?:\/+|\/api\/v1(?=\/|$))+$/u,``)}function m(e){let t={...e};for(let e of[`signature`,`prefix`,`types`,`domain`,`dtoOperation`,`trace`])delete t[e];return t}function h(e,t,n,i,a=u,o=`asset/dexv3-contract`){return s(e,o,l,{callerPublicKey:t,method:n,dto:m(i),uniqueKey:r(a)})}var g=class{constructor(t,n){this.signer=n,e(this,`requestor`,void 0),e(this,`baseUrl`,void 0),e(this,`requestTimeoutMs`,void 0),e(this,`wire`,void 0),this.requestor=t.httpRequestor??i,this.baseUrl=p(t.dexBackendBaseUrl),this.requestTimeoutMs=t.requestTimeoutMs??3e4,this.wire=t.wire}async quote(e,r,i,s={}){if(this.signer===void 0)throw t.noSignerError();let c=s.channel??`asset`,l=s.contract??`dexv3-contract`,u=await h(this.signer,e,r,m(i),void 0,`asset/${l}`),d=`${this.baseUrl}/api/v1/wallet/connect/galachain/api/${encodeURIComponent(c)}/${encodeURIComponent(l)}/${encodeURIComponent(r)}/fee`,f,p,g;try{let e=await o(this.requestor,d,{method:`POST`,headers:n(this.wire,{json:!0,defaults:{Accept:`application/json`}}),body:JSON.stringify(u)},this.requestTimeoutMs);f=e.status,p=e.ok,g=p?await a(e):void 0}catch{return null}return p?_(g):l===`dex-contract`&&f===403?{source:`default`,fees:[{feeInGala:`0`}]}:null}};function _(e){if(typeof e!=`object`||!e)return null;let t=e.fees;return!Array.isArray(t)||typeof t[0]?.feeInGala!=`string`?null:e}export{c as DEX_FEE_METHODS,l as DRY_RUN_METHOD,u as DRY_RUN_UNIQUE_KEY_PREFIX,g as DexFees,h as buildDryRunWrapper,p as dexBackendRoot,f as isCurrentContractDexMessage,d as isDexFeeMethod,m as toChainDto};
|
|
2
2
|
//# sourceMappingURL=dex_fees.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dex_fees.js","names":["_defineProperty","DEX_FEE_METHODS","DRY_RUN_METHOD","DRY_RUN_UNIQUE_KEY_PREFIX","isDexFeeMethod","method","isCurrentContractDexMessage","message","\"token0\"","\"token1\"","toChainDto","chainDto","field","buildDryRunWrapper","signPreSend","signer","contractPath","dto","createUniqueKey","uniqueKeyPrefix","DexFees","client","fetchRequestor","GSwapSDKError","channel","options","contract","wrapper","callerPublicKey","url","status","ok","body","response","requestWithTimeout","buildRequestHeaders","readResponseBody","readQuote","fees"],"sources":["../../../src/classes/dex_fees.ts"],"sourcesContent":["import {\n buildRequestHeaders,\n createUniqueKey,\n fetchRequestor,\n readResponseBody,\n requestWithTimeout,\n signPreSend,\n type ChainContractPath,\n type GalaChainSigner,\n type HttpRequestor,\n type WireOptions,\n} from '@gala-chain/gala-core-sdk';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\n\n/** DEX methods the backend accepts a fee quote for (its allow-list enumerates the same six). */\nexport const DEX_FEE_METHODS = [\n 'Swap',\n 'RequestTrade',\n 'AddLiquidity',\n 'RemoveLiquidity',\n 'CollectPositionFees',\n 'CreatePool',\n] as const;\n/** A chain method whose network fee `DexFees.quote` can price (see `isDexFeeMethod`). */\nexport type DexFeeMethod = (typeof DEX_FEE_METHODS)[number];\n\n/** Which pool contract the DTO being quoted targets: legacy (V3) or current (GalaChainDex). */\nexport type DexFeeContract = 'dexv3-contract' | 'dex-contract';\n\n/** The chain method name the signed DryRun wrapper is signed under. */\nexport const DRY_RUN_METHOD = 'DryRun';\n\n/** `uniqueKey` prefix of the DryRun WRAPPER (distinct from the inner DTO's key). */\nexport const DRY_RUN_UNIQUE_KEY_PREFIX = 'galaconnect-operation-';\n\n/** True when `method` is a DEX method a fee can be quoted for. */\nexport function isDexFeeMethod(method: unknown): method is DexFeeMethod {\n return typeof method === 'string' && (DEX_FEE_METHODS as readonly string[]).includes(method);\n}\n\n/** Current-contract typed DEX messages use trading symbols instead of TokenClassKey objects. */\nexport function isCurrentContractDexMessage(\n message: Record<string, unknown> | null | undefined,\n method: unknown,\n): boolean {\n return (\n isDexFeeMethod(method) &&\n typeof message?.['token0'] === 'string' &&\n typeof message['token1'] === 'string'\n );\n}\n\n/**\n * The backend's response. It ALWAYS carries a usable `fees[0].feeInGala`: the backend decides what\n * to serve when the chain cannot price the operation, so the client never invents a fee.\n *\n * `source` is informational: `'dry-run'` is simulated on chain and authoritative (possibly a\n * legitimate `'0'`), `'default'` means the chain could not price it and the platform default was\n * served.\n */\nexport interface DexFeeQuote {\n fees: Array<{ feeInGala: string }>;\n source: 'dry-run' | 'default';\n}\n\n/**\n * Reduces an EIP-712 approval `message` to the DTO the chain actually receives: drops the signing\n * envelope (`signature`, `prefix`, `types`, `domain`), the `dtoOperation` it was signed to call (a\n * DryRun runs the DTO inside a wrapper signed for `DryRun`; left inside, the chain refuses it:\n * \"signed to call ...:RequestTrade, but the current operation is ...:DryRun\") and transport\n * metadata (`trace`).\n */\nexport function toChainDto(message: Record<string, unknown>): Record<string, unknown> {\n const chainDto: Record<string, unknown> = { ...message };\n for (const field of ['signature', 'prefix', 'types', 'domain', 'dtoOperation', 'trace']) {\n delete chainDto[field];\n }\n return chainDto;\n}\n\n/**\n * Signs the DryRun WRAPPER the gateway accepts for every contract:\n * `{ callerPublicKey, method, dto: <inner DTO object>, uniqueKey, signature }`. The inner DTO\n * travels unsigned and as an object; no `signerPublicKey` is sent because the signature already\n * recovers it (the gateway rejects it as REDUNDANT_SIGNER_PUBLIC_KEY). The wrapper carries its own\n * `uniqueKey`, distinct from the DTO's, and its own `dtoOperation` (`<Contract>:DryRun`); the inner DTO\n * carries none of the signing envelope or the `dtoOperation` of the call it simulates (see\n * {@link toChainDto}), whatever the caller passes, so a signed DTO can be handed in as is.\n */\nexport function buildDryRunWrapper(\n signer: GalaChainSigner,\n callerPublicKey: string,\n method: string,\n dto: Record<string, unknown>,\n uniqueKeyPrefix: string = DRY_RUN_UNIQUE_KEY_PREFIX,\n contractPath: ChainContractPath = 'asset/dexv3-contract',\n): Promise<Record<string, unknown>> {\n return signPreSend(signer, contractPath, DRY_RUN_METHOD, {\n callerPublicKey,\n method,\n dto: toChainDto(dto),\n // Core's RN-safe mint (`getRandomValues`, never `randomUUID`, which Hermes lacks).\n uniqueKey: createUniqueKey(uniqueKeyPrefix),\n });\n}\n\n/** The transport and backend a fee quote reads from. */\nexport interface DexFeesClient {\n /** Swap backend origin, e.g. `https://dex-backend-prod1.defi.gala.com`. */\n dexBackendBaseUrl: string;\n /** Defaults to the global `fetch`. */\n httpRequestor?: HttpRequestor | undefined;\n /** Per-request timeout in milliseconds (default 30 000). */\n requestTimeoutMs?: number | undefined;\n /**\n * Request headers of the fee POST (`userAgent`, `headers`); see {@link WireOptions}. The SDK's\n * `Accept: application/json` is a default that `wire.headers` may replace.\n */\n wire?: WireOptions | undefined;\n}\n\n/** Options for a single quote. */\nexport interface DexFeeQuoteOptions {\n /** GalaChain channel. Default `asset`. */\n channel?: string | undefined;\n /**\n * Contract the DTO targets. Default `dexv3-contract` (what every legacy caller quotes against);\n * a current-contract operation must pass `dex-contract` explicitly.\n */\n contract?: DexFeeContract | undefined;\n}\n\n/**\n * Network-fee quote for GalaChain DEX methods, derived from a server-side DryRun.\n *\n * The client only SIGNS the DryRun wrapper (with whatever {@link GalaChainSigner} it is given) and\n * the backend forwards it to the gateway, where the simulated writes carry the fee; the backend\n * never holds a key. Intended for wallets: the DTO quoted is the typed message a dApp handed over.\n *\n * @example\n * ```ts\n * const fees = new DexFees({ dexBackendBaseUrl }, new PrivateKeySigner(sessionKey));\n * const quote = await fees.quote(publicKey, 'RequestTrade', toChainDto(message), {\n * contract: 'dex-contract',\n * });\n * const feeInGala = quote?.fees[0]?.feeInGala;\n * ```\n */\nexport class DexFees {\n private readonly requestor: HttpRequestor;\n private readonly baseUrl: string;\n private readonly requestTimeoutMs: number;\n private readonly wire: WireOptions | undefined;\n\n constructor(\n client: DexFeesClient,\n private readonly signer: GalaChainSigner | undefined,\n ) {\n this.requestor = client.httpRequestor ?? fetchRequestor;\n this.baseUrl = client.dexBackendBaseUrl.replace(/\\/$/u, '');\n this.requestTimeoutMs = client.requestTimeoutMs ?? 30_000;\n this.wire = client.wire;\n }\n\n /**\n * Quotes the network fee for `method` applied to `message`. The message is reduced with\n * {@link toChainDto} first, so an EIP-712 approval message can be passed as is.\n *\n * Resolves `null` when the BACKEND could not be reached or answered unusably (offline, 4xx/5xx,\n * malformed body): a transport outcome, not a fee. Deciding what to charge when the chain is\n * silent is the backend's job (it serves `source: 'default'`), so the client never substitutes\n * a fee of its own, with ONE exception that mirrors the wallet: a `dex-contract` quote answered\n * 403 or 404 means the contract has no fee route yet and resolves `{ source: 'default', '0' }`.\n * Never throws on transport, so a fee lookup cannot block or break a signing screen.\n *\n * @throws GSwapSDKError NO_SIGNER when constructed without a signer; `SIGNING_FAILED` or\n * `KEY_PROVIDER_FAILED` (a pre-send error, the original as `cause`) when the signer fails, for\n * example a locked wallet.\n */\n public async quote(\n callerPublicKey: string,\n method: DexFeeMethod,\n message: Record<string, unknown>,\n options: DexFeeQuoteOptions = {},\n ): Promise<DexFeeQuote | null> {\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n const channel = options.channel ?? 'asset';\n const contract = options.contract ?? 'dexv3-contract';\n const wrapper = await buildDryRunWrapper(\n this.signer,\n callerPublicKey,\n method,\n toChainDto(message),\n undefined,\n `asset/${contract}`,\n );\n const url = `${this.baseUrl}/wallet/connect/galachain/api/${encodeURIComponent(channel)}/${encodeURIComponent(contract)}/${encodeURIComponent(method)}/fee`;\n\n let status: number;\n let ok: boolean;\n let body: unknown;\n try {\n const response = await requestWithTimeout(\n this.requestor,\n url,\n {\n method: 'POST',\n headers: buildRequestHeaders(this.wire, {\n json: true,\n defaults: { Accept: 'application/json' },\n }),\n body: JSON.stringify(wrapper),\n },\n this.requestTimeoutMs,\n );\n status = response.status;\n ok = response.ok;\n body = ok ? await readResponseBody(response) : undefined;\n } catch {\n return null;\n }\n\n if (!ok) {\n if (contract === 'dex-contract' && (status === 403 || status === 404)) {\n return { source: 'default', fees: [{ feeInGala: '0' }] };\n }\n return null;\n }\n // Accept whatever fee the backend served: 'default' is as usable as 'dry-run'. Only a body\n // missing the fee outright is unusable.\n return readQuote(body);\n }\n}\n\nfunction readQuote(body: unknown): DexFeeQuote | null {\n if (typeof body !== 'object' || body === null) return null;\n const fees = (body as { fees?: unknown }).fees;\n if (\n !Array.isArray(fees) ||\n typeof (fees[0] as { feeInGala?: unknown } | undefined)?.feeInGala !== 'string'\n ) {\n return null;\n }\n return body as DexFeeQuote;\n}\n"],"mappings":"A,oTAeA,MAAaC,EAAkB,CAC7B,OACA,eACA,eACA,kBACA,sBACA,YACF,EAQaC,EAAiB,SAGjBC,EAA4B,yBAGzC,SAAgBC,EAAe,EAAyC,CACtE,OAAO,OAAOC,GAAW,UAAaJ,EAAsC,SAASI,CAAM,CAC7F,CAGA,SAAgBC,EACd,EACA,EACS,CACT,OACEF,EAAeC,CAAM,GACrB,OAAOE,GAAUC,QAAc,UAC/B,OAAOD,EAAQE,QAAc,QAEjC,CAsBA,SAAgBC,EAAW,EAA2D,CACpF,IAAMC,EAAoC,CAAE,GAAGJ,CAAQ,EACvD,IAAK,IAAMK,IAAS,CAAC,YAAa,SAAU,QAAS,SAAU,eAAgB,OAAO,EACpF,OAAOD,EAASC,GAElB,OAAOD,CACT,CAWA,SAAgBE,EACd,EACA,EACA,EACA,EACA,EAA0BV,EAC1B,EAAkC,uBACA,CAClC,OAAOW,EAAYC,EAAQC,EAAcd,EAAgB,CACvD,kBACA,SACA,IAAKQ,EAAWO,CAAG,EAEnB,UAAWC,EAAgBC,CAAe,CAC5C,CAAC,CACH,CA4CA,IAAaC,EAAb,KAAqB,CAMnB,YACE,EACA,EACA,CADiB,KAAA,OAAAL,EAPFf,EAAA,KAAA,YAAA,IAAA,EAAA,EACAA,EAAA,KAAA,UAAA,IAAA,EAAA,EACAA,EAAA,KAAA,mBAAA,IAAA,EAAA,EACAA,EAAA,KAAA,OAAA,IAAA,EAAA,EAMf,KAAK,UAAYqB,EAAO,eAAiBC,EACzC,KAAK,QAAUD,EAAO,kBAAkB,QAAQ,OAAQ,EAAE,EAC1D,KAAK,iBAAmBA,EAAO,kBAAoB,IACnD,KAAK,KAAOA,EAAO,IACrB,CAiBA,MAAa,MACX,EACA,EACA,EACA,EAA8B,CAAC,EACF,CAC7B,GAAI,KAAK,SAAW,IAAA,GAAW,MAAME,EAAc,cAAc,EACjE,IAAMC,EAAUC,EAAQ,SAAW,QAC7BC,EAAWD,EAAQ,UAAY,iBAC/BE,EAAU,MAAMd,EACpB,KAAK,OACLe,EACAvB,EACAK,EAAWH,CAAO,EAClB,IAAA,GACA,SAASmB,GACX,EACMG,EAAM,GAAG,KAAK,QAAQ,gCAAgC,mBAAmBL,CAAO,EAAE,GAAG,mBAAmBE,CAAQ,EAAE,GAAG,mBAAmBrB,CAAM,EAAE,MAElJyB,EACAC,EACAC,EACJ,GAAI,CACF,IAAMC,EAAW,MAAMC,EACrB,KAAK,UACLL,EACA,CACE,OAAQ,OACR,QAASM,EAAoB,KAAK,KAAM,CACtC,KAAM,GACN,SAAU,CAAE,OAAQ,kBAAmB,CACzC,CAAC,EACD,KAAM,KAAK,UAAUR,CAAO,CAC9B,EACA,KAAK,gBACP,EACA,EAASM,EAAS,OAClB,EAAKA,EAAS,GACd,EAAOF,EAAK,MAAMK,EAAiBH,CAAQ,EAAI,IAAA,EACjD,MAAQ,CACN,OAAO,IACT,CAUA,OARKF,EAQEM,EAAUL,CAAI,EAPfN,IAAa,iBAAmBI,IAAW,KAAOA,IAAW,KACxD,CAAE,OAAQ,UAAW,KAAM,CAAC,CAAE,UAAW,GAAI,CAAC,CAAE,EAElD,IAKX,CACF,EAEA,SAASO,EAAU,EAAmC,CACpD,GAAI,OAAOL,GAAS,WAAYA,EAAe,OAAO,KACtD,IAAMM,EAAQN,EAA4B,KAO1C,MALE,CAAC,MAAM,QAAQM,CAAI,GACnB,OAAQA,EAAK,EAAE,EAA0C,WAAc,SAEhE,KAEFN,CACT,C"}
|
|
1
|
+
{"version":3,"file":"dex_fees.js","names":["_defineProperty","DEX_FEE_METHODS","DRY_RUN_METHOD","DRY_RUN_UNIQUE_KEY_PREFIX","isDexFeeMethod","method","isCurrentContractDexMessage","message","\"token0\"","\"token1\"","dexBackendRoot","base","toChainDto","chainDto","field","buildDryRunWrapper","signPreSend","signer","contractPath","dto","createUniqueKey","uniqueKeyPrefix","DexFees","client","fetchRequestor","GSwapSDKError","channel","options","contract","wrapper","callerPublicKey","url","status","ok","body","response","requestWithTimeout","buildRequestHeaders","readResponseBody","readQuote","fees"],"sources":["../../../src/classes/dex_fees.ts"],"sourcesContent":["import {\n buildRequestHeaders,\n createUniqueKey,\n fetchRequestor,\n readResponseBody,\n requestWithTimeout,\n signPreSend,\n type ChainContractPath,\n type GalaChainSigner,\n type HttpRequestor,\n type WireOptions,\n} from '@gala-chain/gala-core-sdk';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\n\n/** DEX methods the backend accepts a fee quote for (its allow-list enumerates the same six). */\nexport const DEX_FEE_METHODS = [\n 'Swap',\n 'RequestTrade',\n 'AddLiquidity',\n 'RemoveLiquidity',\n 'CollectPositionFees',\n 'CreatePool',\n] as const;\n/** A chain method whose network fee `DexFees.quote` can price (see `isDexFeeMethod`). */\nexport type DexFeeMethod = (typeof DEX_FEE_METHODS)[number];\n\n/** Which pool contract the DTO being quoted targets: legacy (V3) or current (GalaChainDex). */\nexport type DexFeeContract = 'dexv3-contract' | 'dex-contract';\n\n/** The chain method name the signed DryRun wrapper is signed under. */\nexport const DRY_RUN_METHOD = 'DryRun';\n\n/** `uniqueKey` prefix of the DryRun WRAPPER (distinct from the inner DTO's key). */\nexport const DRY_RUN_UNIQUE_KEY_PREFIX = 'galaconnect-operation-';\n\n/** True when `method` is a DEX method a fee can be quoted for. */\nexport function isDexFeeMethod(method: unknown): method is DexFeeMethod {\n return typeof method === 'string' && (DEX_FEE_METHODS as readonly string[]).includes(method);\n}\n\n/** Current-contract typed DEX messages use trading symbols instead of TokenClassKey objects. */\nexport function isCurrentContractDexMessage(\n message: Record<string, unknown> | null | undefined,\n method: unknown,\n): boolean {\n return (\n isDexFeeMethod(method) &&\n typeof message?.['token0'] === 'string' &&\n typeof message['token1'] === 'string'\n );\n}\n\n/**\n * The backend's response. It ALWAYS carries a usable `fees[0].feeInGala`: the backend decides what\n * to serve when the chain cannot price the operation, so the client never invents a fee.\n *\n * `source` is informational: `'dry-run'` is simulated on chain and authoritative (possibly a\n * legitimate `'0'`), `'default'` means the chain could not price it and the platform default was\n * served.\n */\nexport interface DexFeeQuote {\n fees: Array<{ feeInGala: string }>;\n source: 'dry-run' | 'default';\n}\n\n/** The wallet-connect proxy's fee route, below the backend root (stage, 2026-11-02: only this prefix exists). */\nconst FEE_ROUTE_PREFIX = '/api/v1/wallet/connect/galachain/api';\n\n/**\n * The backend root a fee quote is built on: `base` without trailing slashes and without a trailing\n * `/api/v1` (the wallet passes the versioned base, the SDK presets the host root). Idempotent.\n *\n * @example\n * ```typescript\n * dexBackendRoot('https://swap-backend.stage.defi.ovh.gala.com/api/v1/'); // 'https://swap-backend.stage.defi.ovh.gala.com'\n * ```\n */\nexport function dexBackendRoot(base: string): string {\n return base.replace(/(?:\\/+|\\/api\\/v1(?=\\/|$))+$/u, '');\n}\n\n/**\n * Reduces an EIP-712 approval `message` to the DTO the chain actually receives: drops the signing\n * envelope (`signature`, `prefix`, `types`, `domain`), the `dtoOperation` it was signed to call (a\n * DryRun runs the DTO inside a wrapper signed for `DryRun`; left inside, the chain refuses it:\n * \"signed to call ...:RequestTrade, but the current operation is ...:DryRun\") and transport\n * metadata (`trace`).\n */\nexport function toChainDto(message: Record<string, unknown>): Record<string, unknown> {\n const chainDto: Record<string, unknown> = { ...message };\n for (const field of ['signature', 'prefix', 'types', 'domain', 'dtoOperation', 'trace']) {\n delete chainDto[field];\n }\n return chainDto;\n}\n\n/**\n * Signs the DryRun WRAPPER the gateway accepts for every contract:\n * `{ callerPublicKey, method, dto: <inner DTO object>, uniqueKey, signature }`. The inner DTO\n * travels unsigned and as an object; no `signerPublicKey` is sent because the signature already\n * recovers it (the gateway rejects it as REDUNDANT_SIGNER_PUBLIC_KEY). The wrapper carries its own\n * `uniqueKey`, distinct from the DTO's, and its own `dtoOperation` (`<Contract>:DryRun`); the inner DTO\n * carries none of the signing envelope or the `dtoOperation` of the call it simulates (see\n * {@link toChainDto}), whatever the caller passes, so a signed DTO can be handed in as is.\n */\nexport function buildDryRunWrapper(\n signer: GalaChainSigner,\n callerPublicKey: string,\n method: string,\n dto: Record<string, unknown>,\n uniqueKeyPrefix: string = DRY_RUN_UNIQUE_KEY_PREFIX,\n contractPath: ChainContractPath = 'asset/dexv3-contract',\n): Promise<Record<string, unknown>> {\n return signPreSend(signer, contractPath, DRY_RUN_METHOD, {\n callerPublicKey,\n method,\n dto: toChainDto(dto),\n // Core's RN-safe mint (`getRandomValues`, never `randomUUID`, which Hermes lacks).\n uniqueKey: createUniqueKey(uniqueKeyPrefix),\n });\n}\n\n/** The transport and backend a fee quote reads from. */\nexport interface DexFeesClient {\n /**\n * Swap backend origin, e.g. `https://dex-backend-prod1.defi.gala.com`. A base that already ends in\n * `/api/v1` (what the wallet passes) and trailing slashes are accepted: the request goes to the\n * same URL either way (see {@link dexBackendRoot}).\n */\n dexBackendBaseUrl: string;\n /** Defaults to the global `fetch`. */\n httpRequestor?: HttpRequestor | undefined;\n /** Per-request timeout in milliseconds (default 30 000). */\n requestTimeoutMs?: number | undefined;\n /**\n * Request headers of the fee POST (`userAgent`, `headers`); see {@link WireOptions}. The SDK's\n * `Accept: application/json` is a default that `wire.headers` may replace.\n */\n wire?: WireOptions | undefined;\n}\n\n/** Options for a single quote. */\nexport interface DexFeeQuoteOptions {\n /** GalaChain channel. Default `asset`. */\n channel?: string | undefined;\n /**\n * Contract the DTO targets. Default `dexv3-contract` (what every legacy caller quotes against);\n * a current-contract operation must pass `dex-contract` explicitly.\n */\n contract?: DexFeeContract | undefined;\n}\n\n/**\n * Network-fee quote for GalaChain DEX methods, derived from a server-side DryRun.\n *\n * The client only SIGNS the DryRun wrapper (with whatever {@link GalaChainSigner} it is given) and\n * the backend forwards it to the gateway, where the simulated writes carry the fee; the backend\n * never holds a key. Intended for wallets: the DTO quoted is the typed message a dApp handed over.\n *\n * @example\n * ```ts\n * const fees = new DexFees({ dexBackendBaseUrl }, new PrivateKeySigner(sessionKey));\n * const quote = await fees.quote(publicKey, 'RequestTrade', toChainDto(message), {\n * contract: 'dex-contract',\n * });\n * const feeInGala = quote?.fees[0]?.feeInGala;\n * ```\n */\nexport class DexFees {\n private readonly requestor: HttpRequestor;\n private readonly baseUrl: string;\n private readonly requestTimeoutMs: number;\n private readonly wire: WireOptions | undefined;\n\n constructor(\n client: DexFeesClient,\n private readonly signer: GalaChainSigner | undefined,\n ) {\n this.requestor = client.httpRequestor ?? fetchRequestor;\n this.baseUrl = dexBackendRoot(client.dexBackendBaseUrl);\n this.requestTimeoutMs = client.requestTimeoutMs ?? 30_000;\n this.wire = client.wire;\n }\n\n /**\n * Quotes the network fee for `method` applied to `message`. The message is reduced with\n * {@link toChainDto} first, so an EIP-712 approval message can be passed as is.\n *\n * Resolves `null` when the BACKEND could not be reached or answered unusably (offline, 4xx/5xx,\n * malformed body): a transport outcome, not a fee. Deciding what to charge when the chain is\n * silent is the backend's job (it serves `source: 'default'`), so the client never substitutes\n * a fee of its own, with ONE exception that mirrors the wallet: a `dex-contract` quote answered\n * 403 means the contract has no fee route yet and resolves `{ source: 'default', '0' }`. A 404 is\n * a wrong path, not \"no fee route\": it resolves `null`, never a default. The request always goes\n * to `<root>/api/v1/wallet/connect/galachain/api/{channel}/{contract}/{method}/fee`, whether the\n * client's base URL is the host root or already ends in `/api/v1`.\n * Never throws on transport, so a fee lookup cannot block or break a signing screen.\n *\n * @throws GSwapSDKError NO_SIGNER when constructed without a signer; `SIGNING_FAILED` or\n * `KEY_PROVIDER_FAILED` (a pre-send error, the original as `cause`) when the signer fails, for\n * example a locked wallet.\n */\n public async quote(\n callerPublicKey: string,\n method: DexFeeMethod,\n message: Record<string, unknown>,\n options: DexFeeQuoteOptions = {},\n ): Promise<DexFeeQuote | null> {\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n const channel = options.channel ?? 'asset';\n const contract = options.contract ?? 'dexv3-contract';\n const wrapper = await buildDryRunWrapper(\n this.signer,\n callerPublicKey,\n method,\n toChainDto(message),\n undefined,\n `asset/${contract}`,\n );\n const url = `${this.baseUrl}${FEE_ROUTE_PREFIX}/${encodeURIComponent(channel)}/${encodeURIComponent(contract)}/${encodeURIComponent(method)}/fee`;\n\n let status: number;\n let ok: boolean;\n let body: unknown;\n try {\n const response = await requestWithTimeout(\n this.requestor,\n url,\n {\n method: 'POST',\n headers: buildRequestHeaders(this.wire, {\n json: true,\n defaults: { Accept: 'application/json' },\n }),\n body: JSON.stringify(wrapper),\n },\n this.requestTimeoutMs,\n );\n status = response.status;\n ok = response.ok;\n body = ok ? await readResponseBody(response) : undefined;\n } catch {\n return null;\n }\n\n if (!ok) {\n // 403: the contract has no fee route yet (the route exists, the backend refuses the path). A 404 is\n // NOT that: it is a wrong path (stage, 2026-11-02: the host root answered 404 and every quote became a\n // silent 0), so it resolves null like any other backend failure.\n if (contract === 'dex-contract' && status === 403) {\n return { source: 'default', fees: [{ feeInGala: '0' }] };\n }\n return null;\n }\n // Accept whatever fee the backend served: 'default' is as usable as 'dry-run'. Only a body\n // missing the fee outright is unusable.\n return readQuote(body);\n }\n}\n\nfunction readQuote(body: unknown): DexFeeQuote | null {\n if (typeof body !== 'object' || body === null) return null;\n const fees = (body as { fees?: unknown }).fees;\n if (\n !Array.isArray(fees) ||\n typeof (fees[0] as { feeInGala?: unknown } | undefined)?.feeInGala !== 'string'\n ) {\n return null;\n }\n return body as DexFeeQuote;\n}\n"],"mappings":"A,oTAeA,MAAaC,EAAkB,CAC7B,OACA,eACA,eACA,kBACA,sBACA,YACF,EAQaC,EAAiB,SAGjBC,EAA4B,yBAGzC,SAAgBC,EAAe,EAAyC,CACtE,OAAO,OAAOC,GAAW,UAAaJ,EAAsC,SAASI,CAAM,CAC7F,CAGA,SAAgBC,EACd,EACA,EACS,CACT,OACEF,EAAeC,CAAM,GACrB,OAAOE,GAAUC,QAAc,UAC/B,OAAOD,EAAQE,QAAc,QAEjC,CA2BA,SAAgBC,EAAe,EAAsB,CACnD,OAAOC,EAAK,QAAQ,+BAAgC,EAAE,CACxD,CASA,SAAgBC,EAAW,EAA2D,CACpF,IAAMC,EAAoC,CAAE,GAAGN,CAAQ,EACvD,IAAK,IAAMO,IAAS,CAAC,YAAa,SAAU,QAAS,SAAU,eAAgB,OAAO,EACpF,OAAOD,EAASC,GAElB,OAAOD,CACT,CAWA,SAAgBE,EACd,EACA,EACA,EACA,EACA,EAA0BZ,EAC1B,EAAkC,uBACA,CAClC,OAAOa,EAAYC,EAAQC,EAAchB,EAAgB,CACvD,kBACA,SACA,IAAKU,EAAWO,CAAG,EAEnB,UAAWC,EAAgBC,CAAe,CAC5C,CAAC,CACH,CAgDA,IAAaC,EAAb,KAAqB,CAMnB,YACE,EACA,EACA,CADiB,KAAA,OAAAL,EAPFjB,EAAA,KAAA,YAAA,IAAA,EAAA,EACAA,EAAA,KAAA,UAAA,IAAA,EAAA,EACAA,EAAA,KAAA,mBAAA,IAAA,EAAA,EACAA,EAAA,KAAA,OAAA,IAAA,EAAA,EAMf,KAAK,UAAYuB,EAAO,eAAiBC,EACzC,KAAK,QAAUd,EAAea,EAAO,iBAAiB,EACtD,KAAK,iBAAmBA,EAAO,kBAAoB,IACnD,KAAK,KAAOA,EAAO,IACrB,CAoBA,MAAa,MACX,EACA,EACA,EACA,EAA8B,CAAC,EACF,CAC7B,GAAI,KAAK,SAAW,IAAA,GAAW,MAAME,EAAc,cAAc,EACjE,IAAMC,EAAUC,EAAQ,SAAW,QAC7BC,EAAWD,EAAQ,UAAY,iBAC/BE,EAAU,MAAMd,EACpB,KAAK,OACLe,EACAzB,EACAO,EAAWL,CAAO,EAClB,IAAA,GACA,SAASqB,GACX,EACMG,EAAM,GAAG,KAAK,+CAA8B,mBAAmBL,CAAO,EAAE,GAAG,mBAAmBE,CAAQ,EAAE,GAAG,mBAAmBvB,CAAM,EAAE,MAExI2B,EACAC,EACAC,EACJ,GAAI,CACF,IAAMC,EAAW,MAAMC,EACrB,KAAK,UACLL,EACA,CACE,OAAQ,OACR,QAASM,EAAoB,KAAK,KAAM,CACtC,KAAM,GACN,SAAU,CAAE,OAAQ,kBAAmB,CACzC,CAAC,EACD,KAAM,KAAK,UAAUR,CAAO,CAC9B,EACA,KAAK,gBACP,EACA,EAASM,EAAS,OAClB,EAAKA,EAAS,GACd,EAAOF,EAAK,MAAMK,EAAiBH,CAAQ,EAAI,IAAA,EACjD,MAAQ,CACN,OAAO,IACT,CAaA,OAXKF,EAWEM,EAAUL,CAAI,EAPfN,IAAa,gBAAkBI,IAAW,IACrC,CAAE,OAAQ,UAAW,KAAM,CAAC,CAAE,UAAW,GAAI,CAAC,CAAE,EAElD,IAKX,CACF,EAEA,SAASO,EAAU,EAAmC,CACpD,GAAI,OAAOL,GAAS,WAAYA,EAAe,OAAO,KACtD,IAAMM,EAAQN,EAA4B,KAO1C,MALE,CAAC,MAAM,QAAQM,CAAI,GACnB,OAAQA,EAAK,EAAE,EAA0C,WAAc,SAEhE,KAEFN,CACT,C"}
|
package/dist/browser/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{GSWAP_ERROR_CATALOG as e,SUBMISSION_OUTCOME_UNKNOWN_REASONS as t,gswapErrorTemplates as n}from"./classes/gswap_error_catalog.js";import{GSWAP_ERROR_PHASE_BY_CODE as r}from"./classes/gswap_error_phase_table.js";import{GSwapSDKError as i,UPDATE_REQUIRED_STATUS as a,getObjectProperty as o,getStringProperty as s,isGSwapError as c,isPreSendError as l}from"./classes/gswap_sdk_error.js";import{AppliedTradeError as u,confirmAppliedTrade as d}from"./classes/apply_results.js";import{ALL_FEE_TIERS as f,FEE_TIER as p,TICK_SPACING_BY_FEE as m}from"./types/fees.js";import{isTickInRange as h}from"./utils/tick_range.js";import{GC_MAX_TICK as g,GC_MIN_TICK as _,isSqrtPriceInRange as v,sqrtPriceToTick as y,tickFromPrice as b,tickToPrice as x,tickToSqrtPrice as S}from"./utils/tick_math.js";import{assertCanonicalPair as C,isProposableTradingSymbol as w,requireUserRef as T,userRef as E,validateFee as D,validateNumericAmount as O,validatePriceValues as k,validateTickRange as A,validateTickSpacing as j,validateTokenDecimals as M}from"./utils/validation.js";import{Assets as N}from"./classes/assets.js";import{DEX_FEE_METHODS as P,DRY_RUN_METHOD as F,DRY_RUN_UNIQUE_KEY_PREFIX as I,DexFees as L,buildDryRunWrapper as R,
|
|
1
|
+
import{GSWAP_ERROR_CATALOG as e,SUBMISSION_OUTCOME_UNKNOWN_REASONS as t,gswapErrorTemplates as n}from"./classes/gswap_error_catalog.js";import{GSWAP_ERROR_PHASE_BY_CODE as r}from"./classes/gswap_error_phase_table.js";import{GSwapSDKError as i,UPDATE_REQUIRED_STATUS as a,getObjectProperty as o,getStringProperty as s,isGSwapError as c,isPreSendError as l}from"./classes/gswap_sdk_error.js";import{AppliedTradeError as u,confirmAppliedTrade as d}from"./classes/apply_results.js";import{ALL_FEE_TIERS as f,FEE_TIER as p,TICK_SPACING_BY_FEE as m}from"./types/fees.js";import{isTickInRange as h}from"./utils/tick_range.js";import{GC_MAX_TICK as g,GC_MIN_TICK as _,isSqrtPriceInRange as v,sqrtPriceToTick as y,tickFromPrice as b,tickToPrice as x,tickToSqrtPrice as S}from"./utils/tick_math.js";import{assertCanonicalPair as C,isProposableTradingSymbol as w,requireUserRef as T,userRef as E,validateFee as D,validateNumericAmount as O,validatePriceValues as k,validateTickRange as A,validateTickSpacing as j,validateTokenDecimals as M}from"./utils/validation.js";import{Assets as N}from"./classes/assets.js";import{DEX_FEE_METHODS as P,DRY_RUN_METHOD as F,DRY_RUN_UNIQUE_KEY_PREFIX as I,DexFees as L,buildDryRunWrapper as R,dexBackendRoot as z,isCurrentContractDexMessage as B,isDexFeeMethod as V,toChainDto as H}from"./classes/dex_fees.js";import{isShadowError as U}from"./utils/shadow_errors.js";import{SubmittedTransaction as W}from"./classes/submitted_transaction.js";import{ChainGateway as G}from"./classes/gateway.js";import{GSWAP_ENVIRONMENTS as K}from"./types/env.js";import{GdexStreamError as q,GdexStreamService as J,isGdexLiquidityEvent as Y}from"./classes/gdex_stream.js";import{Leaderboard as X}from"./classes/leaderboard.js";import{MARKET_PRICE_BATCH_LIMIT as Z,PRICE_SERIES_TIMEFRAMES as Q}from"./types/market.js";import{MARKET_PRICE_QUERY_BYTES as $,Market as ee,priceBatches as te}from"./classes/market.js";import{ONRAMPER_MODES as ne,Onramper as re,createOnramper as ie}from"./classes/onramper.js";import{orderSymbols as ae,parseTokenClassKey as oe,readOrderedSymbols as se}from"./utils/ordering.js";import{CanonicalSymbols as ce,Symbols as le,queryTokenOf as ue,rawTokenOf as de,tradingSymbolOf as fe}from"./classes/symbols.js";import{Pools as pe}from"./classes/pools.js";import{alignTickDownOrNaN as me,alignTickUpOrNaN as he}from"./utils/tick_align.js";import{alignTickDown as ge,alignTickUp as _e,assertTickRange as ve,frameSlot0 as ye}from"./utils/ticks.js";import{assertCanonicalV2Dto as be,buildAddLiquidityDto as xe,buildCollectPositionFeesDto as Se,buildCreatePoolDto as Ce,buildRemoveLiquidityDto as we,buildRequestTradeDto as Te}from"./utils/dto_builders.js";import{Positions as Ee}from"./classes/positions.js";import{Quoting as De}from"./classes/quoting.js";import{SHADOW_FAILURE_KINDS as Oe,SHADOW_SUBMIT_CODES as ke,classifyShadowSubmitError as Ae,classifyShadowSubmitStatus as je,readShadowSubmitOutcome as Me}from"./classes/shadow_submit.js";import{Swaps as Ne,swapRouteFromQuote as Pe}from"./classes/swaps.js";import{GSwap as Fe}from"./classes/gswap.js";import{NOT_QUEUED_FINAL as Ie,classification as Le,notSentClassification as Re}from"./utils/classification.js";import{classifyFailure as ze,mayHaveBeenQueued as Be}from"./utils/failure_classification.js";import{PENDING_SWAP_FATES as Ve,pendingSwapFateFor as He,pendingSwapFateOfOutcome as Ue}from"./classes/pending_swap_fate.js";import{PENDING_SWAPS_STORAGE_KEY as We,PENDING_SWAP_EXPIRY_MS as Ge,PENDING_SWAP_PRUNE_REASONS as Ke,PendingSwapStore as qe}from"./classes/pending_swaps.js";import{storageAdapterFromChromeStorage as Je,webStorageAdapter as Ye}from"./classes/storage_adapters.js";import{confirmationStateOf as Xe,isConfirmationAborted as Ze,isConfirmationTimeout as Qe}from"./utils/confirmation_state.js";import{chainErrorKeyOf as $e,isNoMarket as et,isRelayableRefusal as tt,isUninterpretedAnswer as nt,isUniqueKeyConsumed as rt,isUnprovenAcknowledgement as it}from"./utils/failure_guards.js";import{classifySubmitEnvelope as at,isSubmitExecuted as ot,isSubmitQueued as st,isSubmitRejected as ct}from"./utils/submit_state.js";export{f as ALL_FEE_TIERS,u as AppliedTradeError,N as Assets,ce as CanonicalSymbols,G as ChainGateway,P as DEX_FEE_METHODS,F as DRY_RUN_METHOD,I as DRY_RUN_UNIQUE_KEY_PREFIX,L as DexFees,p as FEE_TIER,g as GC_MAX_TICK,_ as GC_MIN_TICK,K as GSWAP_ENVIRONMENTS,e as GSWAP_ERROR_CATALOG,r as GSWAP_ERROR_PHASE_BY_CODE,Fe as GSwap,i as GSwapSDKError,q as GdexStreamError,J as GdexStreamService,X as Leaderboard,Z as MARKET_PRICE_BATCH_LIMIT,$ as MARKET_PRICE_QUERY_BYTES,ee as Market,Ie as NOT_QUEUED_FINAL,ne as ONRAMPER_MODES,re as Onramper,We as PENDING_SWAPS_STORAGE_KEY,Ge as PENDING_SWAP_EXPIRY_MS,Ve as PENDING_SWAP_FATES,Ke as PENDING_SWAP_PRUNE_REASONS,Q as PRICE_SERIES_TIMEFRAMES,qe as PendingSwapStore,pe as Pools,Ee as Positions,De as Quoting,Oe as SHADOW_FAILURE_KINDS,ke as SHADOW_SUBMIT_CODES,t as SUBMISSION_OUTCOME_UNKNOWN_REASONS,W as SubmittedTransaction,Ne as Swaps,le as Symbols,m as TICK_SPACING_BY_FEE,a as UPDATE_REQUIRED_STATUS,ge as alignTickDown,me as alignTickDownOrNaN,_e as alignTickUp,he as alignTickUpOrNaN,C as assertCanonicalPair,be as assertCanonicalV2Dto,ve as assertTickRange,xe as buildAddLiquidityDto,Se as buildCollectPositionFeesDto,Ce as buildCreatePoolDto,R as buildDryRunWrapper,we as buildRemoveLiquidityDto,Te as buildRequestTradeDto,$e as chainErrorKeyOf,Le as classification,ze as classifyFailure,Ae as classifyShadowSubmitError,je as classifyShadowSubmitStatus,at as classifySubmitEnvelope,d as confirmAppliedTrade,Xe as confirmationStateOf,ie as createOnramper,z as dexBackendRoot,ye as frameSlot0,o as getObjectProperty,s as getStringProperty,n as gswapErrorTemplates,Ze as isConfirmationAborted,Qe as isConfirmationTimeout,B as isCurrentContractDexMessage,V as isDexFeeMethod,c as isGSwapError,Y as isGdexLiquidityEvent,et as isNoMarket,l as isPreSendError,w as isProposableTradingSymbol,tt as isRelayableRefusal,U as isShadowError,v as isSqrtPriceInRange,ot as isSubmitExecuted,st as isSubmitQueued,ct as isSubmitRejected,h as isTickInRange,nt as isUninterpretedAnswer,rt as isUniqueKeyConsumed,it as isUnprovenAcknowledgement,Be as mayHaveBeenQueued,Re as notSentClassification,ae as orderSymbols,oe as parseTokenClassKey,He as pendingSwapFateFor,Ue as pendingSwapFateOfOutcome,te as priceBatches,ue as queryTokenOf,de as rawTokenOf,se as readOrderedSymbols,Me as readShadowSubmitOutcome,T as requireUserRef,y as sqrtPriceToTick,Je as storageAdapterFromChromeStorage,Pe as swapRouteFromQuote,b as tickFromPrice,x as tickToPrice,S as tickToSqrtPrice,H as toChainDto,fe as tradingSymbolOf,E as userRef,D as validateFee,O as validateNumericAmount,k as validatePriceValues,A as validateTickRange,j as validateTickSpacing,M as validateTokenDecimals,Ye as webStorageAdapter};
|
package/dist/index.cjs
CHANGED
|
@@ -1730,6 +1730,20 @@ function isDexFeeMethod(method) {
|
|
|
1730
1730
|
function isCurrentContractDexMessage(message, method) {
|
|
1731
1731
|
return isDexFeeMethod(method) && typeof (message === null || message === void 0 ? void 0 : message["token0"]) === "string" && typeof message["token1"] === "string";
|
|
1732
1732
|
}
|
|
1733
|
+
/** The wallet-connect proxy's fee route, below the backend root (stage, 2026-11-02: only this prefix exists). */
|
|
1734
|
+
const FEE_ROUTE_PREFIX = "/api/v1/wallet/connect/galachain/api";
|
|
1735
|
+
/**
|
|
1736
|
+
* The backend root a fee quote is built on: `base` without trailing slashes and without a trailing
|
|
1737
|
+
* `/api/v1` (the wallet passes the versioned base, the SDK presets the host root). Idempotent.
|
|
1738
|
+
*
|
|
1739
|
+
* @example
|
|
1740
|
+
* ```typescript
|
|
1741
|
+
* dexBackendRoot('https://swap-backend.stage.defi.ovh.gala.com/api/v1/'); // 'https://swap-backend.stage.defi.ovh.gala.com'
|
|
1742
|
+
* ```
|
|
1743
|
+
*/
|
|
1744
|
+
function dexBackendRoot(base) {
|
|
1745
|
+
return base.replace(/(?:\/+|\/api\/v1(?=\/|$))+$/u, "");
|
|
1746
|
+
}
|
|
1733
1747
|
/**
|
|
1734
1748
|
* Reduces an EIP-712 approval `message` to the DTO the chain actually receives: drops the signing
|
|
1735
1749
|
* envelope (`signature`, `prefix`, `types`, `domain`), the `dtoOperation` it was signed to call (a
|
|
@@ -1791,7 +1805,7 @@ var DexFees = class {
|
|
|
1791
1805
|
constructor(client, signer) {
|
|
1792
1806
|
this.signer = signer;
|
|
1793
1807
|
this.requestor = client.httpRequestor ?? _gala_chain_gala_core_sdk.fetchRequestor;
|
|
1794
|
-
this.baseUrl = client.dexBackendBaseUrl
|
|
1808
|
+
this.baseUrl = dexBackendRoot(client.dexBackendBaseUrl);
|
|
1795
1809
|
this.requestTimeoutMs = client.requestTimeoutMs ?? 3e4;
|
|
1796
1810
|
this.wire = client.wire;
|
|
1797
1811
|
}
|
|
@@ -1803,7 +1817,10 @@ var DexFees = class {
|
|
|
1803
1817
|
* malformed body): a transport outcome, not a fee. Deciding what to charge when the chain is
|
|
1804
1818
|
* silent is the backend's job (it serves `source: 'default'`), so the client never substitutes
|
|
1805
1819
|
* a fee of its own, with ONE exception that mirrors the wallet: a `dex-contract` quote answered
|
|
1806
|
-
* 403
|
|
1820
|
+
* 403 means the contract has no fee route yet and resolves `{ source: 'default', '0' }`. A 404 is
|
|
1821
|
+
* a wrong path, not "no fee route": it resolves `null`, never a default. The request always goes
|
|
1822
|
+
* to `<root>/api/v1/wallet/connect/galachain/api/{channel}/{contract}/{method}/fee`, whether the
|
|
1823
|
+
* client's base URL is the host root or already ends in `/api/v1`.
|
|
1807
1824
|
* Never throws on transport, so a fee lookup cannot block or break a signing screen.
|
|
1808
1825
|
*
|
|
1809
1826
|
* @throws GSwapSDKError NO_SIGNER when constructed without a signer; `SIGNING_FAILED` or
|
|
@@ -1815,7 +1832,7 @@ var DexFees = class {
|
|
|
1815
1832
|
const channel = options.channel ?? "asset";
|
|
1816
1833
|
const contract = options.contract ?? "dexv3-contract";
|
|
1817
1834
|
const wrapper = await buildDryRunWrapper(this.signer, callerPublicKey, method, toChainDto(message), void 0, `asset/${contract}`);
|
|
1818
|
-
const url = `${this.baseUrl}
|
|
1835
|
+
const url = `${this.baseUrl}${FEE_ROUTE_PREFIX}/${encodeURIComponent(channel)}/${encodeURIComponent(contract)}/${encodeURIComponent(method)}/fee`;
|
|
1819
1836
|
let status;
|
|
1820
1837
|
let ok;
|
|
1821
1838
|
let body;
|
|
@@ -1835,7 +1852,7 @@ var DexFees = class {
|
|
|
1835
1852
|
return null;
|
|
1836
1853
|
}
|
|
1837
1854
|
if (!ok) {
|
|
1838
|
-
if (contract === "dex-contract" &&
|
|
1855
|
+
if (contract === "dex-contract" && status === 403) return {
|
|
1839
1856
|
source: "default",
|
|
1840
1857
|
fees: [{ feeInGala: "0" }]
|
|
1841
1858
|
};
|
|
@@ -6769,6 +6786,7 @@ exports.classifySubmitEnvelope = classifySubmitEnvelope;
|
|
|
6769
6786
|
exports.confirmAppliedTrade = confirmAppliedTrade;
|
|
6770
6787
|
exports.confirmationStateOf = confirmationStateOf;
|
|
6771
6788
|
exports.createOnramper = createOnramper;
|
|
6789
|
+
exports.dexBackendRoot = dexBackendRoot;
|
|
6772
6790
|
exports.frameSlot0 = frameSlot0;
|
|
6773
6791
|
exports.getObjectProperty = getObjectProperty;
|
|
6774
6792
|
exports.getStringProperty = getStringProperty;
|