@gala-chain/gswap-sdk 2.0.0-rc.0 → 2.0.0-rc.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onramper.js","names":["ONRAMPER_MODES","TEXT_FIELDS","AMOUNT_FIELDS","invalidField","GSwapSDKError","widgetBody","request","body","\"mode\"","field","value","widgetUrlOf","url","asEntryRecord","response","\"data\"","\"url\"","Onramper","dexBackendBaseUrl","httpClient","createOnramper","options","HttpClient"],"sources":["../../../src/classes/onramper.ts"],"sourcesContent":["import type { HttpRequestor, WireOptions } from '@gala-chain/gala-core-sdk';\nimport { asEntryRecord } from '../utils/lenient.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport { HttpClient } from './http_client.js';\n\n/** What the Onramper widget does. */\nexport const ONRAMPER_MODES = ['buy', 'sell', 'swap'] as const;\n\n/** One of {@link ONRAMPER_MODES}. */\nexport type OnramperMode = (typeof ONRAMPER_MODES)[number];\n\n/**\n * The request of {@link Onramper.generateWidgetUrl}: the fields of the swap backend's\n * `GenerateWidgetUrlDto`, no others (the backend refuses a field it does not know). A field left\n * out is the backend's default (`mode` `buy`, `defaultFiat` `USD`, `defaultAmount` 100,\n * `sellDefaultAmount` 1, `onlyCryptoNetworks` `gala`, `defaultPaymentMethod` `creditcard`,\n * `networkPrefix` `gala_gala`).\n */\nexport interface OnramperWidgetRequest {\n /** The wallet that receives the crypto, sent as given (the backend wants an `0x` Ethereum address). */\n walletAddress: string;\n mode?: OnramperMode | undefined;\n defaultFiat?: string | undefined;\n /** The fiat amount the widget opens with (the backend accepts 15 to 15 000, at most 2 decimals). */\n defaultAmount?: number | undefined;\n /** The crypto amount a sell opens with (0.000001 to 1 000 000, at most 18 decimals). */\n sellDefaultAmount?: number | undefined;\n onlyCryptoNetworks?: string | undefined;\n defaultPaymentMethod?: string | undefined;\n defaultCrypto?: string | undefined;\n onlyPaymentMethods?: string | undefined;\n excludePaymentMethods?: string | undefined;\n onlyFiat?: string | undefined;\n excludeFiat?: string | undefined;\n isAddressEditable?: string | undefined;\n networkPrefix?: string | undefined;\n}\n\n/** The request fields that are text, besides `walletAddress` and `mode`. */\nconst TEXT_FIELDS = [\n 'defaultFiat',\n 'onlyCryptoNetworks',\n 'defaultPaymentMethod',\n 'defaultCrypto',\n 'onlyPaymentMethods',\n 'excludePaymentMethods',\n 'onlyFiat',\n 'excludeFiat',\n 'isAddressEditable',\n 'networkPrefix',\n] as const;\n\n/** The request fields that are amounts. */\nconst AMOUNT_FIELDS = ['defaultAmount', 'sellDefaultAmount'] as const;\n\nconst METHOD = 'onramper.generateWidgetUrl';\n\nfunction invalidField(field: string, expected: string): GSwapSDKError {\n return new GSwapSDKError('INVALID_DTO', { method: METHOD, field, expected });\n}\n\n/**\n * The body to send: the fields the caller gave, checked. A field left out (or `undefined`) is not\n * sent, so the backend's default applies. An amount that is not a finite number is refused here:\n * `JSON.stringify` would turn `NaN` into `null`, which the backend reads as \"not given\" and\n * silently replaces with its default amount.\n */\nfunction widgetBody(request: OnramperWidgetRequest): Record<string, string | number> {\n if (typeof request !== 'object' || request === null) {\n throw invalidField('request', 'an object');\n }\n if (typeof request.walletAddress !== 'string' || request.walletAddress.trim() === '') {\n throw invalidField('walletAddress', 'a non-empty string');\n }\n const body: Record<string, string | number> = { walletAddress: request.walletAddress };\n if (request.mode !== undefined) {\n if (!(ONRAMPER_MODES as readonly unknown[]).includes(request.mode)) {\n throw invalidField('mode', ONRAMPER_MODES.join(', '));\n }\n body['mode'] = request.mode;\n }\n for (const field of TEXT_FIELDS) {\n const value: unknown = request[field];\n if (value === undefined) continue;\n if (typeof value !== 'string') throw invalidField(field, 'a string');\n body[field] = value;\n }\n for (const field of AMOUNT_FIELDS) {\n const value: unknown = request[field];\n if (value === undefined) continue;\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {\n throw invalidField(field, 'a finite number, 0 or more');\n }\n body[field] = value;\n }\n return body;\n}\n\n/** The widget URL of the backend's `{ status, error, message, data: { url } }` answer. */\nfunction widgetUrlOf(response: unknown): string {\n const data = asEntryRecord(asEntryRecord(response)?.['data']);\n const url = data?.['url'];\n if (typeof url === 'string' && url !== '') {\n try {\n // Only to know it is an absolute URL; the backend's text is returned as it is.\n void new URL(url);\n return url;\n } catch {\n // Falls through to the invalid-answer error below.\n }\n }\n throw new GSwapSDKError(\n 'INVALID_CHAIN_RESPONSE',\n { resource: 'onramper widget url' },\n { body: response, write: false },\n );\n}\n\n/**\n * The swap backend's Onramper (fiat on-ramp) widget URL. The route is PUBLIC: the request carries\n * no `Authorization` header and no signature, whatever session the app has, so no token can leak to\n * it. The backend signs the wallet into the URL; the app adds its own look (theme query parameters)\n * to the returned URL.\n */\nexport class Onramper {\n /**\n * Creates the service. To get one without building a whole {@link GSwap} client, use\n * {@link createOnramper}.\n *\n * @example\n * ```ts\n * const onramper = new Onramper('https://dex-backend-prod1.defi.gala.com', httpClient);\n * ```\n */\n constructor(\n private readonly dexBackendBaseUrl: string,\n private readonly httpClient: HttpClient,\n ) {}\n\n /**\n * Asks the backend for a signed Onramper widget URL for `request.walletAddress`.\n *\n * @returns The widget URL.\n * @throws GSwapSDKError `INVALID_DTO` (before anything is sent: no wallet address, an unknown\n * `mode`, a text field that is not text, an amount that is not a finite number of 0 or more),\n * `HTTP_ERROR` (the backend refused: `serverMessage` is its message, e.g. \"Failed to generate\n * widget URL. Check server configuration.\" for a 500, its validation message for a 400, the\n * throttle for a 429), `REQUEST_FAILED` (no answer), `INVALID_CHAIN_RESPONSE` (an answer without\n * a usable `data.url`).\n *\n * @example\n * ```ts\n * const url = await gSwap.onramper.generateWidgetUrl({\n * walletAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',\n * defaultCrypto: 'gala',\n * onlyCryptoNetworks: 'gala',\n * mode: 'buy',\n * });\n * window.open(url);\n * ```\n */\n public async generateWidgetUrl(request: OnramperWidgetRequest): Promise<string> {\n const body = widgetBody(request);\n const response = await this.httpClient.sendPostRequest<unknown>(\n this.dexBackendBaseUrl,\n '/api/v1/onramper',\n '/generate-widget-url',\n body,\n );\n return widgetUrlOf(response);\n }\n}\n\n/** Options of {@link createOnramper}. */\nexport interface OnramperOptions {\n /** The swap backend's base URL (no trailing slash needed). */\n dexBackendBaseUrl: string;\n /** Your own HTTP requestor instead of `fetch`. */\n httpRequestor?: HttpRequestor | undefined;\n /** Request timeout in milliseconds (default 30 000). */\n timeoutMs?: number | undefined;\n /** Query encoding and `User-Agent` of the requests. */\n wire?: WireOptions | undefined;\n}\n\n/**\n * An {@link Onramper} for a swap backend, without building a {@link GSwap} client (no signer, no\n * wallet, no pool or stream services): the call for an app that only needs the widget URL.\n *\n * @example\n * ```ts\n * import { createOnramper } from '@gala-chain/gswap-sdk';\n *\n * const onramper = createOnramper({ dexBackendBaseUrl: 'https://dex-backend-prod1.defi.gala.com' });\n * const url = await onramper.generateWidgetUrl({ walletAddress, mode: 'buy' });\n * ```\n */\nexport function createOnramper(options: OnramperOptions): Onramper {\n return new Onramper(\n options.dexBackendBaseUrl.replace(/\\/$/u, ''),\n new HttpClient(options.httpRequestor, options.timeoutMs, options.wire),\n );\n}\n"],"mappings":"uJAMA,MAAaA,EAAiB,CAAC,MAAO,OAAQ,MAAM,EAiC9CC,EAAc,CAClB,cACA,qBACA,uBACA,gBACA,qBACA,wBACA,WACA,cACA,oBACA,eACF,EAGMC,EAAgB,CAAC,gBAAiB,mBAAmB,EAI3D,SAASC,EAAa,EAAe,EAAiC,CACpE,OAAO,IAAIC,EAAc,cAAe,CAAE,OAAQ,6BAAQ,QAAO,UAAS,CAAC,CAC7E,CAQA,SAASC,EAAW,EAAiE,CACnF,GAAI,OAAOC,GAAY,WAAYA,EACjC,MAAMH,EAAa,UAAW,WAAW,EAE3C,GAAI,OAAOG,EAAQ,eAAkB,UAAYA,EAAQ,cAAc,KAAK,IAAM,GAChF,MAAMH,EAAa,gBAAiB,oBAAoB,EAE1D,IAAMI,EAAwC,CAAE,cAAeD,EAAQ,aAAc,EACrF,GAAIA,EAAQ,OAAS,IAAA,GAAW,CAC9B,GAAI,CAAEN,EAAsC,SAASM,EAAQ,IAAI,EAC/D,MAAMH,EAAa,OAAQH,EAAe,KAAK,IAAI,CAAC,EAEtD,EAAKQ,KAAUF,EAAQ,IACzB,CACA,IAAK,IAAMG,KAASR,EAAa,CAC/B,IAAMS,EAAiBJ,EAAQG,GAC/B,GAAIC,IAAU,IAAA,GACd,IAAI,OAAOA,GAAU,SAAU,MAAMP,EAAaM,EAAO,UAAU,EACnE,EAAKA,GAASC,CADqD,CAErE,CACA,IAAK,IAAMD,KAASP,EAAe,CACjC,IAAMQ,EAAiBJ,EAAQG,GAC/B,GAAIC,IAAU,IAAA,GACd,IAAI,OAAOA,GAAU,UAAY,CAAC,OAAO,SAASA,CAAK,GAAKA,EAAQ,EAClE,MAAMP,EAAaM,EAAO,4BAA4B,EAExD,EAAKA,GAASC,CAF0C,CAG1D,CACA,OAAOH,CACT,CAGA,SAASI,EAAY,EAA2B,CAE9C,IAAMC,EADOC,EAAcA,EAAcC,CAAQ,CAAC,EAAGC,IACtC,CAAC,EAAGC,IACnB,GAAI,OAAOJ,GAAQ,UAAYA,IAAQ,GACrC,GAAI,CAGF,OADA,IAAS,IAAIA,CAAG,EACTA,CACT,MAAQ,CAER,CAEF,MAAM,IAAIR,EACR,yBACA,CAAE,SAAU,qBAAsB,EAClC,CAAE,KAAMU,EAAU,MAAO,EAAM,CACjC,CACF,CAQA,IAAaG,EAAb,KAAsB,CAUpB,YACE,EACA,EACA,CAFiB,KAAA,kBAAAC,EACA,KAAA,WAAAC,CAChB,CAwBH,MAAa,kBAAkB,EAAiD,CAC9E,IAAMZ,EAAOF,EAAWC,CAAO,EAO/B,OAAOK,EAAY,MANI,KAAK,WAAW,gBACrC,KAAK,kBACL,mBACA,uBACAJ,CACF,CAC2B,CAC7B,CACF,EA0BA,SAAgBa,EAAe,EAAoC,CACjE,OAAO,IAAIH,EACTI,EAAQ,kBAAkB,QAAQ,OAAQ,EAAE,EAC5C,IAAIC,EAAWD,EAAQ,cAAeA,EAAQ,UAAWA,EAAQ,IAAI,CACvE,CACF"}
@@ -1,2 +1,2 @@
1
- import{ALLOWED_FEE_TIERS_TEXT as e}from"./gswap_error_catalog.js";import t from"../_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/defineProperty.js";import{GSwapSDKError as n,isGSwapError as r}from"./gswap_sdk_error.js";import{TICK_SPACING_BY_FEE as i}from"../types/fees.js";import{tickFromPrice as a}from"../utils/tick_math.js";import{isProposableTradingSymbol as o,validateFee as s,validateNumericAmount as c}from"../utils/validation.js";import{HttpClient as l}from"./http_client.js";import{asEntryRecord as u,entryOk as d,entryRejected as f,readEntries as p}from"../utils/lenient.js";import{parseTokenClassKey as m}from"../utils/ordering.js";import{resolvePreSend as h}from"../utils/resolve_pre_send.js";import{rawTokenOf as g}from"./symbols.js";import{alignTickDown as _,alignTickUp as v,assertTickRange as y}from"../utils/ticks.js";import{assertCanonicalV2Dto as b,buildAddLiquidityDto as x,buildCollectPositionFeesDto as S,buildCreatePoolDto as C,buildRemoveLiquidityDto as w}from"../utils/dto_builders.js";import{assertUniqueKey as T,compositeKeyOf as E,createUniqueKey as D,resolveUniqueKeyPrefix as O,signPreSend as k}from"@gala-chain/gala-core-sdk";import A from"bignumber.js";function j(e){return{token0:e.token0,token1:e.token1,fee:e.fee,tickLower:e.tickLower,tickUpper:e.tickUpper}}var M=class{constructor(e,n,r,i,a={}){this.gateway=e,this.symbols=n,this.signer=r,this.walletAddress=i,t(this,`http`,void 0),t(this,`uniqueKeyPrefix`,void 0),t(this,`onInvalidEntry`,void 0),this.http=new l(e.httpRequestor,e.requestTimeoutMs??3e4,e.wire),this.uniqueKeyPrefix=O(a.uniqueKeyPrefix),this.onInvalidEntry=a.onInvalidEntry}async getUserPositions(e){let t=await this.get(`/positions`,{user:e});return p(`positions`,t.data,I,this.onInvalidEntry)}async getPosition(e,t){let n=await this.getNullable(`/position`,await this.positionParams(e),t);return n===null?null:L(n.data)}async readPosition(e,t){try{let n=await this.getPosition(e,t);return n===null?{kind:`not_found`}:{kind:`found`,data:n}}catch(e){if(t?.aborted===!0)throw e;return{kind:`unknown`,error:r(e)?e:new n(`REQUEST_FAILED`,{operation:`position`},{cause:e,write:!1})}}}async positionParams(e){if(this.symbols.passthrough===!0)return{token0:g(e.token0),token1:g(e.token1),fee:`${e.fee}`,owner:e.owner,tickLower:`${e.tickLower}`,tickUpper:`${e.tickUpper}`};let t=await this.orderPair(e.token0,e.token1),n=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);return{token0:t.token0.symbol,token1:t.token1.symbol,fee:`${e.fee}`,owner:e.owner,tickLower:`${n.tickLower}`,tickUpper:`${n.tickUpper}`}}async estimateAddLiquidity(e){return c(e.amount,`amount`),(await this.get(`/add-liq-estimate`,{token0:g(e.token0),token1:g(e.token1),fee:`${e.fee}`,tickLower:`${e.tickLower}`,tickUpper:`${e.tickUpper}`,amount:new A(e.amount).toFixed(),amountIsToken0:String(e.amountIsToken0)})).data}async estimateRemoveLiquidity(e){return c(e.liquidity,`liquidity`),(await this.get(`/remove-liq-estimate`,{token0:g(e.token0),token1:g(e.token1),fee:`${e.fee}`,tickLower:`${e.tickLower}`,tickUpper:`${e.tickUpper}`,liquidity:new A(e.liquidity).toFixed()})).data}async addLiquidityByTicks(e){return this.submitAddLiquidity(await this.buildAddLiquidity(e))}async buildAddLiquidity(e){s(e.fee);let t=await this.orderPair(e.token0,e.token1),n=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);y(n.tickLower,n.tickUpper,e.fee),c(e.amount,`amount`);let r={token0:t.token0.symbol,token1:t.token1.symbol,fee:e.fee,tickLower:n.tickLower,tickUpper:n.tickUpper,uniqueKey:this.uniqueKeyFor(e.uniqueKey)};return t.flipped===e.amountIsToken0?x({...r,depositQuantityToken1:e.amount}):x({...r,depositQuantityToken0:e.amount})}async submitAddLiquidity(e){return b(`AddLiquidity`,e),this.submit(`AddLiquidity`,e,{kind:`add`,identity:j(e)})}async addLiquidityByPrice(e){s(e.fee),this.rejectNumber(e.minPrice,`minPrice`),this.rejectNumber(e.maxPrice,`maxPrice`);let t=new A(e.minPrice),r=new A(e.maxPrice);if(!t.isFinite()||!r.isFinite()||t.isLessThanOrEqualTo(0)||r.isLessThanOrEqualTo(0))throw new n(`INVALID_PRICE_BOUNDS`,{minPrice:String(e.minPrice),maxPrice:String(e.maxPrice)});if(t.isGreaterThan(r))throw new n(`PRICE_BOUNDS_ORDER`,{minPrice:String(e.minPrice),maxPrice:String(e.maxPrice)});let i=this.tickSpacing(e.fee),o=_(a(t),i),c=v(a(r),i);return this.addLiquidityByTicks({token0:e.token0,token1:e.token1,fee:e.fee,tickLower:o,tickUpper:c,amount:e.amount,amountIsToken0:e.amountIsToken0,uniqueKey:e.uniqueKey})}async removeLiquidity(e){return this.submitRemoveLiquidity(await this.buildRemoveLiquidity(e))}async buildRemoveLiquidity(e){s(e.fee);let t=await this.orderPair(e.token0,e.token1),r=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);if(y(r.tickLower,r.tickUpper,e.fee),e.amount0!==void 0&&e.amount1!==void 0)throw new n(`AT_MOST_ONE_OF_ALLOWED`,{first:`amount0`,second:`amount1`});e.amount0!==void 0&&c(e.amount0,`amount0`),e.amount1!==void 0&&c(e.amount1,`amount1`);let[i,a]=t.flipped?[e.amount1,e.amount0]:[e.amount0,e.amount1];return w({token0:t.token0.symbol,token1:t.token1.symbol,fee:e.fee,tickLower:r.tickLower,tickUpper:r.tickUpper,uniqueKey:this.uniqueKeyFor(e.uniqueKey),withdrawalQuantityToken0:i,withdrawalQuantityToken1:a})}async submitRemoveLiquidity(e){b(`RemoveLiquidity`,e);let t=e.withdrawalQuantityToken0===void 0&&e.withdrawalQuantityToken1===void 0;return this.submit(`RemoveLiquidity`,e,{kind:t?`removeFull`:`removePartial`,identity:j(e)})}async collectPositionFees(e){return this.submitCollectPositionFees(await this.buildCollectPositionFees(e))}async buildCollectPositionFees(e){s(e.fee);let t=await this.orderPair(e.token0,e.token1),n=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);return y(n.tickLower,n.tickUpper,e.fee),S({token0:t.token0.symbol,token1:t.token1.symbol,fee:e.fee,tickLower:n.tickLower,tickUpper:n.tickUpper,uniqueKey:this.uniqueKeyFor(e.uniqueKey)})}async submitCollectPositionFees(e){return b(`CollectPositionFees`,e),this.submit(`CollectPositionFees`,e,{kind:`collect`,identity:j(e)})}async createPool(e){return this.submitCreatePool(await this.buildCreatePool(e))}async buildCreatePool(e){let t=e.startingPrice!==void 0;if(t===(e.startingSqrtPrice!==void 0))throw new n(`EXACTLY_ONE_OF_REQUIRED`,{first:`startingPrice`,second:`startingSqrtPrice`});s(e.fee);let[r,i]=await Promise.all([this.resolveCreateToken(e.token0,e.token0Symbol),this.resolveCreateToken(e.token1,e.token1Symbol)]),a=r.symbol>i.symbol,[o,c]=a?[i,r]:[r,i],l=t?e.startingPrice:e.startingSqrtPrice;this.rejectNumber(l,t?`startingPrice`:`startingSqrtPrice`);let u=new A(l);if(!u.isFinite()||u.isLessThanOrEqualTo(0))throw new n(`INVALID_STARTING_PRICE`,{value:String(l)});let d=a?new A(1).dividedBy(u):u,f={token0Key:o.classKey,token1Key:c.classKey,token0Symbol:o.symbol,token1Symbol:c.symbol,fee:e.fee,uniqueKey:this.uniqueKeyFor(e.uniqueKey),name:e.name,isPrivate:e.isPrivate,privateAccess:e.privateAccess};return C(t?{...f,startingPrice:d}:{...f,startingSqrtPrice:d})}async submitCreatePool(e){b(`CreatePool`,e);let t=await this.submit(`CreatePool`,e,{kind:`createPool`,token0:e.token0Symbol,token1:e.token1Symbol,fee:e.fee});return this.symbols.invalidate?.(),t}async submit(e,t,r){if(this.signer===void 0)throw n.noSignerError();let i=await k(this.signer,e,t),a=this.walletAddress===void 0?{}:{walletAddress:this.walletAddress},o=this.walletAddress,s=this.buildPositionConfirmation(r,o),c={...a,...s===void 0?{}:{positionConfirmation:s}};return this.gateway.submit(e,i,c)}buildPositionConfirmation(e,t){if(e===void 0)return;if(e.kind===`createPool`){let{token0:t,token1:n,fee:r}=e;return async e=>await this.getNullable(`/pool`,{token0:t,token1:n,fee:`${r}`},e)===null?{confirmed:!1}:{confirmed:!0,position:null}}if(t===void 0)return;let{kind:n,identity:r}=e,i;return async e=>{let a=await this.getPosition({...r,owner:t},e);if(i===void 0)return i={liquidity:new A(a?.liquidity??0),fees:new A(a?.fees0??0).plus(new A(a?.fees1??0))},n===`removeFull`&&a===null?{confirmed:!0,position:null}:{confirmed:!1};switch(n){case`add`:return a!==null&&new A(a.liquidity).isGreaterThan(i.liquidity)?{confirmed:!0,position:a}:{confirmed:!1};case`removePartial`:return a!==null&&new A(a.liquidity).isLessThan(i.liquidity)?{confirmed:!0,position:a}:{confirmed:!1};case`removeFull`:return a===null?{confirmed:!0,position:null}:{confirmed:!1};case`collect`:{if(a===null)return{confirmed:!1};let e=new A(a.fees0??0).plus(new A(a.fees1??0));return e.isLessThan(i.fees)||i.fees.isZero()&&e.isZero()?{confirmed:!0,position:a}:{confirmed:!1}}}}}async get(e,t,n){return this.http.sendGetRequest(this.gateway.dexBackendBaseUrl,`/v2/trade`,e,t,n===void 0?void 0:{signal:n})}async getNullable(e,t,n){try{return await this.get(e,t,n)}catch(e){if(this.isNotFound(e))return null;throw e}}isNotFound(e){return r(e)&&e.status===404}canonicalTicks(e,t,n){return n?{tickLower:-t,tickUpper:-e}:{tickLower:e,tickUpper:t}}tickSpacing(t){let r=i[t];if(r===void 0)throw new n(`INVALID_FEE`,{field:`fee`,value:t,allowed:e});return r}rejectNumber(e,t){if(typeof e==`number`)throw new n(`AMOUNT_IS_JS_NUMBER`,{field:t})}uniqueKeyFor(e){return e===void 0?D(this.uniqueKeyPrefix):(T(e),e)}orderPair(e,t){return h(`${g(e)}/${g(t)}`,()=>this.symbols.orderPair(e,t))}async resolveCreateToken(e,t){try{let r=typeof e==`object`?E(e):e,i=await h(g(e),()=>this.symbols.resolve(r));if(t!==void 0&&t!==``&&t!==i.symbol)throw new n(`SYMBOL_DISAGREES_WITH_REGISTRY`,{token:g(e),suppliedSymbol:t,registeredSymbol:i.symbol});let a=this.tryParseClassKey(e);if(a===void 0&&i.collection===``)throw new n(`CREATE_POOL_NEEDS_CLASS_KEY`,{token:g(e)});return{symbol:i.symbol,classKey:a??m({collection:i.collection,category:i.category,type:i.type,additionalKey:i.additionalKey})}}catch(i){if(!r(i,`UNKNOWN_TOKEN`))throw i;let a;try{a=m(e)}catch{throw i}if(t===void 0||t===``)throw new n(`TOKEN_SYMBOL_NOT_REGISTERED`,{token:g(e)});if(!o(t))throw new n(`INVALID_TRADING_SYMBOL`,{symbol:t});return{symbol:t,classKey:a}}}tryParseClassKey(e){try{return m(e)}catch{return}}};const N=[`token0Symbol`,`token1Symbol`,`owner`,`liquidity`,`amount0`,`amount1`],P=[`fee`,`tickLower`,`tickUpper`],F=[`token0CompositeKey`,`token1CompositeKey`,`token0Image`,`token1Image`,`sqrtPrice`,`fees0`,`fees1`];function I(e){let t=u(e);if(t===void 0)return f(`the row is not an object`);for(let e of N)if(typeof t[e]!=`string`)return f(`${e} is not a string`);for(let e of P){let n=t[e];if(typeof n!=`number`||!Number.isFinite(n))return f(`${e} is not a number`)}if(typeof t.inRange!=`boolean`)return f(`inRange is not a boolean`);for(let e of F)if(t[e]!==void 0&&typeof t[e]!=`string`)return f(`${e} is not a string`);let n=t.currentTick;if(n!==void 0&&(typeof n!=`number`||!Number.isFinite(n)))return f(`currentTick is not a number`);let r=t.poolRef??t.pool??``;if(typeof r!=`string`)return f(`pool is not a string`);let i=Object.fromEntries([...F,`currentTick`].flatMap(e=>t[e]===void 0?[]:[[e,t[e]]]));return d({token0Symbol:t.token0Symbol,token1Symbol:t.token1Symbol,fee:t.fee,tickLower:t.tickLower,tickUpper:t.tickUpper,liquidity:t.liquidity,amount0:t.amount0,amount1:t.amount1,inRange:t.inRange,pool:r,owner:t.owner,...i})}function L(e){let t=I(e);if(t.ok)return t.value;throw new n(`INVALID_POSITION_RESPONSE`,{reason:t.reason},{body:e,write:!1})}export{M as Positions};
1
+ import{ALLOWED_FEE_TIERS_TEXT as e}from"./gswap_error_catalog.js";import t from"../_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/defineProperty.js";import{GSwapSDKError as n,isGSwapError as r}from"./gswap_sdk_error.js";import{TICK_SPACING_BY_FEE as i}from"../types/fees.js";import{tickFromPrice as a}from"../utils/tick_math.js";import{isProposableTradingSymbol as o,userRef as s,validateFee as c,validateNumericAmount as l}from"../utils/validation.js";import{HttpClient as u}from"./http_client.js";import{asEntryRecord as d,entryOk as f,entryRejected as p,readEntries as m}from"../utils/lenient.js";import{parseTokenClassKey as h}from"../utils/ordering.js";import{resolvePreSend as g}from"../utils/resolve_pre_send.js";import{rawTokenOf as _}from"./symbols.js";import{alignTickDown as v,alignTickUp as y,assertTickRange as b}from"../utils/ticks.js";import{assertCanonicalV2Dto as x,buildAddLiquidityDto as S,buildCollectPositionFeesDto as C,buildCreatePoolDto as w,buildRemoveLiquidityDto as T}from"../utils/dto_builders.js";import{assertUniqueKey as E,compositeKeyOf as D,createUniqueKey as O,resolveUniqueKeyPrefix as k,signPreSend as A}from"@gala-chain/gala-core-sdk";import j from"bignumber.js";function M(e){return{token0:e.token0,token1:e.token1,fee:e.fee,tickLower:e.tickLower,tickUpper:e.tickUpper}}var N=class{constructor(e,n,r,i,a={}){this.gateway=e,this.symbols=n,this.signer=r,t(this,`walletAddress`,void 0),t(this,`http`,void 0),t(this,`uniqueKeyPrefix`,void 0),t(this,`onInvalidEntry`,void 0),this.walletAddress=i===void 0?void 0:s(i,`walletAddress`),this.http=new u(e.httpRequestor,e.requestTimeoutMs??3e4,e.wire),this.uniqueKeyPrefix=k(a.uniqueKeyPrefix),this.onInvalidEntry=a.onInvalidEntry}async getUserPositions(e){let t=await this.get(`/positions`,{user:s(e,`owner`)});return m(`positions`,t.data,L,this.onInvalidEntry)}async getPosition(e,t){let n=await this.getNullable(`/position`,await this.positionParams(e),t);return n===null?null:R(n.data)}async readPosition(e,t){try{let n=await this.getPosition(e,t);return n===null?{kind:`not_found`}:{kind:`found`,data:n}}catch(e){if(t?.aborted===!0)throw e;return{kind:`unknown`,error:r(e)?e:new n(`REQUEST_FAILED`,{operation:`position`},{cause:e,write:!1})}}}async positionParams(e){let t=s(e.owner,`owner`);if(this.symbols.passthrough===!0)return{token0:_(e.token0),token1:_(e.token1),fee:`${e.fee}`,owner:t,tickLower:`${e.tickLower}`,tickUpper:`${e.tickUpper}`};let n=await this.orderPair(e.token0,e.token1),r=this.canonicalTicks(e.tickLower,e.tickUpper,n.flipped);return{token0:n.token0.symbol,token1:n.token1.symbol,fee:`${e.fee}`,owner:t,tickLower:`${r.tickLower}`,tickUpper:`${r.tickUpper}`}}async estimateAddLiquidity(e){return l(e.amount,`amount`),(await this.get(`/add-liq-estimate`,{token0:_(e.token0),token1:_(e.token1),fee:`${e.fee}`,tickLower:`${e.tickLower}`,tickUpper:`${e.tickUpper}`,amount:new j(e.amount).toFixed(),amountIsToken0:String(e.amountIsToken0)})).data}async estimateRemoveLiquidity(e){return l(e.liquidity,`liquidity`),(await this.get(`/remove-liq-estimate`,{token0:_(e.token0),token1:_(e.token1),fee:`${e.fee}`,tickLower:`${e.tickLower}`,tickUpper:`${e.tickUpper}`,liquidity:new j(e.liquidity).toFixed()})).data}async addLiquidityByTicks(e){return this.submitAddLiquidity(await this.buildAddLiquidity(e))}async buildAddLiquidity(e){c(e.fee);let t=await this.orderPair(e.token0,e.token1),n=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);b(n.tickLower,n.tickUpper,e.fee),l(e.amount,`amount`);let r={token0:t.token0.symbol,token1:t.token1.symbol,fee:e.fee,tickLower:n.tickLower,tickUpper:n.tickUpper,uniqueKey:this.uniqueKeyFor(e.uniqueKey)};return t.flipped===e.amountIsToken0?S({...r,depositQuantityToken1:e.amount}):S({...r,depositQuantityToken0:e.amount})}async submitAddLiquidity(e){return x(`AddLiquidity`,e),this.submit(`AddLiquidity`,e,{kind:`add`,identity:M(e)})}async addLiquidityByPrice(e){c(e.fee),this.rejectNumber(e.minPrice,`minPrice`),this.rejectNumber(e.maxPrice,`maxPrice`);let t=new j(e.minPrice),r=new j(e.maxPrice);if(!t.isFinite()||!r.isFinite()||t.isLessThanOrEqualTo(0)||r.isLessThanOrEqualTo(0))throw new n(`INVALID_PRICE_BOUNDS`,{minPrice:String(e.minPrice),maxPrice:String(e.maxPrice)});if(t.isGreaterThan(r))throw new n(`PRICE_BOUNDS_ORDER`,{minPrice:String(e.minPrice),maxPrice:String(e.maxPrice)});let i=this.tickSpacing(e.fee),o=v(a(t),i),s=y(a(r),i);return this.addLiquidityByTicks({token0:e.token0,token1:e.token1,fee:e.fee,tickLower:o,tickUpper:s,amount:e.amount,amountIsToken0:e.amountIsToken0,uniqueKey:e.uniqueKey})}async removeLiquidity(e){return this.submitRemoveLiquidity(await this.buildRemoveLiquidity(e))}async buildRemoveLiquidity(e){c(e.fee);let t=await this.orderPair(e.token0,e.token1),r=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);if(b(r.tickLower,r.tickUpper,e.fee),e.amount0!==void 0&&e.amount1!==void 0)throw new n(`AT_MOST_ONE_OF_ALLOWED`,{first:`amount0`,second:`amount1`});e.amount0!==void 0&&l(e.amount0,`amount0`),e.amount1!==void 0&&l(e.amount1,`amount1`);let[i,a]=t.flipped?[e.amount1,e.amount0]:[e.amount0,e.amount1];return T({token0:t.token0.symbol,token1:t.token1.symbol,fee:e.fee,tickLower:r.tickLower,tickUpper:r.tickUpper,uniqueKey:this.uniqueKeyFor(e.uniqueKey),withdrawalQuantityToken0:i,withdrawalQuantityToken1:a})}async submitRemoveLiquidity(e){x(`RemoveLiquidity`,e);let t=e.withdrawalQuantityToken0===void 0&&e.withdrawalQuantityToken1===void 0;return this.submit(`RemoveLiquidity`,e,{kind:t?`removeFull`:`removePartial`,identity:M(e)})}async collectPositionFees(e){return this.submitCollectPositionFees(await this.buildCollectPositionFees(e))}async buildCollectPositionFees(e){c(e.fee);let t=await this.orderPair(e.token0,e.token1),n=this.canonicalTicks(e.tickLower,e.tickUpper,t.flipped);return b(n.tickLower,n.tickUpper,e.fee),C({token0:t.token0.symbol,token1:t.token1.symbol,fee:e.fee,tickLower:n.tickLower,tickUpper:n.tickUpper,uniqueKey:this.uniqueKeyFor(e.uniqueKey)})}async submitCollectPositionFees(e){return x(`CollectPositionFees`,e),this.submit(`CollectPositionFees`,e,{kind:`collect`,identity:M(e)})}async createPool(e){return this.submitCreatePool(await this.buildCreatePool(e))}async buildCreatePool(e){let t=e.startingPrice!==void 0;if(t===(e.startingSqrtPrice!==void 0))throw new n(`EXACTLY_ONE_OF_REQUIRED`,{first:`startingPrice`,second:`startingSqrtPrice`});c(e.fee);let[r,i]=await Promise.all([this.resolveCreateToken(e.token0,e.token0Symbol),this.resolveCreateToken(e.token1,e.token1Symbol)]),a=r.symbol>i.symbol,[o,s]=a?[i,r]:[r,i],l=t?e.startingPrice:e.startingSqrtPrice;this.rejectNumber(l,t?`startingPrice`:`startingSqrtPrice`);let u=new j(l);if(!u.isFinite()||u.isLessThanOrEqualTo(0))throw new n(`INVALID_STARTING_PRICE`,{value:String(l)});let d=a?new j(1).dividedBy(u):u,f={token0Key:o.classKey,token1Key:s.classKey,token0Symbol:o.symbol,token1Symbol:s.symbol,fee:e.fee,uniqueKey:this.uniqueKeyFor(e.uniqueKey),name:e.name,isPrivate:e.isPrivate,privateAccess:e.privateAccess};return w(t?{...f,startingPrice:d}:{...f,startingSqrtPrice:d})}async submitCreatePool(e){x(`CreatePool`,e);let t=await this.submit(`CreatePool`,e,{kind:`createPool`,token0:e.token0Symbol,token1:e.token1Symbol,fee:e.fee});return this.symbols.invalidate?.(),t}async submit(e,t,r){if(this.signer===void 0)throw n.noSignerError();let i=await A(this.signer,e,t),a=this.walletAddress===void 0?{}:{walletAddress:this.walletAddress},o=this.walletAddress,s=this.buildPositionConfirmation(r,o),c={...a,...s===void 0?{}:{positionConfirmation:s}};return this.gateway.submit(e,i,c)}buildPositionConfirmation(e,t){if(e===void 0)return;if(e.kind===`createPool`){let{token0:t,token1:n,fee:r}=e;return async e=>await this.getNullable(`/pool`,{token0:t,token1:n,fee:`${r}`},e)===null?{confirmed:!1}:{confirmed:!0,position:null}}if(t===void 0)return;let{kind:n,identity:r}=e,i;return async e=>{let a=await this.getPosition({...r,owner:t},e);if(i===void 0)return i={liquidity:new j(a?.liquidity??0),fees:new j(a?.fees0??0).plus(new j(a?.fees1??0))},n===`removeFull`&&a===null?{confirmed:!0,position:null}:{confirmed:!1};switch(n){case`add`:return a!==null&&new j(a.liquidity).isGreaterThan(i.liquidity)?{confirmed:!0,position:a}:{confirmed:!1};case`removePartial`:return a!==null&&new j(a.liquidity).isLessThan(i.liquidity)?{confirmed:!0,position:a}:{confirmed:!1};case`removeFull`:return a===null?{confirmed:!0,position:null}:{confirmed:!1};case`collect`:{if(a===null)return{confirmed:!1};let e=new j(a.fees0??0).plus(new j(a.fees1??0));return e.isLessThan(i.fees)||i.fees.isZero()&&e.isZero()?{confirmed:!0,position:a}:{confirmed:!1}}}}}async get(e,t,n){return this.http.sendGetRequest(this.gateway.dexBackendBaseUrl,`/v2/trade`,e,t,n===void 0?void 0:{signal:n})}async getNullable(e,t,n){try{return await this.get(e,t,n)}catch(e){if(this.isNotFound(e))return null;throw e}}isNotFound(e){return r(e)&&e.status===404}canonicalTicks(e,t,n){return n?{tickLower:-t,tickUpper:-e}:{tickLower:e,tickUpper:t}}tickSpacing(t){let r=i[t];if(r===void 0)throw new n(`INVALID_FEE`,{field:`fee`,value:t,allowed:e});return r}rejectNumber(e,t){if(typeof e==`number`)throw new n(`AMOUNT_IS_JS_NUMBER`,{field:t})}uniqueKeyFor(e){return e===void 0?O(this.uniqueKeyPrefix):(E(e),e)}orderPair(e,t){return g(`${_(e)}/${_(t)}`,()=>this.symbols.orderPair(e,t))}async resolveCreateToken(e,t){try{let r=typeof e==`object`?D(e):e,i=await g(_(e),()=>this.symbols.resolve(r));if(t!==void 0&&t!==``&&t!==i.symbol)throw new n(`SYMBOL_DISAGREES_WITH_REGISTRY`,{token:_(e),suppliedSymbol:t,registeredSymbol:i.symbol});let a=this.tryParseClassKey(e);if(a===void 0&&i.collection===``)throw new n(`CREATE_POOL_NEEDS_CLASS_KEY`,{token:_(e)});return{symbol:i.symbol,classKey:a??h({collection:i.collection,category:i.category,type:i.type,additionalKey:i.additionalKey})}}catch(i){if(!r(i,`UNKNOWN_TOKEN`))throw i;let a;try{a=h(e)}catch{throw i}if(t===void 0||t===``)throw new n(`TOKEN_SYMBOL_NOT_REGISTERED`,{token:_(e)});if(!o(t))throw new n(`INVALID_TRADING_SYMBOL`,{symbol:t});return{symbol:t,classKey:a}}}tryParseClassKey(e){try{return h(e)}catch{return}}};const P=[`token0Symbol`,`token1Symbol`,`owner`,`liquidity`,`amount0`,`amount1`],F=[`fee`,`tickLower`,`tickUpper`],I=[`token0CompositeKey`,`token1CompositeKey`,`token0Image`,`token1Image`,`sqrtPrice`,`fees0`,`fees1`];function L(e){let t=d(e);if(t===void 0)return p(`the row is not an object`);for(let e of P)if(typeof t[e]!=`string`)return p(`${e} is not a string`);for(let e of F){let n=t[e];if(typeof n!=`number`||!Number.isFinite(n))return p(`${e} is not a number`)}if(typeof t.inRange!=`boolean`)return p(`inRange is not a boolean`);for(let e of I)if(t[e]!==void 0&&typeof t[e]!=`string`)return p(`${e} is not a string`);let n=t.currentTick;if(n!==void 0&&(typeof n!=`number`||!Number.isFinite(n)))return p(`currentTick is not a number`);let r=t.poolRef??t.pool??``;if(typeof r!=`string`)return p(`pool is not a string`);let i=Object.fromEntries([...I,`currentTick`].flatMap(e=>t[e]===void 0?[]:[[e,t[e]]]));return f({token0Symbol:t.token0Symbol,token1Symbol:t.token1Symbol,fee:t.fee,tickLower:t.tickLower,tickUpper:t.tickUpper,liquidity:t.liquidity,amount0:t.amount0,amount1:t.amount1,inRange:t.inRange,pool:r,owner:t.owner,...i})}function R(e){let t=L(e);if(t.ok)return t.value;throw new n(`INVALID_POSITION_RESPONSE`,{reason:t.reason},{body:e,write:!1})}export{N as Positions};
2
2
  //# sourceMappingURL=positions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"positions.js","names":["_defineProperty","BigNumber","identityOf","dto","Positions","gateway","symbols","signer","walletAddress","HttpClient","resolveUniqueKeyPrefix","options","response","owner","readEntries","parsePosition","args","signal","readPositionBody","position","error","isGSwapError","GSwapSDKError","rawTokenOf","pair","ticks","validateNumericAmount","validateFee","assertTickRange","base","buildAddLiquidityDto","assertCanonicalV2Dto","minPrice","maxPrice","spacing","tickLower","alignTickDown","tickFromPrice","tickUpper","alignTickUp","canonical0","canonical1","buildRemoveLiquidityDto","isFullClose","buildCollectPositionFeesDto","hasPrice","tokenA","tokenB","flipped","token0","token1","sourcePriceInput","sourcePrice","canonicalPrice","shared","buildCreatePoolDto","transaction","signed","signPreSend","method","submitOptions","positionConfirmation","confirmation","fee","baseline","current","identity","kind","currentFees","endpoint","params","TICK_SPACING_BY_FEE","ALLOWED_FEE_TIERS_TEXT","value","parameterName","supplied","createUniqueKey","assertUniqueKey","resolvePreSend","a","b","lookupRef","ref","compositeKeyOf","resolved","symbolOverride","suppliedClassKey","parseTokenClassKey","classKey","isProposableTradingSymbol","REQUIRED_POSITION_STRINGS","REQUIRED_POSITION_NUMBERS","OPTIONAL_POSITION_STRINGS","wire","asEntryRecord","entryRejected","key","number","\"inRange\"","currentTick","\"currentTick\"","pool","\"poolRef\"","\"pool\"","optional","entryOk","\"token0Symbol\"","\"token1Symbol\"","\"fee\"","\"tickLower\"","\"tickUpper\"","\"liquidity\"","\"amount0\"","\"amount1\"","\"owner\"","parsed","data"],"sources":["../../../src/classes/positions.ts"],"sourcesContent":["import {\n assertUniqueKey,\n compositeKeyOf,\n createUniqueKey,\n resolveUniqueKeyPrefix,\n signPreSend,\n type GalaChainSigner,\n type UniqueKeyOptions,\n type WireOptions,\n} from '@gala-chain/gala-core-sdk';\nimport BigNumber from 'bignumber.js';\nimport { ALLOWED_FEE_TIERS_TEXT } from './gswap_error_catalog.js';\nimport { GSwapSDKError, isGSwapError } from './gswap_sdk_error.js';\nimport type { ChainGateway, ChainSubmitOptions } from './gateway.js';\nimport type { PositionConfirmationResult, SubmittedTransaction } from './submitted_transaction.js';\nimport { HttpClient } from './http_client.js';\nimport { rawTokenOf, type Symbols, type TokenResolver } from './symbols.js';\nimport type { NumericAmount, PriceIn } from '../types/amounts.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { TICK_SPACING_BY_FEE } from '../types/fees.js';\nimport type {\n AddLiquidityDTO,\n CollectPositionFeesDTO,\n CreatePoolDTO,\n RemoveLiquidityDTO,\n} from '../types/v2_dtos.js';\nimport type {\n AddLiquidityEstimate,\n Position,\n RemoveLiquidityEstimate,\n} from '../types/v2_results.js';\nimport {\n asEntryRecord,\n entryOk,\n entryRejected,\n readEntries,\n type EntryParse,\n type InvalidEntryHandler,\n} from '../utils/lenient.js';\nimport { type TokenRef, parseTokenClassKey } from '../utils/ordering.js';\nimport { resolvePreSend } from '../utils/resolve_pre_send.js';\nimport {\n isProposableTradingSymbol,\n validateFee,\n validateNumericAmount,\n} from '../utils/validation.js';\nimport { tickFromPrice } from '../utils/tick_math.js';\nimport { alignTickDown, alignTickUp, assertTickRange } from '../utils/ticks.js';\nimport {\n assertCanonicalV2Dto,\n buildAddLiquidityDto,\n buildCollectPositionFeesDto,\n buildCreatePoolDto,\n buildRemoveLiquidityDto,\n} from '../utils/dto_builders.js';\n\ntype PositionGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {\n submit: (\n method: string,\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<SubmittedTransaction<Position | null>>;\n requestTimeoutMs?: number | undefined;\n wire?: WireOptions | undefined;\n};\ntype PositionSymbols = TokenResolver & Pick<Symbols, 'orderPair'> & { invalidate?: () => void };\n\n/** Options of {@link Positions}: the `uniqueKey` prefix and a handler for skipped list rows. */\nexport interface PositionsOptions extends UniqueKeyOptions {\n /** Told about every position row of a list that was skipped as unusable. */\n onInvalidEntry?: InvalidEntryHandler | undefined;\n}\n\n/** A write's optional attempt identity. */\ninterface UniqueKeyArg {\n /**\n * The attempt's `uniqueKey` (1-128 characters of `A-Za-z0-9._:-`). Default: a fresh\n * `<uniqueKeyPrefix><uuid>`. Supply one to know the key before signing, or to retry the SAME\n * attempt after a lost response; never reuse it for another write.\n */\n uniqueKey?: string | undefined;\n}\n\n/** Arguments of {@link Positions.addLiquidityByTicks} and {@link Positions.buildAddLiquidity}. */\nexport interface AddLiquidityArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount: NumericAmount;\n /** Whether `amount` is of `token0` as the caller passed it (not of the canonical token0). */\n amountIsToken0: boolean;\n}\n\n/** Arguments of {@link Positions.removeLiquidity} and {@link Positions.buildRemoveLiquidity}. */\nexport interface RemoveLiquidityArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n /** Withdraw this much of the caller's `token0`; give at most one of `amount0` / `amount1`. */\n amount0?: NumericAmount | undefined;\n amount1?: NumericAmount | undefined;\n}\n\n/** Arguments of {@link Positions.collectPositionFees} and {@link Positions.buildCollectPositionFees}. */\nexport interface CollectPositionFeesArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n}\n\n/** Arguments of {@link Positions.createPool} and {@link Positions.buildCreatePool}. */\nexport interface CreatePoolArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n token0Symbol?: string | undefined;\n token1Symbol?: string | undefined;\n fee: FEE_TIER;\n startingPrice?: NumericAmount | undefined;\n startingSqrtPrice?: NumericAmount | undefined;\n /** Optional pool display name, sent as the DTO's `name`; omitted when undefined or empty. */\n name?: string | undefined;\n isPrivate?: boolean | undefined;\n privateAccess?: string[] | undefined;\n}\n\n/** The pool position a liquidity DTO names, as its confirmation needs it. */\nfunction identityOf(\n dto: Pick<CollectPositionFeesDTO, 'token0' | 'token1' | 'fee' | 'tickLower' | 'tickUpper'>,\n): PositionIdentity {\n return {\n token0: dto.token0,\n token1: dto.token1,\n fee: dto.fee,\n tickLower: dto.tickLower,\n tickUpper: dto.tickUpper,\n };\n}\n\n/**\n * The outcome of {@link Positions.readPosition}. Only `not_found` is chain-confirmed absence (the\n * backend answers HTTP 404 only when the chain itself found no such position); `unknown` is \"no\n * evidence either way\" — a transport failure, a gateway timeout, any other error status or an\n * answer that is not a position — and must never be read as a removal.\n */\nexport type PositionRead =\n | { kind: 'found'; data: Position }\n | { kind: 'not_found' }\n | { kind: 'unknown'; error: GSwapSDKError };\n\ninterface BackendEnvelope<TData> {\n data: TData;\n}\n\ninterface AddLiquidityEstimateWire {\n amount0: string;\n amount1: string;\n liquidity: string;\n token0Symbol: string;\n token1Symbol: string;\n tickLower: number;\n tickUpper: number;\n amountIsCanonicalToken0: boolean;\n}\n\ninterface RemoveLiquidityEstimateWire {\n amount0: string;\n amount1: string;\n}\n\ninterface ResolvedCreateToken {\n symbol: string;\n classKey: ReturnType<typeof parseTokenClassKey>;\n}\n\ninterface PositionIdentity {\n token0: string;\n token1: string;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n}\n\n/** Tells `submit()` how to prove a write's own effect for `SubmittedTransaction.confirm()`. */\ntype PositionSubmitConfirmation =\n | { kind: 'add' | 'removePartial' | 'removeFull' | 'collect'; identity: PositionIdentity }\n | { kind: 'createPool'; token0: string; token1: string; fee: FEE_TIER };\n\n/**\n * Manages current-contract concentrated-liquidity positions.\n *\n * @example\n * ```typescript\n * const positions = gSwap.positions;\n * const mine = await positions.getUserPositions('client|012345678901234567890123');\n * console.log(mine.length);\n * ```\n */\nexport class Positions {\n constructor(\n private readonly gateway: PositionGateway,\n private readonly symbols: PositionSymbols,\n private readonly signer?: GalaChainSigner,\n private readonly walletAddress?: string,\n options: PositionsOptions = {},\n ) {\n this.http = new HttpClient(\n gateway.httpRequestor,\n gateway.requestTimeoutMs ?? 30_000,\n gateway.wire,\n );\n this.uniqueKeyPrefix = resolveUniqueKeyPrefix(options.uniqueKeyPrefix);\n this.onInvalidEntry = options.onInvalidEntry;\n }\n\n private readonly http: HttpClient;\n private readonly uniqueKeyPrefix: string;\n private readonly onInvalidEntry: InvalidEntryHandler | undefined;\n\n /**\n * Gets all current-contract positions owned by an address.\n *\n * @param owner - GalaChain owner identity.\n * @returns Enriched positions from the v2 trade backend, token images included. A row that is\n * not a usable position is skipped and reported to `onInvalidEntry`.\n * @example\n * ```typescript\n * const positions = await gSwap.positions.getUserPositions('client|012345678901234567890123');\n * ```\n */\n async getUserPositions(owner: string): Promise<Position[]> {\n const response = await this.get<unknown>('/positions', { user: owner });\n return readEntries('positions', response.data, parsePosition, this.onInvalidEntry);\n }\n\n /**\n * Gets one position, normalizing a caller-supplied reversed pair to canonical symbol order.\n * Reversed pairs also invert the price axis, so `[lower, upper]` becomes `[-upper, -lower]`.\n *\n * @param args - Pair, owner, fee, and position tick range.\n * @returns The position, or `null` when the backend returns 404.\n * @example\n * ```typescript\n * const position = await gSwap.positions.getPosition({\n * token0: 'GALA', token1: 'GUSDC', owner: 'client|012345678901234567890123',\n * fee: 3000, tickLower: -19200, tickUpper: 12000,\n * });\n * ```\n */\n async getPosition(\n args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n owner: string;\n tickLower: number;\n tickUpper: number;\n },\n signal?: AbortSignal,\n ): Promise<Position | null> {\n const response = await this.getNullable<unknown>(\n '/position',\n await this.positionParams(args),\n signal,\n );\n return response === null ? null : readPositionBody(response.data);\n }\n\n /**\n * Reads one position and classifies the outcome instead of throwing: `found` with the position\n * (fees included), `not_found` (the backend's HTTP 404, which it sends only when the chain\n * itself has no such position) or `unknown` (any other failure, carried as `error`). Use it\n * to confirm a write: `unknown` is \"no evidence either way\", never a confirmed absence.\n *\n * Only the caller's own abort rethrows. With a pass-through resolver ({@link CanonicalSymbols})\n * the pair and ticks go to the backend exactly as given and the backend orients them.\n *\n * @example\n * ```typescript\n * const read = await gSwap.positions.readPosition({\n * token0: 'GALA', token1: 'GUSDC', owner: 'client|012345678901234567890123',\n * fee: 3000, tickLower: -19200, tickUpper: 12000,\n * });\n * if (read.kind === 'found') console.log(read.data.fees0);\n * ```\n */\n async readPosition(\n args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n owner: string;\n tickLower: number;\n tickUpper: number;\n },\n signal?: AbortSignal,\n ): Promise<PositionRead> {\n try {\n const position = await this.getPosition(args, signal);\n return position === null ? { kind: 'not_found' } : { kind: 'found', data: position };\n } catch (error: unknown) {\n if (signal?.aborted === true) throw error;\n return {\n kind: 'unknown',\n error: isGSwapError(error)\n ? error\n : new GSwapSDKError(\n 'REQUEST_FAILED',\n { operation: 'position' },\n { cause: error, write: false },\n ),\n };\n }\n }\n\n /**\n * The `/position` query: canonical symbols and canonical ticks after a client-side flip, or,\n * for a pass-through resolver, the caller's references and ticks untouched.\n */\n private async positionParams(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n owner: string;\n tickLower: number;\n tickUpper: number;\n }): Promise<Record<string, string>> {\n if (this.symbols.passthrough === true) {\n return {\n token0: rawTokenOf(args.token0),\n token1: rawTokenOf(args.token1),\n fee: `${args.fee}`,\n owner: args.owner,\n tickLower: `${args.tickLower}`,\n tickUpper: `${args.tickUpper}`,\n };\n }\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n return {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: `${args.fee}`,\n owner: args.owner,\n tickLower: `${ticks.tickLower}`,\n tickUpper: `${ticks.tickUpper}`,\n };\n }\n\n /**\n * Estimates the other token amount and resulting liquidity for a deposit.\n *\n * @param args - Pair, tick range, deposit amount, and the amount's caller-side token index.\n * @returns Backend liquidity estimate.\n * @example\n * ```typescript\n * const estimate = await gSwap.positions.estimateAddLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,\n * });\n * ```\n */\n async estimateAddLiquidity(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount: NumericAmount;\n amountIsToken0: boolean;\n }): Promise<AddLiquidityEstimate> {\n validateNumericAmount(args.amount, 'amount');\n const response = await this.get<AddLiquidityEstimateWire>('/add-liq-estimate', {\n token0: rawTokenOf(args.token0),\n token1: rawTokenOf(args.token1),\n fee: `${args.fee}`,\n tickLower: `${args.tickLower}`,\n tickUpper: `${args.tickUpper}`,\n amount: new BigNumber(args.amount).toFixed(),\n amountIsToken0: String(args.amountIsToken0),\n });\n return response.data;\n }\n\n /**\n * Estimates token amounts released by burning liquidity.\n *\n * @param args - Pair, tick range, fee tier, and liquidity quantity.\n * @returns Estimated token0 and token1 quantities.\n * @example\n * ```typescript\n * const estimate = await gSwap.positions.estimateRemoveLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, liquidity: '1000',\n * });\n * ```\n */\n async estimateRemoveLiquidity(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n liquidity: NumericAmount;\n }): Promise<RemoveLiquidityEstimate> {\n validateNumericAmount(args.liquidity, 'liquidity');\n const response = await this.get<RemoveLiquidityEstimateWire>('/remove-liq-estimate', {\n token0: rawTokenOf(args.token0),\n token1: rawTokenOf(args.token1),\n fee: `${args.fee}`,\n tickLower: `${args.tickLower}`,\n tickUpper: `${args.tickUpper}`,\n liquidity: new BigNumber(args.liquidity).toFixed(),\n });\n return response.data;\n }\n\n /**\n * Adds liquidity using an explicit tick range. Exactly one canonical deposit field is emitted.\n *\n * @param args - Pair, fee, range, deposit amount, and caller-side token index.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.addLiquidityByTicks({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,\n * });\n * await tx.confirm();\n * ```\n */\n async addLiquidityByTicks(args: AddLiquidityArgs) {\n return this.submitAddLiquidity(await this.buildAddLiquidity(args));\n }\n\n /**\n * Builds the AddLiquidity DTO that {@link addLiquidityByTicks} would sign, without signing or\n * sending it: to show in an approval popup, or to sign elsewhere. Submit exactly this DTO with\n * {@link submitAddLiquidity}. The pure counterpart, with canonical inputs and no resolution,\n * is `buildAddLiquidityDto`.\n *\n * @example\n * ```typescript\n * const dto = await gSwap.positions.buildAddLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,\n * });\n * ```\n */\n async buildAddLiquidity(args: AddLiquidityArgs): Promise<AddLiquidityDTO> {\n validateFee(args.fee);\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n // Caller-facing checks first, so a refusal names the caller's own argument (`amount`).\n assertTickRange(ticks.tickLower, ticks.tickUpper, args.fee);\n validateNumericAmount(args.amount, 'amount');\n const base = {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n };\n return pair.flipped !== args.amountIsToken0\n ? buildAddLiquidityDto({ ...base, depositQuantityToken0: args.amount })\n : buildAddLiquidityDto({ ...base, depositQuantityToken1: args.amount });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildAddLiquidity} or `buildAddLiquidityDto`; it must\n * be exactly what the builder produces. The returned transaction confirms by proving the\n * position's liquidity grew.\n */\n async submitAddLiquidity(dto: AddLiquidityDTO) {\n assertCanonicalV2Dto('AddLiquidity', dto);\n return this.submit('AddLiquidity', dto, { kind: 'add', identity: identityOf(dto) });\n }\n\n /**\n * Adds liquidity from prices, flooring the lower tick and ceiling the upper tick to fee spacing.\n * The resulting range is therefore no narrower than the requested price interval.\n *\n * @param args - Pair, fee, price range, deposit amount, and caller-side token index.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.addLiquidityByPrice({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * minPrice: '0.14', maxPrice: '0.16', amount: '100', amountIsToken0: true,\n * });\n * ```\n */\n async addLiquidityByPrice(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n minPrice: PriceIn;\n maxPrice: PriceIn;\n amount: NumericAmount;\n amountIsToken0: boolean;\n /** The attempt's `uniqueKey`; default a fresh one (see {@link AddLiquidityArgs.uniqueKey}). */\n uniqueKey?: string | undefined;\n }) {\n validateFee(args.fee);\n this.rejectNumber(args.minPrice, 'minPrice');\n this.rejectNumber(args.maxPrice, 'maxPrice');\n const minPrice = new BigNumber(args.minPrice);\n const maxPrice = new BigNumber(args.maxPrice);\n if (\n !minPrice.isFinite() ||\n !maxPrice.isFinite() ||\n minPrice.isLessThanOrEqualTo(0) ||\n maxPrice.isLessThanOrEqualTo(0)\n ) {\n throw new GSwapSDKError('INVALID_PRICE_BOUNDS', {\n minPrice: String(args.minPrice),\n maxPrice: String(args.maxPrice),\n });\n }\n if (minPrice.isGreaterThan(maxPrice)) {\n throw new GSwapSDKError('PRICE_BOUNDS_ORDER', {\n minPrice: String(args.minPrice),\n maxPrice: String(args.maxPrice),\n });\n }\n const spacing = this.tickSpacing(args.fee);\n const tickLower = alignTickDown(tickFromPrice(minPrice), spacing);\n const tickUpper = alignTickUp(tickFromPrice(maxPrice), spacing);\n return this.addLiquidityByTicks({\n token0: args.token0,\n token1: args.token1,\n fee: args.fee,\n tickLower,\n tickUpper,\n amount: args.amount,\n amountIsToken0: args.amountIsToken0,\n uniqueKey: args.uniqueKey,\n });\n }\n\n /**\n * Removes liquidity by withdrawing at most one canonical token quantity.\n * Omitting both amounts closes the position and sweeps all accrued fees.\n *\n * @param args - Pair, fee, range, and optional caller-side withdrawal amount.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.removeLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000,\n * });\n * ```\n */\n async removeLiquidity(args: RemoveLiquidityArgs) {\n return this.submitRemoveLiquidity(await this.buildRemoveLiquidity(args));\n }\n\n /**\n * Builds the RemoveLiquidity DTO that {@link removeLiquidity} would sign, without signing or\n * sending it. Submit exactly this DTO with {@link submitRemoveLiquidity}. The pure counterpart\n * is `buildRemoveLiquidityDto`.\n */\n async buildRemoveLiquidity(args: RemoveLiquidityArgs): Promise<RemoveLiquidityDTO> {\n validateFee(args.fee);\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n assertTickRange(ticks.tickLower, ticks.tickUpper, args.fee);\n if (args.amount0 !== undefined && args.amount1 !== undefined) {\n throw new GSwapSDKError('AT_MOST_ONE_OF_ALLOWED', { first: 'amount0', second: 'amount1' });\n }\n if (args.amount0 !== undefined) validateNumericAmount(args.amount0, 'amount0');\n if (args.amount1 !== undefined) validateNumericAmount(args.amount1, 'amount1');\n // The caller's amount0 / amount1 follow the caller's pair; the DTO's follow the canonical one.\n const [canonical0, canonical1] = pair.flipped\n ? [args.amount1, args.amount0]\n : [args.amount0, args.amount1];\n return buildRemoveLiquidityDto({\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n withdrawalQuantityToken0: canonical0,\n withdrawalQuantityToken1: canonical1,\n });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildRemoveLiquidity} or `buildRemoveLiquidityDto`;\n * it must be exactly what the builder produces. A DTO with no withdrawal quantity closes the\n * position, and the returned transaction then confirms by proving the position is gone.\n */\n async submitRemoveLiquidity(dto: RemoveLiquidityDTO) {\n assertCanonicalV2Dto('RemoveLiquidity', dto);\n const isFullClose =\n dto.withdrawalQuantityToken0 === undefined && dto.withdrawalQuantityToken1 === undefined;\n return this.submit('RemoveLiquidity', dto, {\n kind: isFullClose ? 'removeFull' : 'removePartial',\n identity: identityOf(dto),\n });\n }\n\n /**\n * Collects all accrued fees for a position; the contract does not support partial collection.\n *\n * @param args - Pair, fee, and tick range identifying the position.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.collectPositionFees({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000,\n * });\n * ```\n */\n async collectPositionFees(args: CollectPositionFeesArgs) {\n return this.submitCollectPositionFees(await this.buildCollectPositionFees(args));\n }\n\n /**\n * Builds the CollectPositionFees DTO that {@link collectPositionFees} would sign, without\n * signing or sending it. Submit exactly this DTO with {@link submitCollectPositionFees}. The\n * pure counterpart is `buildCollectPositionFeesDto`.\n */\n async buildCollectPositionFees(args: CollectPositionFeesArgs): Promise<CollectPositionFeesDTO> {\n validateFee(args.fee);\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n assertTickRange(ticks.tickLower, ticks.tickUpper, args.fee);\n return buildCollectPositionFeesDto({\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildCollectPositionFees} or\n * `buildCollectPositionFeesDto`; it must be exactly what the builder produces.\n */\n async submitCollectPositionFees(dto: CollectPositionFeesDTO) {\n assertCanonicalV2Dto('CollectPositionFees', dto);\n return this.submit('CollectPositionFees', dto, { kind: 'collect', identity: identityOf(dto) });\n }\n\n /**\n * Creates a pool, resolving registered trading symbols.\n * Reversed symbol order inverts the supplied starting price or square-root price.\n *\n * A token class key carries no symbol, so for a token being proposed into the v2\n * trading-symbol registry for the first time (no existing pool has registered it yet) the\n * caller MUST pass `token0Symbol`/`token1Symbol` (the token class's symbol, from the token\n * list or FetchTokenClasses). The SDK never derives a symbol from the key, and throws a\n * TOKEN_SYMBOL_NOT_REGISTERED error when an unregistered token has none. For an already-registered token a\n * supplied symbol must match the registered one.\n *\n * @param args - Token class keys or references, fee, exactly one starting price field, and privacy options.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.createPool({\n * token0: 'GALA|Unit|none|none', token1: 'GUSDC|Unit|none|none', fee: 3000,\n * startingPrice: '0.15',\n * });\n * ```\n */\n async createPool(args: CreatePoolArgs) {\n return this.submitCreatePool(await this.buildCreatePool(args));\n }\n\n /**\n * Builds the CreatePool DTO that {@link createPool} would sign, without signing or sending it:\n * symbols resolved or proposed, the pair put in canonical order and the price inverted when it\n * was reversed. Submit exactly this DTO with {@link submitCreatePool}. The pure counterpart,\n * with canonical inputs, is `buildCreatePoolDto`.\n */\n async buildCreatePool(args: CreatePoolArgs): Promise<CreatePoolDTO> {\n const hasPrice = args.startingPrice !== undefined;\n const hasSqrtPrice = args.startingSqrtPrice !== undefined;\n if (hasPrice === hasSqrtPrice) {\n throw new GSwapSDKError('EXACTLY_ONE_OF_REQUIRED', {\n first: 'startingPrice',\n second: 'startingSqrtPrice',\n });\n }\n validateFee(args.fee);\n const [tokenA, tokenB] = await Promise.all([\n this.resolveCreateToken(args.token0, args.token0Symbol),\n this.resolveCreateToken(args.token1, args.token1Symbol),\n ]);\n const flipped = tokenA.symbol > tokenB.symbol;\n const [token0, token1] = flipped ? [tokenB, tokenA] : [tokenA, tokenB];\n const sourcePriceInput = hasPrice\n ? (args.startingPrice as NumericAmount)\n : (args.startingSqrtPrice as NumericAmount);\n this.rejectNumber(sourcePriceInput, hasPrice ? 'startingPrice' : 'startingSqrtPrice');\n const sourcePrice = new BigNumber(sourcePriceInput);\n if (!sourcePrice.isFinite() || sourcePrice.isLessThanOrEqualTo(0)) {\n throw new GSwapSDKError('INVALID_STARTING_PRICE', { value: String(sourcePriceInput) });\n }\n const canonicalPrice = flipped ? new BigNumber(1).dividedBy(sourcePrice) : sourcePrice;\n const shared = {\n token0Key: token0.classKey,\n token1Key: token1.classKey,\n token0Symbol: token0.symbol,\n token1Symbol: token1.symbol,\n fee: args.fee,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n name: args.name,\n isPrivate: args.isPrivate,\n privateAccess: args.privateAccess,\n };\n return hasPrice\n ? buildCreatePoolDto({ ...shared, startingPrice: canonicalPrice })\n : buildCreatePoolDto({ ...shared, startingSqrtPrice: canonicalPrice });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildCreatePool} or `buildCreatePoolDto`; it must be\n * exactly what the builder produces. The returned transaction confirms by the pool existing, and\n * the cached symbol registry is dropped, since the pool may have registered new symbols.\n */\n async submitCreatePool(dto: CreatePoolDTO) {\n assertCanonicalV2Dto('CreatePool', dto);\n const transaction = await this.submit('CreatePool', dto, {\n kind: 'createPool',\n token0: dto.token0Symbol,\n token1: dto.token1Symbol,\n fee: dto.fee,\n });\n this.symbols.invalidate?.();\n return transaction;\n }\n\n private async submit(\n method: string,\n dto: Record<string, unknown>,\n confirmation?: PositionSubmitConfirmation,\n ) {\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n const signed = await signPreSend(this.signer, method, dto);\n const submitOptions =\n this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress };\n const owner = this.walletAddress;\n const positionConfirmation = this.buildPositionConfirmation(confirmation, owner);\n const options: ChainSubmitOptions = {\n ...submitOptions,\n ...(positionConfirmation === undefined ? {} : { positionConfirmation }),\n };\n return this.gateway.submit(method, signed, options);\n }\n\n /**\n * Builds a confirmation closure that proves the write's own effect, not just that a\n * position row exists (true before most of these writes run too, for any operation on a\n * pre-existing position — existence alone would false-confirm before the write executes,\n * and would never confirm a full close, whose whole point is that the position stops\n * existing).\n *\n * The \"before\" state is captured lazily, on the confirmation closure's own first poll —\n * not eagerly here in `submit()` — so confirming a write never adds an extra round-trip to\n * the write itself; the cost of establishing the baseline is paid by `confirm()`, only if\n * and when the caller actually asks to confirm.\n */\n private buildPositionConfirmation(\n confirmation: PositionSubmitConfirmation | undefined,\n owner: string | undefined,\n ): ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined {\n if (confirmation === undefined) return undefined;\n\n if (confirmation.kind === 'createPool') {\n const { token0, token1, fee } = confirmation;\n return async (signal) => {\n const pool = await this.getNullable<unknown>(\n '/pool',\n { token0, token1, fee: `${fee}` },\n signal,\n );\n return pool === null ? { confirmed: false } : { confirmed: true, position: null };\n };\n }\n\n if (owner === undefined) return undefined;\n const { kind, identity } = confirmation;\n let baseline: { liquidity: BigNumber; fees: BigNumber } | undefined;\n\n return async (signal) => {\n const current = await this.getPosition({ ...identity, owner }, signal);\n\n if (baseline === undefined) {\n // First poll only establishes the baseline to compare future polls against — it can\n // never itself be the confirmed outcome (nothing has been observed to change yet).\n baseline = {\n liquidity: new BigNumber(current?.liquidity ?? 0),\n fees: new BigNumber(current?.fees0 ?? 0).plus(new BigNumber(current?.fees1 ?? 0)),\n };\n // A full close starting from \"already gone\" (e.g. a retried confirm after the position\n // was already swept) is confirmed immediately rather than waiting for a change that\n // already happened.\n return kind === 'removeFull' && current === null\n ? { confirmed: true, position: null }\n : { confirmed: false };\n }\n\n switch (kind) {\n case 'add':\n return current !== null &&\n new BigNumber(current.liquidity).isGreaterThan(baseline.liquidity)\n ? { confirmed: true, position: current }\n : { confirmed: false };\n case 'removePartial':\n return current !== null && new BigNumber(current.liquidity).isLessThan(baseline.liquidity)\n ? { confirmed: true, position: current }\n : { confirmed: false };\n case 'removeFull':\n return current === null ? { confirmed: true, position: null } : { confirmed: false };\n case 'collect': {\n if (current === null) return { confirmed: false };\n const currentFees = new BigNumber(current.fees0 ?? 0).plus(\n new BigNumber(current.fees1 ?? 0),\n );\n if (currentFees.isLessThan(baseline.fees)) return { confirmed: true, position: current };\n // Nothing to sweep in the first place — a legitimate no-op collect never moves\n // fees, so \"still zero\" is the confirmed outcome, not an unconfirmed one.\n if (baseline.fees.isZero() && currentFees.isZero())\n return { confirmed: true, position: current };\n return { confirmed: false };\n }\n }\n };\n }\n\n private async get<TData>(\n endpoint: string,\n params: Record<string, string>,\n signal?: AbortSignal,\n ): Promise<BackendEnvelope<TData>> {\n return this.http.sendGetRequest<BackendEnvelope<TData>>(\n this.gateway.dexBackendBaseUrl,\n '/v2/trade',\n endpoint,\n params,\n signal === undefined ? undefined : { signal },\n );\n }\n\n private async getNullable<TData>(\n endpoint: string,\n params: Record<string, string>,\n signal?: AbortSignal,\n ): Promise<BackendEnvelope<TData> | null> {\n try {\n return await this.get<TData>(endpoint, params, signal);\n } catch (error: unknown) {\n if (this.isNotFound(error)) return null;\n throw error;\n }\n }\n\n private isNotFound(error: unknown): boolean {\n return isGSwapError(error) && error.status === 404;\n }\n\n private canonicalTicks(tickLower: number, tickUpper: number, flipped: boolean) {\n return flipped ? { tickLower: -tickUpper, tickUpper: -tickLower } : { tickLower, tickUpper };\n }\n\n private tickSpacing(fee: number): number {\n const spacing = (TICK_SPACING_BY_FEE as Record<number, number>)[fee];\n if (spacing === undefined) {\n throw new GSwapSDKError('INVALID_FEE', {\n field: 'fee',\n value: fee,\n allowed: ALLOWED_FEE_TIERS_TEXT,\n });\n }\n return spacing;\n }\n\n private rejectNumber(value: unknown, parameterName: string): void {\n if (typeof value === 'number') {\n throw new GSwapSDKError('AMOUNT_IS_JS_NUMBER', { field: parameterName });\n }\n }\n\n /** The caller's `uniqueKey` (validated), else a fresh one. */\n private uniqueKeyFor(supplied: string | undefined): string {\n if (supplied === undefined) return createUniqueKey(this.uniqueKeyPrefix);\n assertUniqueKey(supplied);\n return supplied;\n }\n\n /**\n * The pair in canonical order. A resolver failure that is not an SDK error (an app's own\n * resolver, an app requestor's rejection during the registry read) is `TOKEN_RESOLUTION_FAILED`.\n */\n private orderPair(a: TokenRef, b: TokenRef) {\n return resolvePreSend(`${rawTokenOf(a)}/${rawTokenOf(b)}`, () => this.symbols.orderPair(a, b));\n }\n\n private async resolveCreateToken(\n ref: TokenRef,\n symbolOverride?: string,\n ): Promise<ResolvedCreateToken> {\n try {\n const lookupRef = typeof ref === 'object' ? compositeKeyOf(ref) : ref;\n const resolved = await resolvePreSend(rawTokenOf(ref), () => this.symbols.resolve(lookupRef));\n if (\n symbolOverride !== undefined &&\n symbolOverride !== '' &&\n symbolOverride !== resolved.symbol\n ) {\n throw new GSwapSDKError('SYMBOL_DISAGREES_WITH_REGISTRY', {\n token: rawTokenOf(ref),\n suppliedSymbol: symbolOverride,\n registeredSymbol: resolved.symbol,\n });\n }\n const suppliedClassKey = this.tryParseClassKey(ref);\n if (suppliedClassKey === undefined && resolved.collection === '') {\n // An offline resolver knows a bare symbol but not its class key; a pool needs the key.\n throw new GSwapSDKError('CREATE_POOL_NEEDS_CLASS_KEY', { token: rawTokenOf(ref) });\n }\n return {\n symbol: resolved.symbol,\n classKey:\n suppliedClassKey ??\n parseTokenClassKey({\n collection: resolved.collection,\n category: resolved.category,\n type: resolved.type,\n additionalKey: resolved.additionalKey,\n }),\n };\n } catch (error: unknown) {\n if (!isGSwapError(error, 'UNKNOWN_TOKEN')) {\n throw error;\n }\n let classKey: ReturnType<typeof parseTokenClassKey>;\n try {\n classKey = parseTokenClassKey(ref);\n } catch {\n throw error;\n }\n // First-time registration: a class key carries NO symbol (collection and symbol disagree\n // for many tokens, launchpad tokens all share collection `Token`, and some collections\n // contain `$`), so the symbol to propose must be supplied by the caller from the token\n // class / registry. Never derive it from the key.\n if (symbolOverride === undefined || symbolOverride === '') {\n throw new GSwapSDKError('TOKEN_SYMBOL_NOT_REGISTERED', { token: rawTokenOf(ref) });\n }\n if (!isProposableTradingSymbol(symbolOverride)) {\n throw new GSwapSDKError('INVALID_TRADING_SYMBOL', { symbol: symbolOverride });\n }\n return { symbol: symbolOverride, classKey };\n }\n }\n\n private tryParseClassKey(ref: TokenRef): ReturnType<typeof parseTokenClassKey> | undefined {\n try {\n return parseTokenClassKey(ref);\n } catch {\n return undefined;\n }\n }\n}\n\nconst REQUIRED_POSITION_STRINGS = [\n 'token0Symbol',\n 'token1Symbol',\n 'owner',\n 'liquidity',\n 'amount0',\n 'amount1',\n] as const;\nconst REQUIRED_POSITION_NUMBERS = ['fee', 'tickLower', 'tickUpper'] as const;\nconst OPTIONAL_POSITION_STRINGS = [\n 'token0CompositeKey',\n 'token1CompositeKey',\n 'token0Image',\n 'token1Image',\n 'sqrtPrice',\n 'fees0',\n 'fees1',\n] as const;\n\n/**\n * Reads one position row of `/positions` or `/position`: the pair, owner, range, liquidity and\n * amounts must be usable; the composite keys, token images, current tick and price, and the\n * escrowed fees are carried when present. `pool` is the pool reference (`poolRef` wins over\n * `pool`; `''` when the row names neither).\n */\nfunction parsePosition(value: unknown): EntryParse<Position> {\n const wire = asEntryRecord(value);\n if (wire === undefined) return entryRejected('the row is not an object');\n for (const key of REQUIRED_POSITION_STRINGS) {\n if (typeof wire[key] !== 'string') return entryRejected(`${key} is not a string`);\n }\n for (const key of REQUIRED_POSITION_NUMBERS) {\n const number = wire[key];\n if (typeof number !== 'number' || !Number.isFinite(number)) {\n return entryRejected(`${key} is not a number`);\n }\n }\n if (typeof wire['inRange'] !== 'boolean') return entryRejected('inRange is not a boolean');\n for (const key of OPTIONAL_POSITION_STRINGS) {\n if (wire[key] !== undefined && typeof wire[key] !== 'string') {\n return entryRejected(`${key} is not a string`);\n }\n }\n const currentTick = wire['currentTick'];\n if (\n currentTick !== undefined &&\n (typeof currentTick !== 'number' || !Number.isFinite(currentTick))\n ) {\n return entryRejected('currentTick is not a number');\n }\n const pool = wire['poolRef'] ?? wire['pool'] ?? '';\n if (typeof pool !== 'string') return entryRejected('pool is not a string');\n const optional = Object.fromEntries(\n [...OPTIONAL_POSITION_STRINGS, 'currentTick' as const].flatMap((key) =>\n wire[key] === undefined ? [] : [[key, wire[key]]],\n ),\n );\n return entryOk({\n token0Symbol: wire['token0Symbol'] as string,\n token1Symbol: wire['token1Symbol'] as string,\n fee: wire['fee'] as number,\n tickLower: wire['tickLower'] as number,\n tickUpper: wire['tickUpper'] as number,\n liquidity: wire['liquidity'] as string,\n amount0: wire['amount0'] as string,\n amount1: wire['amount1'] as string,\n inRange: wire['inRange'],\n pool,\n owner: wire['owner'] as string,\n ...optional,\n });\n}\n\n/** The position inside a `/position` answer, or `INVALID_CHAIN_RESPONSE` when it is not one. */\nfunction readPositionBody(data: unknown): Position {\n const parsed = parsePosition(data);\n if (parsed.ok) return parsed.value;\n throw new GSwapSDKError(\n 'INVALID_POSITION_RESPONSE',\n { reason: parsed.reason },\n { body: data, write: false },\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"positions.js","names":["_defineProperty","BigNumber","identityOf","dto","Positions","gateway","symbols","signer","walletAddress","userRef","HttpClient","resolveUniqueKeyPrefix","options","response","owner","readEntries","parsePosition","args","signal","readPositionBody","position","error","isGSwapError","GSwapSDKError","rawTokenOf","pair","ticks","validateNumericAmount","validateFee","assertTickRange","base","buildAddLiquidityDto","assertCanonicalV2Dto","minPrice","maxPrice","spacing","tickLower","alignTickDown","tickFromPrice","tickUpper","alignTickUp","canonical0","canonical1","buildRemoveLiquidityDto","isFullClose","buildCollectPositionFeesDto","hasPrice","tokenA","tokenB","flipped","token0","token1","sourcePriceInput","sourcePrice","canonicalPrice","shared","buildCreatePoolDto","transaction","signed","signPreSend","method","submitOptions","positionConfirmation","confirmation","fee","baseline","current","identity","kind","currentFees","endpoint","params","TICK_SPACING_BY_FEE","ALLOWED_FEE_TIERS_TEXT","value","parameterName","supplied","createUniqueKey","assertUniqueKey","resolvePreSend","a","b","lookupRef","ref","compositeKeyOf","resolved","symbolOverride","suppliedClassKey","parseTokenClassKey","classKey","isProposableTradingSymbol","REQUIRED_POSITION_STRINGS","REQUIRED_POSITION_NUMBERS","OPTIONAL_POSITION_STRINGS","wire","asEntryRecord","entryRejected","key","number","\"inRange\"","currentTick","\"currentTick\"","pool","\"poolRef\"","\"pool\"","optional","entryOk","\"token0Symbol\"","\"token1Symbol\"","\"fee\"","\"tickLower\"","\"tickUpper\"","\"liquidity\"","\"amount0\"","\"amount1\"","\"owner\"","parsed","data"],"sources":["../../../src/classes/positions.ts"],"sourcesContent":["import {\n assertUniqueKey,\n compositeKeyOf,\n createUniqueKey,\n resolveUniqueKeyPrefix,\n signPreSend,\n type GalaChainSigner,\n type UniqueKeyOptions,\n type WireOptions,\n} from '@gala-chain/gala-core-sdk';\nimport BigNumber from 'bignumber.js';\nimport { ALLOWED_FEE_TIERS_TEXT } from './gswap_error_catalog.js';\nimport { GSwapSDKError, isGSwapError } from './gswap_sdk_error.js';\nimport type { ChainGateway, ChainSubmitOptions } from './gateway.js';\nimport type { PositionConfirmationResult, SubmittedTransaction } from './submitted_transaction.js';\nimport { HttpClient } from './http_client.js';\nimport { rawTokenOf, type Symbols, type TokenResolver } from './symbols.js';\nimport type { NumericAmount, PriceIn } from '../types/amounts.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { TICK_SPACING_BY_FEE } from '../types/fees.js';\nimport type {\n AddLiquidityDTO,\n CollectPositionFeesDTO,\n CreatePoolDTO,\n RemoveLiquidityDTO,\n} from '../types/v2_dtos.js';\nimport type {\n AddLiquidityEstimate,\n Position,\n RemoveLiquidityEstimate,\n} from '../types/v2_results.js';\nimport {\n asEntryRecord,\n entryOk,\n entryRejected,\n readEntries,\n type EntryParse,\n type InvalidEntryHandler,\n} from '../utils/lenient.js';\nimport { type TokenRef, parseTokenClassKey } from '../utils/ordering.js';\nimport { resolvePreSend } from '../utils/resolve_pre_send.js';\nimport {\n isProposableTradingSymbol,\n validateFee,\n userRef,\n validateNumericAmount,\n} from '../utils/validation.js';\nimport { tickFromPrice } from '../utils/tick_math.js';\nimport { alignTickDown, alignTickUp, assertTickRange } from '../utils/ticks.js';\nimport {\n assertCanonicalV2Dto,\n buildAddLiquidityDto,\n buildCollectPositionFeesDto,\n buildCreatePoolDto,\n buildRemoveLiquidityDto,\n} from '../utils/dto_builders.js';\n\ntype PositionGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {\n submit: (\n method: string,\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<SubmittedTransaction<Position | null>>;\n requestTimeoutMs?: number | undefined;\n wire?: WireOptions | undefined;\n};\ntype PositionSymbols = TokenResolver & Pick<Symbols, 'orderPair'> & { invalidate?: () => void };\n\n/** Options of {@link Positions}: the `uniqueKey` prefix and a handler for skipped list rows. */\nexport interface PositionsOptions extends UniqueKeyOptions {\n /** Told about every position row of a list that was skipped as unusable. */\n onInvalidEntry?: InvalidEntryHandler | undefined;\n}\n\n/** A write's optional attempt identity. */\ninterface UniqueKeyArg {\n /**\n * The attempt's `uniqueKey` (1-128 characters of `A-Za-z0-9._:-`). Default: a fresh\n * `<uniqueKeyPrefix><uuid>`. Supply one to know the key before signing, or to retry the SAME\n * attempt after a lost response; never reuse it for another write.\n */\n uniqueKey?: string | undefined;\n}\n\n/** Arguments of {@link Positions.addLiquidityByTicks} and {@link Positions.buildAddLiquidity}. */\nexport interface AddLiquidityArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount: NumericAmount;\n /** Whether `amount` is of `token0` as the caller passed it (not of the canonical token0). */\n amountIsToken0: boolean;\n}\n\n/** Arguments of {@link Positions.removeLiquidity} and {@link Positions.buildRemoveLiquidity}. */\nexport interface RemoveLiquidityArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n /** Withdraw this much of the caller's `token0`; give at most one of `amount0` / `amount1`. */\n amount0?: NumericAmount | undefined;\n amount1?: NumericAmount | undefined;\n}\n\n/** Arguments of {@link Positions.collectPositionFees} and {@link Positions.buildCollectPositionFees}. */\nexport interface CollectPositionFeesArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n}\n\n/** Arguments of {@link Positions.createPool} and {@link Positions.buildCreatePool}. */\nexport interface CreatePoolArgs extends UniqueKeyArg {\n token0: TokenRef;\n token1: TokenRef;\n token0Symbol?: string | undefined;\n token1Symbol?: string | undefined;\n fee: FEE_TIER;\n startingPrice?: NumericAmount | undefined;\n startingSqrtPrice?: NumericAmount | undefined;\n /** Optional pool display name, sent as the DTO's `name`; omitted when undefined or empty. */\n name?: string | undefined;\n isPrivate?: boolean | undefined;\n privateAccess?: string[] | undefined;\n}\n\n/** The pool position a liquidity DTO names, as its confirmation needs it. */\nfunction identityOf(\n dto: Pick<CollectPositionFeesDTO, 'token0' | 'token1' | 'fee' | 'tickLower' | 'tickUpper'>,\n): PositionIdentity {\n return {\n token0: dto.token0,\n token1: dto.token1,\n fee: dto.fee,\n tickLower: dto.tickLower,\n tickUpper: dto.tickUpper,\n };\n}\n\n/**\n * The outcome of {@link Positions.readPosition}. Only `not_found` is chain-confirmed absence (the\n * backend answers HTTP 404 only when the chain itself found no such position); `unknown` is \"no\n * evidence either way\" — a transport failure, a gateway timeout, any other error status or an\n * answer that is not a position — and must never be read as a removal.\n */\nexport type PositionRead =\n | { kind: 'found'; data: Position }\n | { kind: 'not_found' }\n | { kind: 'unknown'; error: GSwapSDKError };\n\ninterface BackendEnvelope<TData> {\n data: TData;\n}\n\ninterface AddLiquidityEstimateWire {\n amount0: string;\n amount1: string;\n liquidity: string;\n token0Symbol: string;\n token1Symbol: string;\n tickLower: number;\n tickUpper: number;\n amountIsCanonicalToken0: boolean;\n}\n\ninterface RemoveLiquidityEstimateWire {\n amount0: string;\n amount1: string;\n}\n\ninterface ResolvedCreateToken {\n symbol: string;\n classKey: ReturnType<typeof parseTokenClassKey>;\n}\n\ninterface PositionIdentity {\n token0: string;\n token1: string;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n}\n\n/** Tells `submit()` how to prove a write's own effect for `SubmittedTransaction.confirm()`. */\ntype PositionSubmitConfirmation =\n | { kind: 'add' | 'removePartial' | 'removeFull' | 'collect'; identity: PositionIdentity }\n | { kind: 'createPool'; token0: string; token1: string; fee: FEE_TIER };\n\n/**\n * Manages current-contract concentrated-liquidity positions.\n *\n * @example\n * ```typescript\n * const positions = gSwap.positions;\n * const mine = await positions.getUserPositions('client|012345678901234567890123');\n * console.log(mine.length);\n * ```\n */\nexport class Positions {\n constructor(\n private readonly gateway: PositionGateway,\n private readonly symbols: PositionSymbols,\n private readonly signer?: GalaChainSigner,\n walletAddress?: string,\n options: PositionsOptions = {},\n ) {\n this.walletAddress =\n walletAddress === undefined ? undefined : userRef(walletAddress, 'walletAddress');\n this.http = new HttpClient(\n gateway.httpRequestor,\n gateway.requestTimeoutMs ?? 30_000,\n gateway.wire,\n );\n this.uniqueKeyPrefix = resolveUniqueKeyPrefix(options.uniqueKeyPrefix);\n this.onInvalidEntry = options.onInvalidEntry;\n }\n\n /** The signing wallet in the gateway's spelling (`eth|<EIP-55>` or `client|<id>`). */\n private readonly walletAddress: string | undefined;\n private readonly http: HttpClient;\n private readonly uniqueKeyPrefix: string;\n private readonly onInvalidEntry: InvalidEntryHandler | undefined;\n\n /**\n * Gets all current-contract positions owned by an address.\n *\n * @param owner - GalaChain owner identity.\n * @returns Enriched positions from the v2 trade backend, token images included. A row that is\n * not a usable position is skipped and reported to `onInvalidEntry`.\n * @example\n * ```typescript\n * const positions = await gSwap.positions.getUserPositions('client|012345678901234567890123');\n * ```\n */\n async getUserPositions(owner: string): Promise<Position[]> {\n const response = await this.get<unknown>('/positions', { user: userRef(owner, 'owner') });\n return readEntries('positions', response.data, parsePosition, this.onInvalidEntry);\n }\n\n /**\n * Gets one position, normalizing a caller-supplied reversed pair to canonical symbol order.\n * Reversed pairs also invert the price axis, so `[lower, upper]` becomes `[-upper, -lower]`.\n *\n * @param args - Pair, owner, fee, and position tick range.\n * @returns The position, or `null` when the backend returns 404.\n * @example\n * ```typescript\n * const position = await gSwap.positions.getPosition({\n * token0: 'GALA', token1: 'GUSDC', owner: 'client|012345678901234567890123',\n * fee: 3000, tickLower: -19200, tickUpper: 12000,\n * });\n * ```\n */\n async getPosition(\n args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n owner: string;\n tickLower: number;\n tickUpper: number;\n },\n signal?: AbortSignal,\n ): Promise<Position | null> {\n const response = await this.getNullable<unknown>(\n '/position',\n await this.positionParams(args),\n signal,\n );\n return response === null ? null : readPositionBody(response.data);\n }\n\n /**\n * Reads one position and classifies the outcome instead of throwing: `found` with the position\n * (fees included), `not_found` (the backend's HTTP 404, which it sends only when the chain\n * itself has no such position) or `unknown` (any other failure, carried as `error`). Use it\n * to confirm a write: `unknown` is \"no evidence either way\", never a confirmed absence.\n *\n * Only the caller's own abort rethrows. With a pass-through resolver ({@link CanonicalSymbols})\n * the pair and ticks go to the backend exactly as given and the backend orients them.\n *\n * @example\n * ```typescript\n * const read = await gSwap.positions.readPosition({\n * token0: 'GALA', token1: 'GUSDC', owner: 'client|012345678901234567890123',\n * fee: 3000, tickLower: -19200, tickUpper: 12000,\n * });\n * if (read.kind === 'found') console.log(read.data.fees0);\n * ```\n */\n async readPosition(\n args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n owner: string;\n tickLower: number;\n tickUpper: number;\n },\n signal?: AbortSignal,\n ): Promise<PositionRead> {\n try {\n const position = await this.getPosition(args, signal);\n return position === null ? { kind: 'not_found' } : { kind: 'found', data: position };\n } catch (error: unknown) {\n if (signal?.aborted === true) throw error;\n return {\n kind: 'unknown',\n error: isGSwapError(error)\n ? error\n : new GSwapSDKError(\n 'REQUEST_FAILED',\n { operation: 'position' },\n { cause: error, write: false },\n ),\n };\n }\n }\n\n /**\n * The `/position` query: canonical symbols and canonical ticks after a client-side flip, or,\n * for a pass-through resolver, the caller's references and ticks untouched.\n */\n private async positionParams(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n owner: string;\n tickLower: number;\n tickUpper: number;\n }): Promise<Record<string, string>> {\n // The backend matches `owner` against the chain's position owner with strict equality, so\n // only the chain's own spelling (`eth|<EIP-55>`) finds a position.\n const owner = userRef(args.owner, 'owner');\n if (this.symbols.passthrough === true) {\n return {\n token0: rawTokenOf(args.token0),\n token1: rawTokenOf(args.token1),\n fee: `${args.fee}`,\n owner,\n tickLower: `${args.tickLower}`,\n tickUpper: `${args.tickUpper}`,\n };\n }\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n return {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: `${args.fee}`,\n owner,\n tickLower: `${ticks.tickLower}`,\n tickUpper: `${ticks.tickUpper}`,\n };\n }\n\n /**\n * Estimates the other token amount and resulting liquidity for a deposit.\n *\n * @param args - Pair, tick range, deposit amount, and the amount's caller-side token index.\n * @returns Backend liquidity estimate.\n * @example\n * ```typescript\n * const estimate = await gSwap.positions.estimateAddLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,\n * });\n * ```\n */\n async estimateAddLiquidity(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount: NumericAmount;\n amountIsToken0: boolean;\n }): Promise<AddLiquidityEstimate> {\n validateNumericAmount(args.amount, 'amount');\n const response = await this.get<AddLiquidityEstimateWire>('/add-liq-estimate', {\n token0: rawTokenOf(args.token0),\n token1: rawTokenOf(args.token1),\n fee: `${args.fee}`,\n tickLower: `${args.tickLower}`,\n tickUpper: `${args.tickUpper}`,\n amount: new BigNumber(args.amount).toFixed(),\n amountIsToken0: String(args.amountIsToken0),\n });\n return response.data;\n }\n\n /**\n * Estimates token amounts released by burning liquidity.\n *\n * @param args - Pair, tick range, fee tier, and liquidity quantity.\n * @returns Estimated token0 and token1 quantities.\n * @example\n * ```typescript\n * const estimate = await gSwap.positions.estimateRemoveLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, liquidity: '1000',\n * });\n * ```\n */\n async estimateRemoveLiquidity(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n liquidity: NumericAmount;\n }): Promise<RemoveLiquidityEstimate> {\n validateNumericAmount(args.liquidity, 'liquidity');\n const response = await this.get<RemoveLiquidityEstimateWire>('/remove-liq-estimate', {\n token0: rawTokenOf(args.token0),\n token1: rawTokenOf(args.token1),\n fee: `${args.fee}`,\n tickLower: `${args.tickLower}`,\n tickUpper: `${args.tickUpper}`,\n liquidity: new BigNumber(args.liquidity).toFixed(),\n });\n return response.data;\n }\n\n /**\n * Adds liquidity using an explicit tick range. Exactly one canonical deposit field is emitted.\n *\n * @param args - Pair, fee, range, deposit amount, and caller-side token index.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.addLiquidityByTicks({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,\n * });\n * await tx.confirm();\n * ```\n */\n async addLiquidityByTicks(args: AddLiquidityArgs) {\n return this.submitAddLiquidity(await this.buildAddLiquidity(args));\n }\n\n /**\n * Builds the AddLiquidity DTO that {@link addLiquidityByTicks} would sign, without signing or\n * sending it: to show in an approval popup, or to sign elsewhere. Submit exactly this DTO with\n * {@link submitAddLiquidity}. The pure counterpart, with canonical inputs and no resolution,\n * is `buildAddLiquidityDto`.\n *\n * @example\n * ```typescript\n * const dto = await gSwap.positions.buildAddLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,\n * });\n * ```\n */\n async buildAddLiquidity(args: AddLiquidityArgs): Promise<AddLiquidityDTO> {\n validateFee(args.fee);\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n // Caller-facing checks first, so a refusal names the caller's own argument (`amount`).\n assertTickRange(ticks.tickLower, ticks.tickUpper, args.fee);\n validateNumericAmount(args.amount, 'amount');\n const base = {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n };\n return pair.flipped !== args.amountIsToken0\n ? buildAddLiquidityDto({ ...base, depositQuantityToken0: args.amount })\n : buildAddLiquidityDto({ ...base, depositQuantityToken1: args.amount });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildAddLiquidity} or `buildAddLiquidityDto`; it must\n * be exactly what the builder produces. The returned transaction confirms by proving the\n * position's liquidity grew.\n */\n async submitAddLiquidity(dto: AddLiquidityDTO) {\n assertCanonicalV2Dto('AddLiquidity', dto);\n return this.submit('AddLiquidity', dto, { kind: 'add', identity: identityOf(dto) });\n }\n\n /**\n * Adds liquidity from prices, flooring the lower tick and ceiling the upper tick to fee spacing.\n * The resulting range is therefore no narrower than the requested price interval.\n *\n * @param args - Pair, fee, price range, deposit amount, and caller-side token index.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.addLiquidityByPrice({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * minPrice: '0.14', maxPrice: '0.16', amount: '100', amountIsToken0: true,\n * });\n * ```\n */\n async addLiquidityByPrice(args: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n minPrice: PriceIn;\n maxPrice: PriceIn;\n amount: NumericAmount;\n amountIsToken0: boolean;\n /** The attempt's `uniqueKey`; default a fresh one (see {@link AddLiquidityArgs.uniqueKey}). */\n uniqueKey?: string | undefined;\n }) {\n validateFee(args.fee);\n this.rejectNumber(args.minPrice, 'minPrice');\n this.rejectNumber(args.maxPrice, 'maxPrice');\n const minPrice = new BigNumber(args.minPrice);\n const maxPrice = new BigNumber(args.maxPrice);\n if (\n !minPrice.isFinite() ||\n !maxPrice.isFinite() ||\n minPrice.isLessThanOrEqualTo(0) ||\n maxPrice.isLessThanOrEqualTo(0)\n ) {\n throw new GSwapSDKError('INVALID_PRICE_BOUNDS', {\n minPrice: String(args.minPrice),\n maxPrice: String(args.maxPrice),\n });\n }\n if (minPrice.isGreaterThan(maxPrice)) {\n throw new GSwapSDKError('PRICE_BOUNDS_ORDER', {\n minPrice: String(args.minPrice),\n maxPrice: String(args.maxPrice),\n });\n }\n const spacing = this.tickSpacing(args.fee);\n const tickLower = alignTickDown(tickFromPrice(minPrice), spacing);\n const tickUpper = alignTickUp(tickFromPrice(maxPrice), spacing);\n return this.addLiquidityByTicks({\n token0: args.token0,\n token1: args.token1,\n fee: args.fee,\n tickLower,\n tickUpper,\n amount: args.amount,\n amountIsToken0: args.amountIsToken0,\n uniqueKey: args.uniqueKey,\n });\n }\n\n /**\n * Removes liquidity by withdrawing at most one canonical token quantity.\n * Omitting both amounts closes the position and sweeps all accrued fees.\n *\n * @param args - Pair, fee, range, and optional caller-side withdrawal amount.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.removeLiquidity({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000,\n * });\n * ```\n */\n async removeLiquidity(args: RemoveLiquidityArgs) {\n return this.submitRemoveLiquidity(await this.buildRemoveLiquidity(args));\n }\n\n /**\n * Builds the RemoveLiquidity DTO that {@link removeLiquidity} would sign, without signing or\n * sending it. Submit exactly this DTO with {@link submitRemoveLiquidity}. The pure counterpart\n * is `buildRemoveLiquidityDto`.\n */\n async buildRemoveLiquidity(args: RemoveLiquidityArgs): Promise<RemoveLiquidityDTO> {\n validateFee(args.fee);\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n assertTickRange(ticks.tickLower, ticks.tickUpper, args.fee);\n if (args.amount0 !== undefined && args.amount1 !== undefined) {\n throw new GSwapSDKError('AT_MOST_ONE_OF_ALLOWED', { first: 'amount0', second: 'amount1' });\n }\n if (args.amount0 !== undefined) validateNumericAmount(args.amount0, 'amount0');\n if (args.amount1 !== undefined) validateNumericAmount(args.amount1, 'amount1');\n // The caller's amount0 / amount1 follow the caller's pair; the DTO's follow the canonical one.\n const [canonical0, canonical1] = pair.flipped\n ? [args.amount1, args.amount0]\n : [args.amount0, args.amount1];\n return buildRemoveLiquidityDto({\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n withdrawalQuantityToken0: canonical0,\n withdrawalQuantityToken1: canonical1,\n });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildRemoveLiquidity} or `buildRemoveLiquidityDto`;\n * it must be exactly what the builder produces. A DTO with no withdrawal quantity closes the\n * position, and the returned transaction then confirms by proving the position is gone.\n */\n async submitRemoveLiquidity(dto: RemoveLiquidityDTO) {\n assertCanonicalV2Dto('RemoveLiquidity', dto);\n const isFullClose =\n dto.withdrawalQuantityToken0 === undefined && dto.withdrawalQuantityToken1 === undefined;\n return this.submit('RemoveLiquidity', dto, {\n kind: isFullClose ? 'removeFull' : 'removePartial',\n identity: identityOf(dto),\n });\n }\n\n /**\n * Collects all accrued fees for a position; the contract does not support partial collection.\n *\n * @param args - Pair, fee, and tick range identifying the position.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.collectPositionFees({\n * token0: 'GALA', token1: 'GUSDC', fee: 3000,\n * tickLower: -19200, tickUpper: 12000,\n * });\n * ```\n */\n async collectPositionFees(args: CollectPositionFeesArgs) {\n return this.submitCollectPositionFees(await this.buildCollectPositionFees(args));\n }\n\n /**\n * Builds the CollectPositionFees DTO that {@link collectPositionFees} would sign, without\n * signing or sending it. Submit exactly this DTO with {@link submitCollectPositionFees}. The\n * pure counterpart is `buildCollectPositionFeesDto`.\n */\n async buildCollectPositionFees(args: CollectPositionFeesArgs): Promise<CollectPositionFeesDTO> {\n validateFee(args.fee);\n const pair = await this.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n assertTickRange(ticks.tickLower, ticks.tickUpper, args.fee);\n return buildCollectPositionFeesDto({\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildCollectPositionFees} or\n * `buildCollectPositionFeesDto`; it must be exactly what the builder produces.\n */\n async submitCollectPositionFees(dto: CollectPositionFeesDTO) {\n assertCanonicalV2Dto('CollectPositionFees', dto);\n return this.submit('CollectPositionFees', dto, { kind: 'collect', identity: identityOf(dto) });\n }\n\n /**\n * Creates a pool, resolving registered trading symbols.\n * Reversed symbol order inverts the supplied starting price or square-root price.\n *\n * A token class key carries no symbol, so for a token being proposed into the v2\n * trading-symbol registry for the first time (no existing pool has registered it yet) the\n * caller MUST pass `token0Symbol`/`token1Symbol` (the token class's symbol, from the token\n * list or FetchTokenClasses). The SDK never derives a symbol from the key, and throws a\n * TOKEN_SYMBOL_NOT_REGISTERED error when an unregistered token has none. For an already-registered token a\n * supplied symbol must match the registered one.\n *\n * @param args - Token class keys or references, fee, exactly one starting price field, and privacy options.\n * @returns The synchronously submitted transaction.\n * @example\n * ```typescript\n * const tx = await gSwap.positions.createPool({\n * token0: 'GALA|Unit|none|none', token1: 'GUSDC|Unit|none|none', fee: 3000,\n * startingPrice: '0.15',\n * });\n * ```\n */\n async createPool(args: CreatePoolArgs) {\n return this.submitCreatePool(await this.buildCreatePool(args));\n }\n\n /**\n * Builds the CreatePool DTO that {@link createPool} would sign, without signing or sending it:\n * symbols resolved or proposed, the pair put in canonical order and the price inverted when it\n * was reversed. Submit exactly this DTO with {@link submitCreatePool}. The pure counterpart,\n * with canonical inputs, is `buildCreatePoolDto`.\n */\n async buildCreatePool(args: CreatePoolArgs): Promise<CreatePoolDTO> {\n const hasPrice = args.startingPrice !== undefined;\n const hasSqrtPrice = args.startingSqrtPrice !== undefined;\n if (hasPrice === hasSqrtPrice) {\n throw new GSwapSDKError('EXACTLY_ONE_OF_REQUIRED', {\n first: 'startingPrice',\n second: 'startingSqrtPrice',\n });\n }\n validateFee(args.fee);\n const [tokenA, tokenB] = await Promise.all([\n this.resolveCreateToken(args.token0, args.token0Symbol),\n this.resolveCreateToken(args.token1, args.token1Symbol),\n ]);\n const flipped = tokenA.symbol > tokenB.symbol;\n const [token0, token1] = flipped ? [tokenB, tokenA] : [tokenA, tokenB];\n const sourcePriceInput = hasPrice\n ? (args.startingPrice as NumericAmount)\n : (args.startingSqrtPrice as NumericAmount);\n this.rejectNumber(sourcePriceInput, hasPrice ? 'startingPrice' : 'startingSqrtPrice');\n const sourcePrice = new BigNumber(sourcePriceInput);\n if (!sourcePrice.isFinite() || sourcePrice.isLessThanOrEqualTo(0)) {\n throw new GSwapSDKError('INVALID_STARTING_PRICE', { value: String(sourcePriceInput) });\n }\n const canonicalPrice = flipped ? new BigNumber(1).dividedBy(sourcePrice) : sourcePrice;\n const shared = {\n token0Key: token0.classKey,\n token1Key: token1.classKey,\n token0Symbol: token0.symbol,\n token1Symbol: token1.symbol,\n fee: args.fee,\n uniqueKey: this.uniqueKeyFor(args.uniqueKey),\n name: args.name,\n isPrivate: args.isPrivate,\n privateAccess: args.privateAccess,\n };\n return hasPrice\n ? buildCreatePoolDto({ ...shared, startingPrice: canonicalPrice })\n : buildCreatePoolDto({ ...shared, startingSqrtPrice: canonicalPrice });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildCreatePool} or `buildCreatePoolDto`; it must be\n * exactly what the builder produces. The returned transaction confirms by the pool existing, and\n * the cached symbol registry is dropped, since the pool may have registered new symbols.\n */\n async submitCreatePool(dto: CreatePoolDTO) {\n assertCanonicalV2Dto('CreatePool', dto);\n const transaction = await this.submit('CreatePool', dto, {\n kind: 'createPool',\n token0: dto.token0Symbol,\n token1: dto.token1Symbol,\n fee: dto.fee,\n });\n this.symbols.invalidate?.();\n return transaction;\n }\n\n private async submit(\n method: string,\n dto: Record<string, unknown>,\n confirmation?: PositionSubmitConfirmation,\n ) {\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n const signed = await signPreSend(this.signer, method, dto);\n const submitOptions =\n this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress };\n const owner = this.walletAddress;\n const positionConfirmation = this.buildPositionConfirmation(confirmation, owner);\n const options: ChainSubmitOptions = {\n ...submitOptions,\n ...(positionConfirmation === undefined ? {} : { positionConfirmation }),\n };\n return this.gateway.submit(method, signed, options);\n }\n\n /**\n * Builds a confirmation closure that proves the write's own effect, not just that a\n * position row exists (true before most of these writes run too, for any operation on a\n * pre-existing position — existence alone would false-confirm before the write executes,\n * and would never confirm a full close, whose whole point is that the position stops\n * existing).\n *\n * The \"before\" state is captured lazily, on the confirmation closure's own first poll —\n * not eagerly here in `submit()` — so confirming a write never adds an extra round-trip to\n * the write itself; the cost of establishing the baseline is paid by `confirm()`, only if\n * and when the caller actually asks to confirm.\n */\n private buildPositionConfirmation(\n confirmation: PositionSubmitConfirmation | undefined,\n owner: string | undefined,\n ): ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined {\n if (confirmation === undefined) return undefined;\n\n if (confirmation.kind === 'createPool') {\n const { token0, token1, fee } = confirmation;\n return async (signal) => {\n const pool = await this.getNullable<unknown>(\n '/pool',\n { token0, token1, fee: `${fee}` },\n signal,\n );\n return pool === null ? { confirmed: false } : { confirmed: true, position: null };\n };\n }\n\n if (owner === undefined) return undefined;\n const { kind, identity } = confirmation;\n let baseline: { liquidity: BigNumber; fees: BigNumber } | undefined;\n\n return async (signal) => {\n const current = await this.getPosition({ ...identity, owner }, signal);\n\n if (baseline === undefined) {\n // First poll only establishes the baseline to compare future polls against — it can\n // never itself be the confirmed outcome (nothing has been observed to change yet).\n baseline = {\n liquidity: new BigNumber(current?.liquidity ?? 0),\n fees: new BigNumber(current?.fees0 ?? 0).plus(new BigNumber(current?.fees1 ?? 0)),\n };\n // A full close starting from \"already gone\" (e.g. a retried confirm after the position\n // was already swept) is confirmed immediately rather than waiting for a change that\n // already happened.\n return kind === 'removeFull' && current === null\n ? { confirmed: true, position: null }\n : { confirmed: false };\n }\n\n switch (kind) {\n case 'add':\n return current !== null &&\n new BigNumber(current.liquidity).isGreaterThan(baseline.liquidity)\n ? { confirmed: true, position: current }\n : { confirmed: false };\n case 'removePartial':\n return current !== null && new BigNumber(current.liquidity).isLessThan(baseline.liquidity)\n ? { confirmed: true, position: current }\n : { confirmed: false };\n case 'removeFull':\n return current === null ? { confirmed: true, position: null } : { confirmed: false };\n case 'collect': {\n if (current === null) return { confirmed: false };\n const currentFees = new BigNumber(current.fees0 ?? 0).plus(\n new BigNumber(current.fees1 ?? 0),\n );\n if (currentFees.isLessThan(baseline.fees)) return { confirmed: true, position: current };\n // Nothing to sweep in the first place — a legitimate no-op collect never moves\n // fees, so \"still zero\" is the confirmed outcome, not an unconfirmed one.\n if (baseline.fees.isZero() && currentFees.isZero())\n return { confirmed: true, position: current };\n return { confirmed: false };\n }\n }\n };\n }\n\n private async get<TData>(\n endpoint: string,\n params: Record<string, string>,\n signal?: AbortSignal,\n ): Promise<BackendEnvelope<TData>> {\n return this.http.sendGetRequest<BackendEnvelope<TData>>(\n this.gateway.dexBackendBaseUrl,\n '/v2/trade',\n endpoint,\n params,\n signal === undefined ? undefined : { signal },\n );\n }\n\n private async getNullable<TData>(\n endpoint: string,\n params: Record<string, string>,\n signal?: AbortSignal,\n ): Promise<BackendEnvelope<TData> | null> {\n try {\n return await this.get<TData>(endpoint, params, signal);\n } catch (error: unknown) {\n if (this.isNotFound(error)) return null;\n throw error;\n }\n }\n\n private isNotFound(error: unknown): boolean {\n return isGSwapError(error) && error.status === 404;\n }\n\n private canonicalTicks(tickLower: number, tickUpper: number, flipped: boolean) {\n return flipped ? { tickLower: -tickUpper, tickUpper: -tickLower } : { tickLower, tickUpper };\n }\n\n private tickSpacing(fee: number): number {\n const spacing = (TICK_SPACING_BY_FEE as Record<number, number>)[fee];\n if (spacing === undefined) {\n throw new GSwapSDKError('INVALID_FEE', {\n field: 'fee',\n value: fee,\n allowed: ALLOWED_FEE_TIERS_TEXT,\n });\n }\n return spacing;\n }\n\n private rejectNumber(value: unknown, parameterName: string): void {\n if (typeof value === 'number') {\n throw new GSwapSDKError('AMOUNT_IS_JS_NUMBER', { field: parameterName });\n }\n }\n\n /** The caller's `uniqueKey` (validated), else a fresh one. */\n private uniqueKeyFor(supplied: string | undefined): string {\n if (supplied === undefined) return createUniqueKey(this.uniqueKeyPrefix);\n assertUniqueKey(supplied);\n return supplied;\n }\n\n /**\n * The pair in canonical order. A resolver failure that is not an SDK error (an app's own\n * resolver, an app requestor's rejection during the registry read) is `TOKEN_RESOLUTION_FAILED`.\n */\n private orderPair(a: TokenRef, b: TokenRef) {\n return resolvePreSend(`${rawTokenOf(a)}/${rawTokenOf(b)}`, () => this.symbols.orderPair(a, b));\n }\n\n private async resolveCreateToken(\n ref: TokenRef,\n symbolOverride?: string,\n ): Promise<ResolvedCreateToken> {\n try {\n const lookupRef = typeof ref === 'object' ? compositeKeyOf(ref) : ref;\n const resolved = await resolvePreSend(rawTokenOf(ref), () => this.symbols.resolve(lookupRef));\n if (\n symbolOverride !== undefined &&\n symbolOverride !== '' &&\n symbolOverride !== resolved.symbol\n ) {\n throw new GSwapSDKError('SYMBOL_DISAGREES_WITH_REGISTRY', {\n token: rawTokenOf(ref),\n suppliedSymbol: symbolOverride,\n registeredSymbol: resolved.symbol,\n });\n }\n const suppliedClassKey = this.tryParseClassKey(ref);\n if (suppliedClassKey === undefined && resolved.collection === '') {\n // An offline resolver knows a bare symbol but not its class key; a pool needs the key.\n throw new GSwapSDKError('CREATE_POOL_NEEDS_CLASS_KEY', { token: rawTokenOf(ref) });\n }\n return {\n symbol: resolved.symbol,\n classKey:\n suppliedClassKey ??\n parseTokenClassKey({\n collection: resolved.collection,\n category: resolved.category,\n type: resolved.type,\n additionalKey: resolved.additionalKey,\n }),\n };\n } catch (error: unknown) {\n if (!isGSwapError(error, 'UNKNOWN_TOKEN')) {\n throw error;\n }\n let classKey: ReturnType<typeof parseTokenClassKey>;\n try {\n classKey = parseTokenClassKey(ref);\n } catch {\n throw error;\n }\n // First-time registration: a class key carries NO symbol (collection and symbol disagree\n // for many tokens, launchpad tokens all share collection `Token`, and some collections\n // contain `$`), so the symbol to propose must be supplied by the caller from the token\n // class / registry. Never derive it from the key.\n if (symbolOverride === undefined || symbolOverride === '') {\n throw new GSwapSDKError('TOKEN_SYMBOL_NOT_REGISTERED', { token: rawTokenOf(ref) });\n }\n if (!isProposableTradingSymbol(symbolOverride)) {\n throw new GSwapSDKError('INVALID_TRADING_SYMBOL', { symbol: symbolOverride });\n }\n return { symbol: symbolOverride, classKey };\n }\n }\n\n private tryParseClassKey(ref: TokenRef): ReturnType<typeof parseTokenClassKey> | undefined {\n try {\n return parseTokenClassKey(ref);\n } catch {\n return undefined;\n }\n }\n}\n\nconst REQUIRED_POSITION_STRINGS = [\n 'token0Symbol',\n 'token1Symbol',\n 'owner',\n 'liquidity',\n 'amount0',\n 'amount1',\n] as const;\nconst REQUIRED_POSITION_NUMBERS = ['fee', 'tickLower', 'tickUpper'] as const;\nconst OPTIONAL_POSITION_STRINGS = [\n 'token0CompositeKey',\n 'token1CompositeKey',\n 'token0Image',\n 'token1Image',\n 'sqrtPrice',\n 'fees0',\n 'fees1',\n] as const;\n\n/**\n * Reads one position row of `/positions` or `/position`: the pair, owner, range, liquidity and\n * amounts must be usable; the composite keys, token images, current tick and price, and the\n * escrowed fees are carried when present. `pool` is the pool reference (`poolRef` wins over\n * `pool`; `''` when the row names neither).\n */\nfunction parsePosition(value: unknown): EntryParse<Position> {\n const wire = asEntryRecord(value);\n if (wire === undefined) return entryRejected('the row is not an object');\n for (const key of REQUIRED_POSITION_STRINGS) {\n if (typeof wire[key] !== 'string') return entryRejected(`${key} is not a string`);\n }\n for (const key of REQUIRED_POSITION_NUMBERS) {\n const number = wire[key];\n if (typeof number !== 'number' || !Number.isFinite(number)) {\n return entryRejected(`${key} is not a number`);\n }\n }\n if (typeof wire['inRange'] !== 'boolean') return entryRejected('inRange is not a boolean');\n for (const key of OPTIONAL_POSITION_STRINGS) {\n if (wire[key] !== undefined && typeof wire[key] !== 'string') {\n return entryRejected(`${key} is not a string`);\n }\n }\n const currentTick = wire['currentTick'];\n if (\n currentTick !== undefined &&\n (typeof currentTick !== 'number' || !Number.isFinite(currentTick))\n ) {\n return entryRejected('currentTick is not a number');\n }\n const pool = wire['poolRef'] ?? wire['pool'] ?? '';\n if (typeof pool !== 'string') return entryRejected('pool is not a string');\n const optional = Object.fromEntries(\n [...OPTIONAL_POSITION_STRINGS, 'currentTick' as const].flatMap((key) =>\n wire[key] === undefined ? [] : [[key, wire[key]]],\n ),\n );\n return entryOk({\n token0Symbol: wire['token0Symbol'] as string,\n token1Symbol: wire['token1Symbol'] as string,\n fee: wire['fee'] as number,\n tickLower: wire['tickLower'] as number,\n tickUpper: wire['tickUpper'] as number,\n liquidity: wire['liquidity'] as string,\n amount0: wire['amount0'] as string,\n amount1: wire['amount1'] as string,\n inRange: wire['inRange'],\n pool,\n owner: wire['owner'] as string,\n ...optional,\n });\n}\n\n/** The position inside a `/position` answer, or `INVALID_CHAIN_RESPONSE` when it is not one. */\nfunction readPositionBody(data: unknown): Position {\n const parsed = parsePosition(data);\n if (parsed.ok) return parsed.value;\n throw new GSwapSDKError(\n 'INVALID_POSITION_RESPONSE',\n { reason: parsed.reason },\n { body: data, write: false },\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e from"../_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/defineProperty.js";import{GSwapSDKError as t}from"./gswap_sdk_error.js";import{assertCanonicalPair as n,validateFee as r}from"../utils/validation.js";import{shadowFailures as i}from"../utils/shadow_errors.js";import{SubmittedTransaction as a}from"./submitted_transaction.js";import{orderSymbols as o,readOrderedSymbols as s}from"../utils/ordering.js";import{tradingSymbolOf as c}from"./symbols.js";import{assertCanonicalV2Dto as l,buildRequestTradeDto as u}from"../utils/dto_builders.js";import{readShadowSubmitOutcome as d}from"./shadow_submit.js";import{assertUniqueKey as f,createUniqueKey as p,resolveUniqueKeyPrefix as m,signPreSend as h}from"@gala-chain/gala-core-sdk";function g(e){r(e.fee),n(e.token0Symbol,e.token1Symbol);let[t,i]=e.tokenInIsToken0?[e.token0Symbol,e.token1Symbol]:[e.token1Symbol,e.token0Symbol];return{tokenIn:t,tokenOut:i,fee:e.fee,pool:{token0:e.token0Symbol,token1:e.token1Symbol}}}var _=class{constructor(t,n,r,i,a={}){this.gateway=t,this.symbols=n,this.signer=r,this.walletAddress=i,e(this,`uniqueKeyPrefix`,void 0),this.uniqueKeyPrefix=m(a.uniqueKeyPrefix)}async swap(e,t,n,r,i){return this.submitSwap(await this.buildSwap(e,t,n,r,i))}async swapShadow(e,t,n,r,a){return i(async()=>this.submitSwapShadow(await this.buildSwap(e,t,n,r,a)))}async buildSwap(e,t,n,i,a){r(n);let o=a?.uniqueKey??p(this.uniqueKeyPrefix);f(o);let s=await c(this.symbols,e),l=await c(this.symbols,t),d=this.orientPool(s,l,a?.pool);return u({token0:d.token0,token1:d.token1,fee:n,tokenInIsToken0:s===d.token0,uniqueKey:o,...i})}async submitSwap(e){let t=await this.signRequestTrade(e);return this.gateway.submit(`RequestTrade`,t,this.submitOptions())}async submitSwapShadow(e){return i(async()=>{let t=await this.signRequestTrade(e),n=await this.gateway.submitShadow(`RequestTrade`,t,this.submitOptions());return d(`RequestTrade`,t,n)})}submitOptions(){return this.walletAddress===void 0?{}:{walletAddress:this.walletAddress}}async signRequestTrade(e){if(l(`RequestTrade`,e),this.signer===void 0)throw t.noSignerError();return h(this.signer,`RequestTrade`,e)}orientPool(e,n,r){if(r===void 0)return s(o(e,n));if(!(e===r.token0&&n===r.token1||e===r.token1&&n===r.token0))throw new t(`POOL_MISMATCH`,{tokenIn:e,tokenOut:n,poolToken0:r.token0,poolToken1:r.token1});return{token0:r.token0,token1:r.token1}}async confirmSwap(e,t){return f(e),new a({method:`RequestTrade`,uniqueKey:e,transactionId:null,mode:`queued`,result:void 0,dexBackendBaseUrl:this.gateway.dexBackendBaseUrl,httpRequestor:this.gateway.httpRequestor,requestTimeoutMs:this.gateway.requestTimeoutMs,wire:this.gateway.wire}).confirm({initialDelayMs:0,...t})}};export{_ as Swaps,g as swapRouteFromQuote};
1
+ import e from"../_virtual/_@oxc-project_runtime@0.153.0/helpers/esm/defineProperty.js";import{GSwapSDKError as t}from"./gswap_sdk_error.js";import{assertCanonicalPair as n,userRef as r,validateFee as i}from"../utils/validation.js";import{shadowFailures as a}from"../utils/shadow_errors.js";import{SubmittedTransaction as o}from"./submitted_transaction.js";import{orderSymbols as s,readOrderedSymbols as c}from"../utils/ordering.js";import{tradingSymbolOf as l}from"./symbols.js";import{assertCanonicalV2Dto as u,buildRequestTradeDto as d}from"../utils/dto_builders.js";import{readShadowSubmitOutcome as f}from"./shadow_submit.js";import{assertUniqueKey as p,createUniqueKey as m,resolveUniqueKeyPrefix as h,signPreSend as g}from"@gala-chain/gala-core-sdk";function _(e){i(e.fee),n(e.token0Symbol,e.token1Symbol);let[t,r]=e.tokenInIsToken0?[e.token0Symbol,e.token1Symbol]:[e.token1Symbol,e.token0Symbol];return{tokenIn:t,tokenOut:r,fee:e.fee,pool:{token0:e.token0Symbol,token1:e.token1Symbol}}}var v=class{constructor(t,n,i,a,o={}){this.gateway=t,this.symbols=n,this.signer=i,e(this,`walletAddress`,void 0),e(this,`uniqueKeyPrefix`,void 0),this.walletAddress=a===void 0?void 0:r(a,`walletAddress`),this.uniqueKeyPrefix=h(o.uniqueKeyPrefix)}async swap(e,t,n,r,i){return this.submitSwap(await this.buildSwap(e,t,n,r,i))}async swapShadow(e,t,n,r,i){return a(async()=>this.submitSwapShadow(await this.buildSwap(e,t,n,r,i)))}async buildSwap(e,t,n,r,a){i(n);let o=a?.uniqueKey??m(this.uniqueKeyPrefix);p(o);let s=await l(this.symbols,e),c=await l(this.symbols,t),u=this.orientPool(s,c,a?.pool);return d({token0:u.token0,token1:u.token1,fee:n,tokenInIsToken0:s===u.token0,uniqueKey:o,...r})}async submitSwap(e){let t=await this.signRequestTrade(e);return this.gateway.submit(`RequestTrade`,t,this.submitOptions())}async submitSwapShadow(e){return a(async()=>{let t=await this.signRequestTrade(e),n=await this.gateway.submitShadow(`RequestTrade`,t,this.submitOptions());return f(`RequestTrade`,t,n)})}submitOptions(){return this.walletAddress===void 0?{}:{walletAddress:this.walletAddress}}async signRequestTrade(e){if(u(`RequestTrade`,e),this.signer===void 0)throw t.noSignerError();return g(this.signer,`RequestTrade`,e)}orientPool(e,n,r){if(r===void 0)return c(s(e,n));if(!(e===r.token0&&n===r.token1||e===r.token1&&n===r.token0))throw new t(`POOL_MISMATCH`,{tokenIn:e,tokenOut:n,poolToken0:r.token0,poolToken1:r.token1});return{token0:r.token0,token1:r.token1}}async confirmSwap(e,t){return p(e),new o({method:`RequestTrade`,uniqueKey:e,transactionId:null,mode:`queued`,result:void 0,dexBackendBaseUrl:this.gateway.dexBackendBaseUrl,httpRequestor:this.gateway.httpRequestor,requestTimeoutMs:this.gateway.requestTimeoutMs,wire:this.gateway.wire}).confirm({initialDelayMs:0,...t})}};export{v as Swaps,_ as swapRouteFromQuote};
2
2
  //# sourceMappingURL=swaps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"swaps.js","names":["_defineProperty","swapRouteFromQuote","validateFee","quote","assertCanonicalPair","tokenIn","tokenOut","Swaps","gateway","symbols","signer","walletAddress","resolveUniqueKeyPrefix","options","fee","amount","shadowFailures","uniqueKey","createUniqueKey","assertUniqueKey","tokenInSymbol","tradingSymbolOf","tokenOutSymbol","ordered","buildRequestTradeDto","signed","dto","result","readShadowSubmitOutcome","assertCanonicalV2Dto","GSwapSDKError","signPreSend","pool","readOrderedSymbols","orderSymbols","SubmittedTransaction"],"sources":["../../../src/classes/swaps.ts"],"sourcesContent":["import {\n assertUniqueKey,\n createUniqueKey,\n resolveUniqueKeyPrefix,\n signPreSend,\n type GalaChainSigner,\n type HttpRequestor,\n type UniqueKeyOptions,\n type WireOptions,\n} from '@gala-chain/gala-core-sdk';\nimport type { SwapAmount } from '../types/amounts.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { orderSymbols, readOrderedSymbols, type TokenRef } from '../utils/ordering.js';\nimport { assertCanonicalV2Dto, buildRequestTradeDto } from '../utils/dto_builders.js';\nimport { shadowFailures } from '../utils/shadow_errors.js';\nimport { assertCanonicalPair, validateFee } from '../utils/validation.js';\nimport type { ChainSubmitOptions } from './gateway.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport {\n readShadowSubmitOutcome,\n type ShadowSubmitOutcome,\n type ShadowSubmitResult,\n} from './shadow_submit.js';\nimport { SubmittedTransaction } from './submitted_transaction.js';\nimport type { ConfirmOptions } from '../types/confirm_options.js';\nimport type { RequestTradeDTO } from '../types/v2_dtos.js';\nimport type { AppliedTrade, QuoteResult } from '../types/v2_results.js';\nimport { tradingSymbolOf, type TokenResolver } from './symbols.js';\n\ninterface SwapGateway {\n submit: (\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<SubmittedTransaction<AppliedTrade>>;\n submitShadow: (\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<ShadowSubmitResult>;\n readonly dexBackendBaseUrl: string;\n readonly httpRequestor: HttpRequestor;\n readonly requestTimeoutMs: number;\n readonly wire?: WireOptions | undefined;\n}\n\n/** The canonical pool a swap trades in, as a quote names it. */\nexport interface SwapPool {\n token0: string;\n token1: string;\n}\n\n/** Options of a swap. */\nexport interface SwapOptions {\n /**\n * The attempt's `uniqueKey` (1-128 characters of `A-Za-z0-9._:-`). Default: a fresh\n * `<uniqueKeyPrefix><uuid>`. Supply one to know the key before signing (to remember it, to\n * show it), or to retry the SAME attempt after a lost response; never reuse it for another trade.\n */\n uniqueKey?: string | undefined;\n /**\n * Pin the pool: take `token0` / `token1` verbatim from the quote the user saw, instead of\n * ordering `tokenIn` / `tokenOut` by string comparison. `tokenIn` and `tokenOut` must be exactly\n * these two symbols, and `token0` must sort before `token1`. See {@link swapRouteFromQuote}.\n */\n pool?: SwapPool | undefined;\n}\n\n/** Everything {@link Swaps.swap} needs to trade in the pool a quote priced. */\nexport interface SwapRoute {\n tokenIn: string;\n tokenOut: string;\n fee: FEE_TIER;\n pool: SwapPool;\n}\n\n/**\n * The route of a quote: its fee tier and pool, with `tokenIn` / `tokenOut` taken from\n * `tokenInIsToken0`, nothing re-derived. Use it to swap in exactly the pool a quote priced:\n *\n * @example\n * ```ts\n * const route = swapRouteFromQuote(quote);\n * await swaps.swap(route.tokenIn, route.tokenOut, route.fee, { exactIn: '100' }, { pool: route.pool });\n * ```\n */\nexport function swapRouteFromQuote(\n quote: Pick<QuoteResult, 'token0Symbol' | 'token1Symbol' | 'tokenInIsToken0' | 'fee'>,\n): SwapRoute {\n validateFee(quote.fee);\n assertCanonicalPair(quote.token0Symbol, quote.token1Symbol);\n const [tokenIn, tokenOut] = quote.tokenInIsToken0\n ? [quote.token0Symbol, quote.token1Symbol]\n : [quote.token1Symbol, quote.token0Symbol];\n return {\n tokenIn,\n tokenOut,\n fee: quote.fee,\n pool: { token0: quote.token0Symbol, token1: quote.token1Symbol },\n };\n}\n\n/** Executes queued current-contract RequestTrade operations through the Chain Gateway. */\nexport class Swaps {\n /**\n * Creates a swap service.\n *\n * @example\n * ```ts\n * const swaps = new Swaps(gateway, symbols, signer, 'client|alice');\n * ```\n */\n constructor(\n private readonly gateway: SwapGateway,\n private readonly symbols: TokenResolver,\n private readonly signer?: GalaChainSigner,\n private readonly walletAddress?: string,\n options: UniqueKeyOptions = {},\n ) {\n this.uniqueKeyPrefix = resolveUniqueKeyPrefix(options.uniqueKeyPrefix);\n }\n\n private readonly uniqueKeyPrefix: string;\n\n /**\n * Signs and submits an exact-input or exact-output RequestTrade DTO. The returned transaction\n * is QUEUED; call `await tx.confirm()` to obtain the executed trade or chain rejection.\n *\n * @example\n * ```ts\n * const submitted = await swaps.swap('GALA', 'GUSDC', 3000, {\n * exactIn: '100',\n * amountOutMinimum: '14',\n * });\n * ```\n */\n public async swap(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n options?: SwapOptions,\n ): Promise<SubmittedTransaction<AppliedTrade>> {\n return this.submitSwap(await this.buildSwap(tokenIn, tokenOut, fee, amount, options));\n }\n\n /**\n * Signs and submits a SHADOW (dark) swap: the same RequestTrade as {@link swap}, relayed with\n * `X-Shadow: true` so defi-backend marks it private before it reaches the contract. Requires a\n * `walletAddress`. Resolves the normalized outcome instead of throwing on a gateway refusal:\n * `ok: false` carries `unavailable` (retryable), `disabled`, `rejected` (with the gateway's\n * message) or `unknown`. A success carries `queued`, to be confirmed with\n * `confirmSwap(queued.uniqueKey)`; never fall back to a public swap on failure. Whatever this\n * THROWS (a validation error, the signer, a lost connection, `SHADOW_NOT_QUEUED`) has\n * `error.shadow === true` (`isShadowError`), so an app can apply its dark-swap policy to it.\n *\n * @example\n * ```ts\n * const outcome = await swaps.swapShadow('GALA', 'GUSDC', 3000, { exactIn: '100' });\n * if (outcome.ok) await swaps.confirmSwap(outcome.queued.uniqueKey);\n * ```\n */\n public async swapShadow(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n options?: SwapOptions,\n ): Promise<ShadowSubmitOutcome> {\n return shadowFailures(async () =>\n this.submitSwapShadow(await this.buildSwap(tokenIn, tokenOut, fee, amount, options)),\n );\n }\n\n /**\n * Builds the RequestTrade DTO that {@link swap} would sign, without signing or sending it: to\n * show in an approval popup, to remember its `uniqueKey`, or to sign elsewhere. Submit exactly\n * this DTO with {@link submitSwap}. The pure counterpart, with canonical inputs and no\n * resolution, is `buildRequestTradeDto`.\n *\n * @example\n * ```ts\n * const dto = await swaps.buildSwap('GALA', 'GUSDC', 3000, { exactIn: '100' });\n * showApproval(dto);\n * const submitted = await swaps.submitSwap(dto);\n * ```\n */\n public async buildSwap(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n options?: SwapOptions,\n ): Promise<RequestTradeDTO> {\n validateFee(fee);\n const uniqueKey = options?.uniqueKey ?? createUniqueKey(this.uniqueKeyPrefix);\n assertUniqueKey(uniqueKey);\n const tokenInSymbol = await tradingSymbolOf(this.symbols, tokenIn);\n const tokenOutSymbol = await tradingSymbolOf(this.symbols, tokenOut);\n const ordered = this.orientPool(tokenInSymbol, tokenOutSymbol, options?.pool);\n return buildRequestTradeDto({\n token0: ordered.token0,\n token1: ordered.token1,\n fee,\n tokenInIsToken0: tokenInSymbol === ordered.token0,\n uniqueKey,\n ...amount,\n });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildSwap} or `buildRequestTradeDto`. The DTO must be\n * exactly what the builder produces (no signature, canonical decimals, builder key order), so\n * what an app showed is what gets signed.\n *\n * @example\n * ```ts\n * const submitted = await swaps.submitSwap(dto);\n * const applied = await submitted.confirm();\n * ```\n */\n public async submitSwap(dto: RequestTradeDTO): Promise<SubmittedTransaction<AppliedTrade>> {\n const signed = await this.signRequestTrade(dto);\n return this.gateway.submit('RequestTrade', signed, this.submitOptions());\n }\n\n /** Signs and shadow-submits a DTO built by {@link buildSwap}; see {@link swapShadow}. */\n public async submitSwapShadow(dto: RequestTradeDTO): Promise<ShadowSubmitOutcome> {\n return shadowFailures(async () => {\n const signed = await this.signRequestTrade(dto);\n const result = await this.gateway.submitShadow('RequestTrade', signed, this.submitOptions());\n return readShadowSubmitOutcome('RequestTrade', signed, result);\n });\n }\n\n private submitOptions(): ChainSubmitOptions {\n return this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress };\n }\n\n private async signRequestTrade(dto: RequestTradeDTO): Promise<Record<string, unknown>> {\n assertCanonicalV2Dto('RequestTrade', dto);\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n return signPreSend(this.signer, 'RequestTrade', dto);\n }\n\n /** The pool's two symbols in contract order: the quote's own when pinned, else string order. */\n private orientPool(\n tokenInSymbol: string,\n tokenOutSymbol: string,\n pool: SwapPool | undefined,\n ): SwapPool {\n if (pool === undefined) {\n return readOrderedSymbols(orderSymbols(tokenInSymbol, tokenOutSymbol));\n }\n const sameSet =\n (tokenInSymbol === pool.token0 && tokenOutSymbol === pool.token1) ||\n (tokenInSymbol === pool.token1 && tokenOutSymbol === pool.token0);\n if (!sameSet) {\n throw new GSwapSDKError('POOL_MISMATCH', {\n tokenIn: tokenInSymbol,\n tokenOut: tokenOutSymbol,\n poolToken0: pool.token0,\n poolToken1: pool.token1,\n });\n }\n return { token0: pool.token0, token1: pool.token1 };\n }\n\n /**\n * Confirm a swap by its durable `uniqueKey` without resubmitting it. This is the recovery\n * path after a `CONFIRMATION_TIMEOUT`, a `SUBMISSION_OUTCOME_UNKNOWN`, a `409` replay\n * conflict, or a process restart: it reads the same apply-results record that\n * `SubmittedTransaction.confirm()` reads (retained for 7 days) and resolves the applied trade\n * or throws the chain's rejection. The first read happens immediately unless\n * `initialDelayMs` is given.\n *\n * @example\n * ```ts\n * const applied = await swaps.confirmSwap('galaswap-operation-2f1c…');\n * ```\n */\n public async confirmSwap(uniqueKey: string, options?: ConfirmOptions): Promise<AppliedTrade> {\n assertUniqueKey(uniqueKey);\n const transaction = new SubmittedTransaction<AppliedTrade>({\n method: 'RequestTrade',\n uniqueKey,\n transactionId: null,\n mode: 'queued',\n result: undefined,\n dexBackendBaseUrl: this.gateway.dexBackendBaseUrl,\n httpRequestor: this.gateway.httpRequestor,\n requestTimeoutMs: this.gateway.requestTimeoutMs,\n wire: this.gateway.wire,\n });\n return transaction.confirm({ initialDelayMs: 0, ...options });\n }\n}\n"],"mappings":"uuBAsFA,SAAgBC,EACd,EACW,CACXC,EAAYC,EAAM,GAAG,EACrBC,EAAoBD,EAAM,aAAcA,EAAM,YAAY,EAC1D,GAAM,CAACE,EAASC,GAAYH,EAAM,gBAC9B,CAACA,EAAM,aAAcA,EAAM,YAAY,EACvC,CAACA,EAAM,aAAcA,EAAM,YAAY,EAC3C,MAAO,CACL,UACA,WACA,IAAKA,EAAM,IACX,KAAM,CAAE,OAAQA,EAAM,aAAc,OAAQA,EAAM,YAAa,CACjE,CACF,CAGA,IAAaI,EAAb,KAAmB,CASjB,YACE,EACA,EACA,EACA,EACA,EAA4B,CAAC,EAC7B,CALiB,KAAA,QAAAC,EACA,KAAA,QAAAC,EACA,KAAA,OAAAC,EACA,KAAA,cAAAC,EAMFX,EAAA,KAAA,kBAAA,IAAA,EAAA,EAHf,KAAK,gBAAkBY,EAAuBC,EAAQ,eAAe,CACvE,CAgBA,MAAa,KACX,EACA,EACA,EACA,EACA,EAC6C,CAC7C,OAAO,KAAK,WAAW,MAAM,KAAK,UAAUR,EAASC,EAAUQ,EAAKC,EAAQF,CAAO,CAAC,CACtF,CAkBA,MAAa,WACX,EACA,EACA,EACA,EACA,EAC8B,CAC9B,OAAOG,EAAe,SACpB,KAAK,iBAAiB,MAAM,KAAK,UAAUX,EAASC,EAAUQ,EAAKC,EAAQF,CAAO,CAAC,CACrF,CACF,CAeA,MAAa,UACX,EACA,EACA,EACA,EACA,EAC0B,CAC1BX,EAAYY,CAAG,EACf,IAAMG,EAAYJ,GAAS,WAAaK,EAAgB,KAAK,eAAe,EAC5EC,EAAgBF,CAAS,EACzB,IAAMG,EAAgB,MAAMC,EAAgB,KAAK,QAAShB,CAAO,EAC3DiB,EAAiB,MAAMD,EAAgB,KAAK,QAASf,CAAQ,EAC7DiB,EAAU,KAAK,WAAWH,EAAeE,EAAgBT,GAAS,IAAI,EAC5E,OAAOW,EAAqB,CAC1B,OAAQD,EAAQ,OAChB,OAAQA,EAAQ,OAChB,MACA,gBAAiBH,IAAkBG,EAAQ,OAC3C,YACA,GAAGR,CACL,CAAC,CACH,CAaA,MAAa,WAAW,EAAmE,CACzF,IAAMU,EAAS,MAAM,KAAK,iBAAiBC,CAAG,EAC9C,OAAO,KAAK,QAAQ,OAAO,eAAgBD,EAAQ,KAAK,cAAc,CAAC,CACzE,CAGA,MAAa,iBAAiB,EAAoD,CAChF,OAAOT,EAAe,SAAY,CAChC,IAAMS,EAAS,MAAM,KAAK,iBAAiBC,CAAG,EACxCC,EAAS,MAAM,KAAK,QAAQ,aAAa,eAAgBF,EAAQ,KAAK,cAAc,CAAC,EAC3F,OAAOG,EAAwB,eAAgBH,EAAQE,CAAM,CAC/D,CAAC,CACH,CAEA,eAA4C,CAC1C,OAAO,KAAK,gBAAkB,IAAA,GAAY,CAAC,EAAI,CAAE,cAAe,KAAK,aAAc,CACrF,CAEA,MAAc,iBAAiB,EAAwD,CAErF,GADAE,EAAqB,eAAgBH,CAAG,EACpC,KAAK,SAAW,IAAA,GAAW,MAAMI,EAAc,cAAc,EACjE,OAAOC,EAAY,KAAK,OAAQ,eAAgBL,CAAG,CACrD,CAGA,WACE,EACA,EACA,EACU,CACV,GAAIM,IAAS,IAAA,GACX,OAAOC,EAAmBC,EAAad,EAAeE,CAAc,CAAC,EAKvE,GAAI,EAFDF,IAAkBY,EAAK,QAAUV,IAAmBU,EAAK,QACzDZ,IAAkBY,EAAK,QAAUV,IAAmBU,EAAK,QAE1D,MAAM,IAAIF,EAAc,gBAAiB,CACvC,QAASV,EACT,SAAUE,EACV,WAAYU,EAAK,OACjB,WAAYA,EAAK,MACnB,CAAC,EAEH,MAAO,CAAE,OAAQA,EAAK,OAAQ,OAAQA,EAAK,MAAO,CACpD,CAeA,MAAa,YAAY,EAAmB,EAAiD,CAa3F,OAZAb,EAAgBF,CAAS,EAYlB,IAXiBkB,EAAmC,CACzD,OAAQ,eACR,YACA,cAAe,KACf,KAAM,SACN,OAAQ,IAAA,GACR,kBAAmB,KAAK,QAAQ,kBAChC,cAAe,KAAK,QAAQ,cAC5B,iBAAkB,KAAK,QAAQ,iBAC/B,KAAM,KAAK,QAAQ,IACrB,CACiB,CAAC,CAAC,QAAQ,CAAE,eAAgB,EAAG,GAAGtB,CAAQ,CAAC,CAC9D,CACF"}
1
+ {"version":3,"file":"swaps.js","names":["_defineProperty","swapRouteFromQuote","validateFee","quote","assertCanonicalPair","tokenIn","tokenOut","Swaps","gateway","symbols","signer","walletAddress","userRef","resolveUniqueKeyPrefix","options","fee","amount","shadowFailures","uniqueKey","createUniqueKey","assertUniqueKey","tokenInSymbol","tradingSymbolOf","tokenOutSymbol","ordered","buildRequestTradeDto","signed","dto","result","readShadowSubmitOutcome","assertCanonicalV2Dto","GSwapSDKError","signPreSend","pool","readOrderedSymbols","orderSymbols","SubmittedTransaction"],"sources":["../../../src/classes/swaps.ts"],"sourcesContent":["import {\n assertUniqueKey,\n createUniqueKey,\n resolveUniqueKeyPrefix,\n signPreSend,\n type GalaChainSigner,\n type HttpRequestor,\n type UniqueKeyOptions,\n type WireOptions,\n} from '@gala-chain/gala-core-sdk';\nimport type { SwapAmount } from '../types/amounts.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { orderSymbols, readOrderedSymbols, type TokenRef } from '../utils/ordering.js';\nimport { assertCanonicalV2Dto, buildRequestTradeDto } from '../utils/dto_builders.js';\nimport { shadowFailures } from '../utils/shadow_errors.js';\nimport { assertCanonicalPair, userRef, validateFee } from '../utils/validation.js';\nimport type { ChainSubmitOptions } from './gateway.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport {\n readShadowSubmitOutcome,\n type ShadowSubmitOutcome,\n type ShadowSubmitResult,\n} from './shadow_submit.js';\nimport { SubmittedTransaction } from './submitted_transaction.js';\nimport type { ConfirmOptions } from '../types/confirm_options.js';\nimport type { RequestTradeDTO } from '../types/v2_dtos.js';\nimport type { AppliedTrade, QuoteResult } from '../types/v2_results.js';\nimport { tradingSymbolOf, type TokenResolver } from './symbols.js';\n\ninterface SwapGateway {\n submit: (\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<SubmittedTransaction<AppliedTrade>>;\n submitShadow: (\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<ShadowSubmitResult>;\n readonly dexBackendBaseUrl: string;\n readonly httpRequestor: HttpRequestor;\n readonly requestTimeoutMs: number;\n readonly wire?: WireOptions | undefined;\n}\n\n/** The canonical pool a swap trades in, as a quote names it. */\nexport interface SwapPool {\n token0: string;\n token1: string;\n}\n\n/** Options of a swap. */\nexport interface SwapOptions {\n /**\n * The attempt's `uniqueKey` (1-128 characters of `A-Za-z0-9._:-`). Default: a fresh\n * `<uniqueKeyPrefix><uuid>`. Supply one to know the key before signing (to remember it, to\n * show it), or to retry the SAME attempt after a lost response; never reuse it for another trade.\n */\n uniqueKey?: string | undefined;\n /**\n * Pin the pool: take `token0` / `token1` verbatim from the quote the user saw, instead of\n * ordering `tokenIn` / `tokenOut` by string comparison. `tokenIn` and `tokenOut` must be exactly\n * these two symbols, and `token0` must sort before `token1`. See {@link swapRouteFromQuote}.\n */\n pool?: SwapPool | undefined;\n}\n\n/** Everything {@link Swaps.swap} needs to trade in the pool a quote priced. */\nexport interface SwapRoute {\n tokenIn: string;\n tokenOut: string;\n fee: FEE_TIER;\n pool: SwapPool;\n}\n\n/**\n * The route of a quote: its fee tier and pool, with `tokenIn` / `tokenOut` taken from\n * `tokenInIsToken0`, nothing re-derived. Use it to swap in exactly the pool a quote priced:\n *\n * @example\n * ```ts\n * const route = swapRouteFromQuote(quote);\n * await swaps.swap(route.tokenIn, route.tokenOut, route.fee, { exactIn: '100' }, { pool: route.pool });\n * ```\n */\nexport function swapRouteFromQuote(\n quote: Pick<QuoteResult, 'token0Symbol' | 'token1Symbol' | 'tokenInIsToken0' | 'fee'>,\n): SwapRoute {\n validateFee(quote.fee);\n assertCanonicalPair(quote.token0Symbol, quote.token1Symbol);\n const [tokenIn, tokenOut] = quote.tokenInIsToken0\n ? [quote.token0Symbol, quote.token1Symbol]\n : [quote.token1Symbol, quote.token0Symbol];\n return {\n tokenIn,\n tokenOut,\n fee: quote.fee,\n pool: { token0: quote.token0Symbol, token1: quote.token1Symbol },\n };\n}\n\n/** Executes queued current-contract RequestTrade operations through the Chain Gateway. */\nexport class Swaps {\n /**\n * Creates a swap service.\n *\n * @example\n * ```ts\n * const swaps = new Swaps(gateway, symbols, signer, 'client|alice');\n * ```\n */\n constructor(\n private readonly gateway: SwapGateway,\n private readonly symbols: TokenResolver,\n private readonly signer?: GalaChainSigner,\n walletAddress?: string,\n options: UniqueKeyOptions = {},\n ) {\n this.walletAddress =\n walletAddress === undefined ? undefined : userRef(walletAddress, 'walletAddress');\n this.uniqueKeyPrefix = resolveUniqueKeyPrefix(options.uniqueKeyPrefix);\n }\n\n /** The signing wallet in the gateway's spelling (`eth|<EIP-55>` or `client|<id>`). */\n private readonly walletAddress: string | undefined;\n private readonly uniqueKeyPrefix: string;\n\n /**\n * Signs and submits an exact-input or exact-output RequestTrade DTO. The returned transaction\n * is QUEUED; call `await tx.confirm()` to obtain the executed trade or chain rejection.\n *\n * @example\n * ```ts\n * const submitted = await swaps.swap('GALA', 'GUSDC', 3000, {\n * exactIn: '100',\n * amountOutMinimum: '14',\n * });\n * ```\n */\n public async swap(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n options?: SwapOptions,\n ): Promise<SubmittedTransaction<AppliedTrade>> {\n return this.submitSwap(await this.buildSwap(tokenIn, tokenOut, fee, amount, options));\n }\n\n /**\n * Signs and submits a SHADOW (dark) swap: the same RequestTrade as {@link swap}, relayed with\n * `X-Shadow: true` so defi-backend marks it private before it reaches the contract. Requires a\n * `walletAddress`. Resolves the normalized outcome instead of throwing on a gateway refusal:\n * `ok: false` carries `unavailable` (retryable), `disabled`, `rejected` (with the gateway's\n * message) or `unknown`. A success carries `queued`, to be confirmed with\n * `confirmSwap(queued.uniqueKey)`; never fall back to a public swap on failure. Whatever this\n * THROWS (a validation error, the signer, a lost connection, `SHADOW_NOT_QUEUED`) has\n * `error.shadow === true` (`isShadowError`), so an app can apply its dark-swap policy to it.\n *\n * @example\n * ```ts\n * const outcome = await swaps.swapShadow('GALA', 'GUSDC', 3000, { exactIn: '100' });\n * if (outcome.ok) await swaps.confirmSwap(outcome.queued.uniqueKey);\n * ```\n */\n public async swapShadow(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n options?: SwapOptions,\n ): Promise<ShadowSubmitOutcome> {\n return shadowFailures(async () =>\n this.submitSwapShadow(await this.buildSwap(tokenIn, tokenOut, fee, amount, options)),\n );\n }\n\n /**\n * Builds the RequestTrade DTO that {@link swap} would sign, without signing or sending it: to\n * show in an approval popup, to remember its `uniqueKey`, or to sign elsewhere. Submit exactly\n * this DTO with {@link submitSwap}. The pure counterpart, with canonical inputs and no\n * resolution, is `buildRequestTradeDto`.\n *\n * @example\n * ```ts\n * const dto = await swaps.buildSwap('GALA', 'GUSDC', 3000, { exactIn: '100' });\n * showApproval(dto);\n * const submitted = await swaps.submitSwap(dto);\n * ```\n */\n public async buildSwap(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n options?: SwapOptions,\n ): Promise<RequestTradeDTO> {\n validateFee(fee);\n const uniqueKey = options?.uniqueKey ?? createUniqueKey(this.uniqueKeyPrefix);\n assertUniqueKey(uniqueKey);\n const tokenInSymbol = await tradingSymbolOf(this.symbols, tokenIn);\n const tokenOutSymbol = await tradingSymbolOf(this.symbols, tokenOut);\n const ordered = this.orientPool(tokenInSymbol, tokenOutSymbol, options?.pool);\n return buildRequestTradeDto({\n token0: ordered.token0,\n token1: ordered.token1,\n fee,\n tokenInIsToken0: tokenInSymbol === ordered.token0,\n uniqueKey,\n ...amount,\n });\n }\n\n /**\n * Signs and submits a DTO built by {@link buildSwap} or `buildRequestTradeDto`. The DTO must be\n * exactly what the builder produces (no signature, canonical decimals, builder key order), so\n * what an app showed is what gets signed.\n *\n * @example\n * ```ts\n * const submitted = await swaps.submitSwap(dto);\n * const applied = await submitted.confirm();\n * ```\n */\n public async submitSwap(dto: RequestTradeDTO): Promise<SubmittedTransaction<AppliedTrade>> {\n const signed = await this.signRequestTrade(dto);\n return this.gateway.submit('RequestTrade', signed, this.submitOptions());\n }\n\n /** Signs and shadow-submits a DTO built by {@link buildSwap}; see {@link swapShadow}. */\n public async submitSwapShadow(dto: RequestTradeDTO): Promise<ShadowSubmitOutcome> {\n return shadowFailures(async () => {\n const signed = await this.signRequestTrade(dto);\n const result = await this.gateway.submitShadow('RequestTrade', signed, this.submitOptions());\n return readShadowSubmitOutcome('RequestTrade', signed, result);\n });\n }\n\n private submitOptions(): ChainSubmitOptions {\n return this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress };\n }\n\n private async signRequestTrade(dto: RequestTradeDTO): Promise<Record<string, unknown>> {\n assertCanonicalV2Dto('RequestTrade', dto);\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n return signPreSend(this.signer, 'RequestTrade', dto);\n }\n\n /** The pool's two symbols in contract order: the quote's own when pinned, else string order. */\n private orientPool(\n tokenInSymbol: string,\n tokenOutSymbol: string,\n pool: SwapPool | undefined,\n ): SwapPool {\n if (pool === undefined) {\n return readOrderedSymbols(orderSymbols(tokenInSymbol, tokenOutSymbol));\n }\n const sameSet =\n (tokenInSymbol === pool.token0 && tokenOutSymbol === pool.token1) ||\n (tokenInSymbol === pool.token1 && tokenOutSymbol === pool.token0);\n if (!sameSet) {\n throw new GSwapSDKError('POOL_MISMATCH', {\n tokenIn: tokenInSymbol,\n tokenOut: tokenOutSymbol,\n poolToken0: pool.token0,\n poolToken1: pool.token1,\n });\n }\n return { token0: pool.token0, token1: pool.token1 };\n }\n\n /**\n * Confirm a swap by its durable `uniqueKey` without resubmitting it. This is the recovery\n * path after a `CONFIRMATION_TIMEOUT`, a `SUBMISSION_OUTCOME_UNKNOWN`, a `409` replay\n * conflict, or a process restart: it reads the same apply-results record that\n * `SubmittedTransaction.confirm()` reads (retained for 7 days) and resolves the applied trade\n * or throws the chain's rejection. The first read happens immediately unless\n * `initialDelayMs` is given.\n *\n * @example\n * ```ts\n * const applied = await swaps.confirmSwap('galaswap-operation-2f1c…');\n * ```\n */\n public async confirmSwap(uniqueKey: string, options?: ConfirmOptions): Promise<AppliedTrade> {\n assertUniqueKey(uniqueKey);\n const transaction = new SubmittedTransaction<AppliedTrade>({\n method: 'RequestTrade',\n uniqueKey,\n transactionId: null,\n mode: 'queued',\n result: undefined,\n dexBackendBaseUrl: this.gateway.dexBackendBaseUrl,\n httpRequestor: this.gateway.httpRequestor,\n requestTimeoutMs: this.gateway.requestTimeoutMs,\n wire: this.gateway.wire,\n });\n return transaction.confirm({ initialDelayMs: 0, ...options });\n }\n}\n"],"mappings":"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"}
@@ -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,validateFee as T,validateNumericAmount as E,validatePriceValues as D,validateTickRange as O,validateTickSpacing as k,validateTokenDecimals as A,validateWalletAddress as j}from"./utils/validation.js";import{Assets as M}from"./classes/assets.js";import{DEX_FEE_METHODS as N,DRY_RUN_METHOD as P,DRY_RUN_UNIQUE_KEY_PREFIX as F,DexFees as I,buildDryRunWrapper as L,isCurrentContractDexMessage as R,isDexFeeMethod as z,toChainDto as B}from"./classes/dex_fees.js";import{isShadowError as V}from"./utils/shadow_errors.js";import{SubmittedTransaction as H}from"./classes/submitted_transaction.js";import{ChainGateway as U}from"./classes/gateway.js";import{GSWAP_ENVIRONMENTS as W}from"./types/env.js";import{GdexStreamError as G,GdexStreamService as K,isGdexLiquidityEvent as q}from"./classes/gdex_stream.js";import{Leaderboard as J}from"./classes/leaderboard.js";import{MARKET_PRICE_BATCH_LIMIT as Y,PRICE_SERIES_TIMEFRAMES as X}from"./types/market.js";import{MARKET_PRICE_QUERY_BYTES as Z,Market as Q,priceBatches as $}from"./classes/market.js";import{orderSymbols as ee,parseTokenClassKey as te,readOrderedSymbols as ne}from"./utils/ordering.js";import{CanonicalSymbols as re,Symbols as ie,queryTokenOf as ae,rawTokenOf as oe,tradingSymbolOf as se}from"./classes/symbols.js";import{Pools as ce}from"./classes/pools.js";import{alignTickDownOrNaN as le,alignTickUpOrNaN as ue}from"./utils/tick_align.js";import{alignTickDown as de,alignTickUp as fe,assertTickRange as pe,frameSlot0 as me}from"./utils/ticks.js";import{assertCanonicalV2Dto as he,buildAddLiquidityDto as ge,buildCollectPositionFeesDto as _e,buildCreatePoolDto as ve,buildRemoveLiquidityDto as ye,buildRequestTradeDto as be}from"./utils/dto_builders.js";import{Positions as xe}from"./classes/positions.js";import{Quoting as Se}from"./classes/quoting.js";import{SHADOW_FAILURE_KINDS as Ce,SHADOW_SUBMIT_CODES as we,classifyShadowSubmitError as Te,classifyShadowSubmitStatus as Ee,readShadowSubmitOutcome as De}from"./classes/shadow_submit.js";import{Swaps as Oe,swapRouteFromQuote as ke}from"./classes/swaps.js";import{GSwap as Ae}from"./classes/gswap.js";import{NOT_QUEUED_FINAL as je,classification as Me,notSentClassification as Ne}from"./utils/classification.js";import{classifyFailure as Pe,mayHaveBeenQueued as Fe}from"./utils/failure_classification.js";import{PENDING_SWAP_FATES as Ie,pendingSwapFateFor as Le,pendingSwapFateOfOutcome as Re}from"./classes/pending_swap_fate.js";import{PENDING_SWAPS_STORAGE_KEY as ze,PENDING_SWAP_EXPIRY_MS as Be,PENDING_SWAP_PRUNE_REASONS as Ve,PendingSwapStore as He}from"./classes/pending_swaps.js";import{storageAdapterFromChromeStorage as Ue,webStorageAdapter as We}from"./classes/storage_adapters.js";import{confirmationStateOf as Ge,isConfirmationAborted as Ke,isConfirmationTimeout as qe}from"./utils/confirmation_state.js";import{chainErrorKeyOf as Je,isNoMarket as Ye,isRelayableRefusal as Xe,isUninterpretedAnswer as Ze,isUniqueKeyConsumed as Qe,isUnprovenAcknowledgement as $e}from"./utils/failure_guards.js";import{classifySubmitEnvelope as et,isSubmitExecuted as tt,isSubmitQueued as nt,isSubmitRejected as rt}from"./utils/submit_state.js";export{f as ALL_FEE_TIERS,u as AppliedTradeError,M as Assets,re as CanonicalSymbols,U as ChainGateway,N as DEX_FEE_METHODS,P as DRY_RUN_METHOD,F as DRY_RUN_UNIQUE_KEY_PREFIX,I as DexFees,p as FEE_TIER,g as GC_MAX_TICK,_ as GC_MIN_TICK,W as GSWAP_ENVIRONMENTS,e as GSWAP_ERROR_CATALOG,r as GSWAP_ERROR_PHASE_BY_CODE,Ae as GSwap,i as GSwapSDKError,G as GdexStreamError,K as GdexStreamService,J as Leaderboard,Y as MARKET_PRICE_BATCH_LIMIT,Z as MARKET_PRICE_QUERY_BYTES,Q as Market,je as NOT_QUEUED_FINAL,ze as PENDING_SWAPS_STORAGE_KEY,Be as PENDING_SWAP_EXPIRY_MS,Ie as PENDING_SWAP_FATES,Ve as PENDING_SWAP_PRUNE_REASONS,X as PRICE_SERIES_TIMEFRAMES,He as PendingSwapStore,ce as Pools,xe as Positions,Se as Quoting,Ce as SHADOW_FAILURE_KINDS,we as SHADOW_SUBMIT_CODES,t as SUBMISSION_OUTCOME_UNKNOWN_REASONS,H as SubmittedTransaction,Oe as Swaps,ie as Symbols,m as TICK_SPACING_BY_FEE,a as UPDATE_REQUIRED_STATUS,de as alignTickDown,le as alignTickDownOrNaN,fe as alignTickUp,ue as alignTickUpOrNaN,C as assertCanonicalPair,he as assertCanonicalV2Dto,pe as assertTickRange,ge as buildAddLiquidityDto,_e as buildCollectPositionFeesDto,ve as buildCreatePoolDto,L as buildDryRunWrapper,ye as buildRemoveLiquidityDto,be as buildRequestTradeDto,Je as chainErrorKeyOf,Me as classification,Pe as classifyFailure,Te as classifyShadowSubmitError,Ee as classifyShadowSubmitStatus,et as classifySubmitEnvelope,d as confirmAppliedTrade,Ge as confirmationStateOf,me as frameSlot0,o as getObjectProperty,s as getStringProperty,n as gswapErrorTemplates,Ke as isConfirmationAborted,qe as isConfirmationTimeout,R as isCurrentContractDexMessage,z as isDexFeeMethod,c as isGSwapError,q as isGdexLiquidityEvent,Ye as isNoMarket,l as isPreSendError,w as isProposableTradingSymbol,Xe as isRelayableRefusal,V as isShadowError,v as isSqrtPriceInRange,tt as isSubmitExecuted,nt as isSubmitQueued,rt as isSubmitRejected,h as isTickInRange,Ze as isUninterpretedAnswer,Qe as isUniqueKeyConsumed,$e as isUnprovenAcknowledgement,Fe as mayHaveBeenQueued,Ne as notSentClassification,ee as orderSymbols,te as parseTokenClassKey,Le as pendingSwapFateFor,Re as pendingSwapFateOfOutcome,$ as priceBatches,ae as queryTokenOf,oe as rawTokenOf,ne as readOrderedSymbols,De as readShadowSubmitOutcome,y as sqrtPriceToTick,Ue as storageAdapterFromChromeStorage,ke as swapRouteFromQuote,b as tickFromPrice,x as tickToPrice,S as tickToSqrtPrice,B as toChainDto,se as tradingSymbolOf,T as validateFee,E as validateNumericAmount,D as validatePriceValues,O as validateTickRange,k as validateTickSpacing,A as validateTokenDecimals,j as validateWalletAddress,We as webStorageAdapter};
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,isCurrentContractDexMessage as z,isDexFeeMethod as B,toChainDto as V}from"./classes/dex_fees.js";import{isShadowError as H}from"./utils/shadow_errors.js";import{SubmittedTransaction as U}from"./classes/submitted_transaction.js";import{ChainGateway as W}from"./classes/gateway.js";import{GSWAP_ENVIRONMENTS as G}from"./types/env.js";import{GdexStreamError as K,GdexStreamService as q,isGdexLiquidityEvent as J}from"./classes/gdex_stream.js";import{Leaderboard as Y}from"./classes/leaderboard.js";import{MARKET_PRICE_BATCH_LIMIT as X,PRICE_SERIES_TIMEFRAMES as Z}from"./types/market.js";import{MARKET_PRICE_QUERY_BYTES as Q,Market as $,priceBatches as ee}from"./classes/market.js";import{ONRAMPER_MODES as te,Onramper as ne,createOnramper as re}from"./classes/onramper.js";import{orderSymbols as ie,parseTokenClassKey as ae,readOrderedSymbols as oe}from"./utils/ordering.js";import{CanonicalSymbols as se,Symbols as ce,queryTokenOf as le,rawTokenOf as ue,tradingSymbolOf as de}from"./classes/symbols.js";import{Pools as fe}from"./classes/pools.js";import{alignTickDownOrNaN as pe,alignTickUpOrNaN as me}from"./utils/tick_align.js";import{alignTickDown as he,alignTickUp as ge,assertTickRange as _e,frameSlot0 as ve}from"./utils/ticks.js";import{assertCanonicalV2Dto as ye,buildAddLiquidityDto as be,buildCollectPositionFeesDto as xe,buildCreatePoolDto as Se,buildRemoveLiquidityDto as Ce,buildRequestTradeDto as we}from"./utils/dto_builders.js";import{Positions as Te}from"./classes/positions.js";import{Quoting as Ee}from"./classes/quoting.js";import{SHADOW_FAILURE_KINDS as De,SHADOW_SUBMIT_CODES as Oe,classifyShadowSubmitError as ke,classifyShadowSubmitStatus as Ae,readShadowSubmitOutcome as je}from"./classes/shadow_submit.js";import{Swaps as Me,swapRouteFromQuote as Ne}from"./classes/swaps.js";import{GSwap as Pe}from"./classes/gswap.js";import{NOT_QUEUED_FINAL as Fe,classification as Ie,notSentClassification as Le}from"./utils/classification.js";import{classifyFailure as Re,mayHaveBeenQueued as ze}from"./utils/failure_classification.js";import{PENDING_SWAP_FATES as Be,pendingSwapFateFor as Ve,pendingSwapFateOfOutcome as He}from"./classes/pending_swap_fate.js";import{PENDING_SWAPS_STORAGE_KEY as Ue,PENDING_SWAP_EXPIRY_MS as We,PENDING_SWAP_PRUNE_REASONS as Ge,PendingSwapStore as Ke}from"./classes/pending_swaps.js";import{storageAdapterFromChromeStorage as qe,webStorageAdapter as Je}from"./classes/storage_adapters.js";import{confirmationStateOf as Ye,isConfirmationAborted as Xe,isConfirmationTimeout as Ze}from"./utils/confirmation_state.js";import{chainErrorKeyOf as Qe,isNoMarket as $e,isRelayableRefusal as et,isUninterpretedAnswer as tt,isUniqueKeyConsumed as nt,isUnprovenAcknowledgement as rt}from"./utils/failure_guards.js";import{classifySubmitEnvelope as it,isSubmitExecuted as at,isSubmitQueued as ot,isSubmitRejected as st}from"./utils/submit_state.js";export{f as ALL_FEE_TIERS,u as AppliedTradeError,N as Assets,se as CanonicalSymbols,W 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,G as GSWAP_ENVIRONMENTS,e as GSWAP_ERROR_CATALOG,r as GSWAP_ERROR_PHASE_BY_CODE,Pe as GSwap,i as GSwapSDKError,K as GdexStreamError,q as GdexStreamService,Y as Leaderboard,X as MARKET_PRICE_BATCH_LIMIT,Q as MARKET_PRICE_QUERY_BYTES,$ as Market,Fe as NOT_QUEUED_FINAL,te as ONRAMPER_MODES,ne as Onramper,Ue as PENDING_SWAPS_STORAGE_KEY,We as PENDING_SWAP_EXPIRY_MS,Be as PENDING_SWAP_FATES,Ge as PENDING_SWAP_PRUNE_REASONS,Z as PRICE_SERIES_TIMEFRAMES,Ke as PendingSwapStore,fe as Pools,Te as Positions,Ee as Quoting,De as SHADOW_FAILURE_KINDS,Oe as SHADOW_SUBMIT_CODES,t as SUBMISSION_OUTCOME_UNKNOWN_REASONS,U as SubmittedTransaction,Me as Swaps,ce as Symbols,m as TICK_SPACING_BY_FEE,a as UPDATE_REQUIRED_STATUS,he as alignTickDown,pe as alignTickDownOrNaN,ge as alignTickUp,me as alignTickUpOrNaN,C as assertCanonicalPair,ye as assertCanonicalV2Dto,_e as assertTickRange,be as buildAddLiquidityDto,xe as buildCollectPositionFeesDto,Se as buildCreatePoolDto,R as buildDryRunWrapper,Ce as buildRemoveLiquidityDto,we as buildRequestTradeDto,Qe as chainErrorKeyOf,Ie as classification,Re as classifyFailure,ke as classifyShadowSubmitError,Ae as classifyShadowSubmitStatus,it as classifySubmitEnvelope,d as confirmAppliedTrade,Ye as confirmationStateOf,re as createOnramper,ve as frameSlot0,o as getObjectProperty,s as getStringProperty,n as gswapErrorTemplates,Xe as isConfirmationAborted,Ze as isConfirmationTimeout,z as isCurrentContractDexMessage,B as isDexFeeMethod,c as isGSwapError,J as isGdexLiquidityEvent,$e as isNoMarket,l as isPreSendError,w as isProposableTradingSymbol,et as isRelayableRefusal,H as isShadowError,v as isSqrtPriceInRange,at as isSubmitExecuted,ot as isSubmitQueued,st as isSubmitRejected,h as isTickInRange,tt as isUninterpretedAnswer,nt as isUniqueKeyConsumed,rt as isUnprovenAcknowledgement,ze as mayHaveBeenQueued,Le as notSentClassification,ie as orderSymbols,ae as parseTokenClassKey,Ve as pendingSwapFateFor,He as pendingSwapFateOfOutcome,ee as priceBatches,le as queryTokenOf,ue as rawTokenOf,oe as readOrderedSymbols,je as readShadowSubmitOutcome,T as requireUserRef,y as sqrtPriceToTick,qe as storageAdapterFromChromeStorage,Ne as swapRouteFromQuote,b as tickFromPrice,x as tickToPrice,S as tickToSqrtPrice,V as toChainDto,de as tradingSymbolOf,E as userRef,D as validateFee,O as validateNumericAmount,k as validatePriceValues,A as validateTickRange,j as validateTickSpacing,M as validateTokenDecimals,Je as webStorageAdapter};
@@ -1,2 +1,2 @@
1
- import{ALLOWED_FEE_TIERS_TEXT as e}from"../classes/gswap_error_catalog.js";import{GSwapSDKError as t}from"../classes/gswap_sdk_error.js";import{ALL_FEE_TIERS as n}from"../types/fees.js";import{GC_MAX_TICK as r,GC_MIN_TICK as i}from"./tick_math.js";import a from"bignumber.js";function o(e,n,r=!1){if(typeof e==`number`)throw new t(`AMOUNT_IS_JS_NUMBER`,{field:n});let i;try{i=a(e)}catch{i=a(NaN)}if(!i.isFinite())throw new t(`AMOUNT_NOT_FINITE`,{field:n,value:String(e)});if(!r&&i.isZero())throw new t(`AMOUNT_NOT_POSITIVE`,{field:n,value:String(e)});if(i.isNegative())throw new t(`AMOUNT_NEGATIVE`,{field:n,value:String(e)})}function s(e,n,r){if([e,n,r].some(e=>typeof e==`number`))throw new t(`PRICE_VALUES_IS_JS_NUMBER`,{});let i=e=>{try{return a(e)}catch{return a(NaN)}},o=i(e),s=i(n),c=i(r);if(c=c.isFinite()?c:a(0xde0b6b3a7640000),!o.isFinite()||!s.isFinite()||!c.isFinite()||!o.isPositive()||!s.isPositive()||!c.isPositive())throw new t(`INVALID_PRICE_VALUES`,{spotPrice:String(e),lowerPrice:String(n),upperPrice:String(r)});if(s.isGreaterThan(c))throw new t(`INVALID_PRICE_RANGE`,{lowerPrice:String(n),upperPrice:String(r)})}function c(e,n){if(e<0||!Number.isInteger(e))throw new t(`INVALID_TOKEN_DECIMALS`,{field:n,value:e})}function l(e,n){if(!Number.isInteger(e)||!Number.isInteger(n))throw new t(`TICKS_NOT_INTEGERS`,{tickLower:e,tickUpper:n});if(e>=n)throw new t(`INVALID_TICK_RANGE`,{tickLower:e,tickUpper:n});if(e<-887272||n>887272)throw new t(`TICKS_OUT_OF_BOUNDS`,{tickLower:e,tickUpper:n,minTick:i,maxTick:r})}function u(r){if(!n.some(e=>Number(e)===r))throw new t(`INVALID_FEE`,{field:`fee`,value:r,allowed:e})}function d(e){if(!Number.isInteger(e)||e<=0)throw new t(`INVALID_TICK_SPACING`,{value:e})}function f(e){if(e===void 0)throw new t(`MISSING_WALLET_ADDRESS`,{});if(!e||typeof e!=`string`||e.trim().length===0)throw new t(`INVALID_WALLET_ADDRESS`,{field:`walletAddress`,value:String(e)})}const p=/* @__PURE__ */ new Set([`Token`,`Unit`,`none`]),m=/^[A-Za-z0-9]+$/u;function h(e){return m.test(e)&&e.length<=32&&!p.has(e)}function g(e,n){if(!(e<n))throw new t(`NON_CANONICAL_PAIR`,{token0:e,token1:n})}export{g as assertCanonicalPair,h as isProposableTradingSymbol,u as validateFee,o as validateNumericAmount,s as validatePriceValues,l as validateTickRange,d as validateTickSpacing,c as validateTokenDecimals,f as validateWalletAddress};
1
+ import{ALLOWED_FEE_TIERS_TEXT as e}from"../classes/gswap_error_catalog.js";import{GSwapSDKError as t}from"../classes/gswap_sdk_error.js";import{ALL_FEE_TIERS as n}from"../types/fees.js";import{GC_MAX_TICK as r,GC_MIN_TICK as i}from"./tick_math.js";import{galaChainUserRef as a}from"@gala-chain/gala-core-sdk";import o from"bignumber.js";function s(e,n,r=!1){if(typeof e==`number`)throw new t(`AMOUNT_IS_JS_NUMBER`,{field:n});let i;try{i=o(e)}catch{i=o(NaN)}if(!i.isFinite())throw new t(`AMOUNT_NOT_FINITE`,{field:n,value:String(e)});if(!r&&i.isZero())throw new t(`AMOUNT_NOT_POSITIVE`,{field:n,value:String(e)});if(i.isNegative())throw new t(`AMOUNT_NEGATIVE`,{field:n,value:String(e)})}function c(e,n,r){if([e,n,r].some(e=>typeof e==`number`))throw new t(`PRICE_VALUES_IS_JS_NUMBER`,{});let i=e=>{try{return o(e)}catch{return o(NaN)}},a=i(e),s=i(n),c=i(r);if(c=c.isFinite()?c:o(0xde0b6b3a7640000),!a.isFinite()||!s.isFinite()||!c.isFinite()||!a.isPositive()||!s.isPositive()||!c.isPositive())throw new t(`INVALID_PRICE_VALUES`,{spotPrice:String(e),lowerPrice:String(n),upperPrice:String(r)});if(s.isGreaterThan(c))throw new t(`INVALID_PRICE_RANGE`,{lowerPrice:String(n),upperPrice:String(r)})}function l(e,n){if(e<0||!Number.isInteger(e))throw new t(`INVALID_TOKEN_DECIMALS`,{field:n,value:e})}function u(e,n){if(!Number.isInteger(e)||!Number.isInteger(n))throw new t(`TICKS_NOT_INTEGERS`,{tickLower:e,tickUpper:n});if(e>=n)throw new t(`INVALID_TICK_RANGE`,{tickLower:e,tickUpper:n});if(e<-887272||n>887272)throw new t(`TICKS_OUT_OF_BOUNDS`,{tickLower:e,tickUpper:n,minTick:i,maxTick:r})}function d(r){if(!n.some(e=>Number(e)===r))throw new t(`INVALID_FEE`,{field:`fee`,value:r,allowed:e})}function f(e){if(!Number.isInteger(e)||e<=0)throw new t(`INVALID_TICK_SPACING`,{value:e})}function p(e,n){try{return a(e,n)}catch{throw new t(`INVALID_WALLET_ADDRESS`,{field:n,value:String(e)})}}function m(e,n){if(e===void 0)throw new t(`MISSING_WALLET_ADDRESS`,{});return p(e,n)}const h=/* @__PURE__ */ new Set([`Token`,`Unit`,`none`]),g=/^[A-Za-z0-9]+$/u;function _(e){return g.test(e)&&e.length<=32&&!h.has(e)}function v(e,n){if(!(e<n))throw new t(`NON_CANONICAL_PAIR`,{token0:e,token1:n})}export{v as assertCanonicalPair,_ as isProposableTradingSymbol,m as requireUserRef,p as userRef,d as validateFee,s as validateNumericAmount,c as validatePriceValues,u as validateTickRange,f as validateTickSpacing,l as validateTokenDecimals};
2
2
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","names":["BigNumber","validateNumericAmount","amount","GSwapSDKError","parameterName","bnAmount","allowZero","validatePriceValues","spotPrice","lowerPrice","upperPrice","value","parse","bnSpotPrice","bnLowerPrice","bnUpperPrice","validateTokenDecimals","decimals","validateTickRange","tickLower","tickUpper","GC_MIN_TICK","GC_MAX_TICK","validateFee","ALL_FEE_TIERS","tier","fee","ALLOWED_FEE_TIERS_TEXT","validateTickSpacing","tickSpacing","validateWalletAddress","address","RESERVED_TRADING_SYMBOLS","TRADING_SYMBOL_PATTERN","isProposableTradingSymbol","symbol","assertCanonicalPair","token0","token1"],"sources":["../../../src/utils/validation.ts"],"sourcesContent":["import BigNumber from 'bignumber.js';\nimport { ALLOWED_FEE_TIERS_TEXT } from '../classes/gswap_error_catalog.js';\nimport { GSwapSDKError } from '../classes/gswap_sdk_error.js';\nimport type { NumericAmount } from '../types/amounts.js';\nimport { ALL_FEE_TIERS } from '../types/fees.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { GC_MAX_TICK, GC_MIN_TICK } from './tick_math.js';\n\n/**\n * Validates a decimal amount: a string or `BigNumber`, never a JavaScript number.\n *\n * @param amount - The amount to check.\n * @param parameterName - The field name reported in the error's `params.field`.\n * @param allowZero - Accept zero (default `false`).\n * @throws GSwapSDKError `AMOUNT_IS_JS_NUMBER`, `AMOUNT_NOT_FINITE`, `AMOUNT_NOT_POSITIVE` (zero\n * when `allowZero` is false) or `AMOUNT_NEGATIVE`.\n */\nexport function validateNumericAmount(\n amount: NumericAmount,\n parameterName: string,\n allowZero = false,\n): void {\n if (typeof amount === 'number') {\n throw new GSwapSDKError('AMOUNT_IS_JS_NUMBER', { field: parameterName });\n }\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — substitute an explicit NaN so the isFinite() check below still catches\n // it and raises the same typed error, instead of a raw exception escaping.\n let bnAmount: BigNumber;\n try {\n bnAmount = BigNumber(amount);\n } catch {\n bnAmount = BigNumber(NaN);\n }\n\n if (!bnAmount.isFinite()) {\n throw new GSwapSDKError('AMOUNT_NOT_FINITE', {\n field: parameterName,\n value: String(amount),\n });\n }\n\n if (!allowZero && bnAmount.isZero()) {\n throw new GSwapSDKError('AMOUNT_NOT_POSITIVE', {\n field: parameterName,\n value: String(amount),\n });\n }\n\n if (bnAmount.isNegative()) {\n throw new GSwapSDKError('AMOUNT_NEGATIVE', { field: parameterName, value: String(amount) });\n }\n}\n\n/**\n * Validates a spot price and a lower/upper price range: none a JavaScript number, all positive and\n * finite (a non-finite upper bound counts as an unbounded `1e18`), and `lowerPrice <= upperPrice`.\n *\n * @throws GSwapSDKError `PRICE_VALUES_IS_JS_NUMBER`, `INVALID_PRICE_VALUES` or `INVALID_PRICE_RANGE`.\n */\nexport function validatePriceValues(\n spotPrice: NumericAmount,\n lowerPrice: NumericAmount,\n upperPrice: NumericAmount,\n): void {\n if ([spotPrice, lowerPrice, upperPrice].some((value) => typeof value === 'number')) {\n throw new GSwapSDKError('PRICE_VALUES_IS_JS_NUMBER', {});\n }\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — substitute an explicit NaN so the isFinite()/isPositive() checks below\n // still catch it and raise the same typed error, instead of a raw exception escaping.\n const parse = (value: NumericAmount): BigNumber => {\n try {\n return BigNumber(value);\n } catch {\n return BigNumber(NaN);\n }\n };\n const bnSpotPrice = parse(spotPrice);\n const bnLowerPrice = parse(lowerPrice);\n let bnUpperPrice = parse(upperPrice);\n\n bnUpperPrice = bnUpperPrice.isFinite() ? bnUpperPrice : BigNumber(1e18);\n\n if (\n !bnSpotPrice.isFinite() ||\n !bnLowerPrice.isFinite() ||\n !bnUpperPrice.isFinite() ||\n !bnSpotPrice.isPositive() ||\n !bnLowerPrice.isPositive() ||\n !bnUpperPrice.isPositive()\n ) {\n throw new GSwapSDKError('INVALID_PRICE_VALUES', {\n spotPrice: String(spotPrice),\n lowerPrice: String(lowerPrice),\n upperPrice: String(upperPrice),\n });\n }\n\n if (bnLowerPrice.isGreaterThan(bnUpperPrice)) {\n throw new GSwapSDKError('INVALID_PRICE_RANGE', {\n lowerPrice: String(lowerPrice),\n upperPrice: String(upperPrice),\n });\n }\n}\n\n/**\n * Validates a token's decimals: a non-negative integer.\n *\n * @throws GSwapSDKError `INVALID_TOKEN_DECIMALS` (`params.field` is `parameterName`).\n */\nexport function validateTokenDecimals(decimals: number, parameterName: string): void {\n if (decimals < 0 || !Number.isInteger(decimals)) {\n throw new GSwapSDKError('INVALID_TOKEN_DECIMALS', { field: parameterName, value: decimals });\n }\n}\n\n/**\n * Validates a position's tick range: two integers with `tickLower < tickUpper`, both within\n * `GC_MIN_TICK`..`GC_MAX_TICK`. It does not check alignment to a fee tier's spacing (see\n * `assertTickRange`).\n *\n * @throws GSwapSDKError `TICKS_NOT_INTEGERS`, `INVALID_TICK_RANGE` or `TICKS_OUT_OF_BOUNDS`.\n */\nexport function validateTickRange(tickLower: number, tickUpper: number): void {\n if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper)) {\n throw new GSwapSDKError('TICKS_NOT_INTEGERS', { tickLower, tickUpper });\n }\n\n if (tickLower >= tickUpper) {\n throw new GSwapSDKError('INVALID_TICK_RANGE', { tickLower, tickUpper });\n }\n\n if (tickLower < GC_MIN_TICK || tickUpper > GC_MAX_TICK) {\n throw new GSwapSDKError('TICKS_OUT_OF_BOUNDS', {\n tickLower,\n tickUpper,\n minTick: GC_MIN_TICK,\n maxTick: GC_MAX_TICK,\n });\n }\n}\n\n/**\n * Asserts that `fee` is one of the fee tiers in `ALL_FEE_TIERS` (`0`, `500`, `3000`, `10000`).\n *\n * @throws GSwapSDKError `INVALID_FEE` (`params.field` `'fee'`, `params.allowed` the tiers).\n */\nexport function validateFee(fee: number): asserts fee is FEE_TIER {\n if (!ALL_FEE_TIERS.some((tier) => Number(tier) === fee)) {\n throw new GSwapSDKError('INVALID_FEE', {\n field: 'fee',\n value: fee,\n allowed: ALLOWED_FEE_TIERS_TEXT,\n });\n }\n}\n\n/**\n * Validates a tick spacing: a positive integer.\n *\n * @throws GSwapSDKError `INVALID_TICK_SPACING`.\n */\nexport function validateTickSpacing(tickSpacing: number): void {\n if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) {\n throw new GSwapSDKError('INVALID_TICK_SPACING', { value: tickSpacing });\n }\n}\n\n/**\n * Asserts that a wallet address was given and is a non-blank string. It does not check the address\n * format.\n *\n * @throws GSwapSDKError `MISSING_WALLET_ADDRESS` (undefined) or `INVALID_WALLET_ADDRESS` (blank).\n */\nexport function validateWalletAddress(address?: string): asserts address is string {\n if (address === undefined) {\n throw new GSwapSDKError('MISSING_WALLET_ADDRESS', {});\n }\n\n if (!address || typeof address !== 'string' || address.trim().length === 0) {\n throw new GSwapSDKError('INVALID_WALLET_ADDRESS', {\n field: 'walletAddress',\n value: String(address),\n });\n }\n}\n\n/** Words the chain gateway refuses as a trading symbol. */\nconst RESERVED_TRADING_SYMBOLS = new Set(['Token', 'Unit', 'none']);\nconst TRADING_SYMBOL_PATTERN = /^[A-Za-z0-9]+$/u;\nconst MAX_TRADING_SYMBOL_LENGTH = 32;\n\n/**\n * True when `symbol` is acceptable to propose into the trading-symbol registry: ASCII letters and\n * digits only, 1 to 32 characters, and not a reserved word (`Token`, `Unit`, `none`) — the rules\n * the chain gateway enforces on a CreatePool symbol.\n */\nexport function isProposableTradingSymbol(symbol: string): boolean {\n return (\n TRADING_SYMBOL_PATTERN.test(symbol) &&\n symbol.length <= MAX_TRADING_SYMBOL_LENGTH &&\n !RESERVED_TRADING_SYMBOLS.has(symbol)\n );\n}\n\n/**\n * Asserts that a pair is in the contract's canonical order (`token0 < token1` by plain string\n * comparison), which every write DTO requires. A pair a caller took from a stale quote or\n * position can be reversed; signing it would sign something other than what was priced.\n *\n * @throws GSwapSDKError `NON_CANONICAL_PAIR` (`params.token0`, `params.token1`) otherwise.\n */\nexport function assertCanonicalPair(token0: string, token1: string): void {\n if (!(token0 < token1)) {\n throw new GSwapSDKError('NON_CANONICAL_PAIR', { token0, token1 });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validation.js","names":["BigNumber","validateNumericAmount","amount","GSwapSDKError","parameterName","bnAmount","allowZero","validatePriceValues","spotPrice","lowerPrice","upperPrice","value","parse","bnSpotPrice","bnLowerPrice","bnUpperPrice","validateTokenDecimals","decimals","validateTickRange","tickLower","tickUpper","GC_MIN_TICK","GC_MAX_TICK","validateFee","ALL_FEE_TIERS","tier","fee","ALLOWED_FEE_TIERS_TEXT","validateTickSpacing","tickSpacing","userRef","galaChainUserRef","field","requireUserRef","address","RESERVED_TRADING_SYMBOLS","TRADING_SYMBOL_PATTERN","isProposableTradingSymbol","symbol","assertCanonicalPair","token0","token1"],"sources":["../../../src/utils/validation.ts"],"sourcesContent":["import { galaChainUserRef } from '@gala-chain/gala-core-sdk';\nimport BigNumber from 'bignumber.js';\nimport { ALLOWED_FEE_TIERS_TEXT } from '../classes/gswap_error_catalog.js';\nimport { GSwapSDKError } from '../classes/gswap_sdk_error.js';\nimport type { NumericAmount } from '../types/amounts.js';\nimport { ALL_FEE_TIERS } from '../types/fees.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { GC_MAX_TICK, GC_MIN_TICK } from './tick_math.js';\n\n/**\n * Validates a decimal amount: a string or `BigNumber`, never a JavaScript number.\n *\n * @param amount - The amount to check.\n * @param parameterName - The field name reported in the error's `params.field`.\n * @param allowZero - Accept zero (default `false`).\n * @throws GSwapSDKError `AMOUNT_IS_JS_NUMBER`, `AMOUNT_NOT_FINITE`, `AMOUNT_NOT_POSITIVE` (zero\n * when `allowZero` is false) or `AMOUNT_NEGATIVE`.\n */\nexport function validateNumericAmount(\n amount: NumericAmount,\n parameterName: string,\n allowZero = false,\n): void {\n if (typeof amount === 'number') {\n throw new GSwapSDKError('AMOUNT_IS_JS_NUMBER', { field: parameterName });\n }\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — substitute an explicit NaN so the isFinite() check below still catches\n // it and raises the same typed error, instead of a raw exception escaping.\n let bnAmount: BigNumber;\n try {\n bnAmount = BigNumber(amount);\n } catch {\n bnAmount = BigNumber(NaN);\n }\n\n if (!bnAmount.isFinite()) {\n throw new GSwapSDKError('AMOUNT_NOT_FINITE', {\n field: parameterName,\n value: String(amount),\n });\n }\n\n if (!allowZero && bnAmount.isZero()) {\n throw new GSwapSDKError('AMOUNT_NOT_POSITIVE', {\n field: parameterName,\n value: String(amount),\n });\n }\n\n if (bnAmount.isNegative()) {\n throw new GSwapSDKError('AMOUNT_NEGATIVE', { field: parameterName, value: String(amount) });\n }\n}\n\n/**\n * Validates a spot price and a lower/upper price range: none a JavaScript number, all positive and\n * finite (a non-finite upper bound counts as an unbounded `1e18`), and `lowerPrice <= upperPrice`.\n *\n * @throws GSwapSDKError `PRICE_VALUES_IS_JS_NUMBER`, `INVALID_PRICE_VALUES` or `INVALID_PRICE_RANGE`.\n */\nexport function validatePriceValues(\n spotPrice: NumericAmount,\n lowerPrice: NumericAmount,\n upperPrice: NumericAmount,\n): void {\n if ([spotPrice, lowerPrice, upperPrice].some((value) => typeof value === 'number')) {\n throw new GSwapSDKError('PRICE_VALUES_IS_JS_NUMBER', {});\n }\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — substitute an explicit NaN so the isFinite()/isPositive() checks below\n // still catch it and raise the same typed error, instead of a raw exception escaping.\n const parse = (value: NumericAmount): BigNumber => {\n try {\n return BigNumber(value);\n } catch {\n return BigNumber(NaN);\n }\n };\n const bnSpotPrice = parse(spotPrice);\n const bnLowerPrice = parse(lowerPrice);\n let bnUpperPrice = parse(upperPrice);\n\n bnUpperPrice = bnUpperPrice.isFinite() ? bnUpperPrice : BigNumber(1e18);\n\n if (\n !bnSpotPrice.isFinite() ||\n !bnLowerPrice.isFinite() ||\n !bnUpperPrice.isFinite() ||\n !bnSpotPrice.isPositive() ||\n !bnLowerPrice.isPositive() ||\n !bnUpperPrice.isPositive()\n ) {\n throw new GSwapSDKError('INVALID_PRICE_VALUES', {\n spotPrice: String(spotPrice),\n lowerPrice: String(lowerPrice),\n upperPrice: String(upperPrice),\n });\n }\n\n if (bnLowerPrice.isGreaterThan(bnUpperPrice)) {\n throw new GSwapSDKError('INVALID_PRICE_RANGE', {\n lowerPrice: String(lowerPrice),\n upperPrice: String(upperPrice),\n });\n }\n}\n\n/**\n * Validates a token's decimals: a non-negative integer.\n *\n * @throws GSwapSDKError `INVALID_TOKEN_DECIMALS` (`params.field` is `parameterName`).\n */\nexport function validateTokenDecimals(decimals: number, parameterName: string): void {\n if (decimals < 0 || !Number.isInteger(decimals)) {\n throw new GSwapSDKError('INVALID_TOKEN_DECIMALS', { field: parameterName, value: decimals });\n }\n}\n\n/**\n * Validates a position's tick range: two integers with `tickLower < tickUpper`, both within\n * `GC_MIN_TICK`..`GC_MAX_TICK`. It does not check alignment to a fee tier's spacing (see\n * `assertTickRange`).\n *\n * @throws GSwapSDKError `TICKS_NOT_INTEGERS`, `INVALID_TICK_RANGE` or `TICKS_OUT_OF_BOUNDS`.\n */\nexport function validateTickRange(tickLower: number, tickUpper: number): void {\n if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper)) {\n throw new GSwapSDKError('TICKS_NOT_INTEGERS', { tickLower, tickUpper });\n }\n\n if (tickLower >= tickUpper) {\n throw new GSwapSDKError('INVALID_TICK_RANGE', { tickLower, tickUpper });\n }\n\n if (tickLower < GC_MIN_TICK || tickUpper > GC_MAX_TICK) {\n throw new GSwapSDKError('TICKS_OUT_OF_BOUNDS', {\n tickLower,\n tickUpper,\n minTick: GC_MIN_TICK,\n maxTick: GC_MAX_TICK,\n });\n }\n}\n\n/**\n * Asserts that `fee` is one of the fee tiers in `ALL_FEE_TIERS` (`0`, `500`, `3000`, `10000`).\n *\n * @throws GSwapSDKError `INVALID_FEE` (`params.field` `'fee'`, `params.allowed` the tiers).\n */\nexport function validateFee(fee: number): asserts fee is FEE_TIER {\n if (!ALL_FEE_TIERS.some((tier) => Number(tier) === fee)) {\n throw new GSwapSDKError('INVALID_FEE', {\n field: 'fee',\n value: fee,\n allowed: ALLOWED_FEE_TIERS_TEXT,\n });\n }\n}\n\n/**\n * Validates a tick spacing: a positive integer.\n *\n * @throws GSwapSDKError `INVALID_TICK_SPACING`.\n */\nexport function validateTickSpacing(tickSpacing: number): void {\n if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) {\n throw new GSwapSDKError('INVALID_TICK_SPACING', { value: tickSpacing });\n }\n}\n\n/**\n * The GalaChain user reference an owner, user or wallet address names, in the one spelling the\n * gateway and the swap backend accept: `eth|<EIP-55 checksummed digits>` for an Ethereum account\n * (given as `eth|<40 hex>` in any casing, `eth|0x<40 hex>`, `0x<40 hex>` or bare hex), `client|<id>`\n * as written. This is `galaChainUserRef` of `@gala-chain/gala-core-sdk`, the one implementation;\n * only the error is this package's. Every place this SDK puts a user identity on the wire goes\n * through it, so what is signed, sent and compared on the backend (`owner === position.owner`,\n * strict) is always the chain's own spelling.\n *\n * @param value - The identity the caller gave.\n * @param field - The field name reported in the error's `params.field`.\n * @throws GSwapSDKError `INVALID_WALLET_ADDRESS` for anything else, a mixed-case spelling whose\n * casing is not the EIP-55 checksum included (a typo); nothing is signed or sent.\n */\nexport function userRef(value: unknown, field: string): string {\n try {\n return galaChainUserRef(value, field);\n } catch {\n throw new GSwapSDKError('INVALID_WALLET_ADDRESS', { field, value: String(value) });\n }\n}\n\n/**\n * {@link userRef} of an address that must be there.\n *\n * @throws GSwapSDKError `MISSING_WALLET_ADDRESS` (undefined) or `INVALID_WALLET_ADDRESS`.\n */\nexport function requireUserRef(address: string | undefined, field: string): string {\n if (address === undefined) {\n throw new GSwapSDKError('MISSING_WALLET_ADDRESS', {});\n }\n return userRef(address, field);\n}\n\n/** Words the chain gateway refuses as a trading symbol. */\nconst RESERVED_TRADING_SYMBOLS = new Set(['Token', 'Unit', 'none']);\nconst TRADING_SYMBOL_PATTERN = /^[A-Za-z0-9]+$/u;\nconst MAX_TRADING_SYMBOL_LENGTH = 32;\n\n/**\n * True when `symbol` is acceptable to propose into the trading-symbol registry: ASCII letters and\n * digits only, 1 to 32 characters, and not a reserved word (`Token`, `Unit`, `none`) — the rules\n * the chain gateway enforces on a CreatePool symbol.\n */\nexport function isProposableTradingSymbol(symbol: string): boolean {\n return (\n TRADING_SYMBOL_PATTERN.test(symbol) &&\n symbol.length <= MAX_TRADING_SYMBOL_LENGTH &&\n !RESERVED_TRADING_SYMBOLS.has(symbol)\n );\n}\n\n/**\n * Asserts that a pair is in the contract's canonical order (`token0 < token1` by plain string\n * comparison), which every write DTO requires. A pair a caller took from a stale quote or\n * position can be reversed; signing it would sign something other than what was priced.\n *\n * @throws GSwapSDKError `NON_CANONICAL_PAIR` (`params.token0`, `params.token1`) otherwise.\n */\nexport function assertCanonicalPair(token0: string, token1: string): void {\n if (!(token0 < token1)) {\n throw new GSwapSDKError('NON_CANONICAL_PAIR', { token0, token1 });\n }\n}\n"],"mappings":"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"}