@gala-chain/gswap-sdk 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["BigNumber","Decimal","BigNumber","asRecord","trimTrailingSlash","resolveSymbol","BigNumber","toDecimalString","resolveSymbol","BigNumber","BigNumber","serialize","globalObject","signatures"],"sources":["../src/classes/gswap_sdk_error.ts","../src/types/fees.ts","../src/utils/ticks.ts","../src/utils/validation.ts","../src/classes/assets.ts","../src/utils/transport.ts","../src/classes/submitted_transaction.ts","../src/classes/gateway.ts","../src/utils/debug.ts","../src/version.ts","../src/classes/http_client.ts","../src/utils/ordering.ts","../src/classes/pools.ts","../src/classes/positions.ts","../src/classes/quoting.ts","../src/classes/symbols.ts","../src/classes/swaps.ts","../src/types/env.ts","../src/classes/gswap.ts","../src/utils/eip712.ts","../src/classes/signers.ts"],"sourcesContent":["import type { GalaChainTokenClassKey } from '../types/token.js';\nimport type { HTTPResponse } from '../types/http_requestor.js';\n\n/** Error raised by the SDK for validation, gateway, chain, or transaction failures. */\nexport class GSwapSDKError extends Error {\n public readonly chainMessage: string | undefined;\n public readonly retryAfterMs: number | undefined;\n\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n chainMessage?: string,\n retryAfterMs?: number,\n ) {\n super(message);\n this.name = 'GSwapSDKError';\n this.chainMessage = chainMessage;\n this.retryAfterMs = retryAfterMs;\n }\n\n /** Create the standard missing-signer error. */\n public static noSignerError(): GSwapSDKError {\n return new GSwapSDKError(\n 'This method requires a signer. Please provide a signer to the GSwap constructor.',\n 'NO_SIGNER',\n );\n }\n\n /** Create the error used when confirming a position write without a configured wallet address. */\n public static noWalletAddressError(): GSwapSDKError {\n return new GSwapSDKError(\n 'Cannot confirm this write: no walletAddress was provided to the GSwap constructor, so ' +\n 'the resulting position cannot be looked up to confirm it landed on chain.',\n 'NO_WALLET_ADDRESS',\n );\n }\n\n /** Create the error used when no pool can quote the requested pair. */\n public static noPoolAvailableError(\n tokenIn: GalaChainTokenClassKey | string,\n tokenOut: GalaChainTokenClassKey | string,\n fee?: number,\n ): GSwapSDKError {\n return new GSwapSDKError('No pool is available for the requested pair.', 'NO_POOL_AVAILABLE', {\n tokenIn,\n tokenOut,\n ...(fee === undefined ? {} : { fee }),\n });\n }\n\n /** Create the error used when a pool lacks liquidity for a quote. */\n public static insufficientLiquidityError(\n tokenIn: GalaChainTokenClassKey | string,\n tokenOut: GalaChainTokenClassKey | string,\n fee?: number,\n ): GSwapSDKError {\n return new GSwapSDKError(\n 'The selected pool has insufficient liquidity for the requested quote.',\n 'INSUFFICIENT_LIQUIDITY',\n { tokenIn, tokenOut, ...(fee === undefined ? {} : { fee }) },\n );\n }\n\n /** Convert a chain-gateway bounce into a typed SDK error. */\n public static fromGatewayBounce(\n code: string,\n message: string,\n status: number,\n retryAfterMs?: number,\n ): GSwapSDKError {\n const details: Record<string, unknown> = { status, chainMessage: message };\n if (retryAfterMs !== undefined) details['retryAfterMs'] = retryAfterMs;\n const sdkMessage =\n code === 'CHAIN_DISPATCH_FAILED' ? message : `Gateway rejected ${code}: ${message}`;\n return new GSwapSDKError(sdkMessage, code, details, message, retryAfterMs);\n }\n\n /** Convert a GalaChain `Status: 0` response into a typed SDK error. */\n public static fromChainError(\n errorKey: string,\n message: string,\n details?: Record<string, unknown>,\n ): GSwapSDKError {\n return new GSwapSDKError(\n `GalaChain error ${errorKey}: ${message}`,\n errorKey,\n { ...details, errorKey, message },\n message,\n );\n }\n\n /** Create the error used when a token is not registered by the current DEX contract. */\n public static unknownTokenError(token: GalaChainTokenClassKey | string): GSwapSDKError {\n const tokenText = typeof token === 'string' ? token : JSON.stringify(token);\n return new GSwapSDKError(\n `Token ${tokenText} has no trading symbol on the new DEX contract (no gcdex pool includes it yet).`,\n 'UNKNOWN_TOKEN',\n { token },\n );\n }\n\n /** Create the error used when apply-results confirmation does not arrive in time. */\n public static confirmationTimeoutError(uniqueKey: string, cause?: unknown): GSwapSDKError {\n return new GSwapSDKError(\n 'Transaction confirmation timed out; the trade may still apply. Confirm the same uniqueKey again later instead of resubmitting.',\n 'CONFIRMATION_TIMEOUT',\n { uniqueKey, ...(cause === undefined ? {} : { cause }) },\n );\n }\n\n /** Convert an unexpected HTTP response into an SDK error. */\n public static async fromErrorResponse(\n url: string,\n response: HTTPResponse,\n ): Promise<GSwapSDKError> {\n const bodyText = await response.text();\n const bodyJson: unknown = parseJson(bodyText);\n const errorObject = getObjectProperty(bodyJson, 'error');\n const errorKey = getStringProperty(errorObject, 'ErrorKey');\n const message = getStringProperty(errorObject, 'Message');\n\n if (errorKey !== undefined && message !== undefined) {\n return new GSwapSDKError(\n `GalaChain Error ${errorKey} from ${url}: ${message}`,\n errorKey,\n { message, errorKey, status: response.status, body: bodyJson, url },\n message,\n );\n }\n\n return new GSwapSDKError(`Unexpected HTTP Error ${response.status} from ${url}`, 'HTTP_ERROR', {\n status: response.status,\n body: bodyJson ?? bodyText,\n url,\n });\n }\n}\n\n/** Narrow an object property without trusting a cast at a network boundary. */\nexport function getObjectProperty(\n value: unknown,\n property: string,\n): Record<string, unknown> | undefined {\n if (typeof value !== 'object' || value === null || !(property in value)) return undefined;\n const propertyValue = (value as Record<string, unknown>)[property];\n return typeof propertyValue === 'object' && propertyValue !== null\n ? (propertyValue as Record<string, unknown>)\n : undefined;\n}\n\n/** Read a string property from an unknown object. */\nexport function getStringProperty(value: unknown, property: string): string | undefined {\n if (typeof value !== 'object' || value === null || !(property in value)) return undefined;\n const propertyValue = (value as Record<string, unknown>)[property];\n return typeof propertyValue === 'string' ? propertyValue : undefined;\n}\n\n/** Parse a response body, preserving non-JSON text for error reporting. */\nexport function parseJson(text: string): unknown {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return undefined;\n }\n}\n","/**\n * Fee tiers for pools.\n */\nexport enum FEE_TIER {\n /** No trading fee. */\n PERCENT_00_00 = 0,\n /** 0.05% fee tier */\n PERCENT_00_05 = 500,\n /** 0.3% fee tier */\n PERCENT_00_30 = 3000,\n /** 1.0% fee tier */\n PERCENT_01_00 = 10000,\n}\n\n/** Tick spacing required by the current GalaChainDex contract for each fee tier. */\nexport const TICK_SPACING_BY_FEE: Readonly<Record<FEE_TIER, number>> = {\n [FEE_TIER.PERCENT_00_00]: 200,\n [FEE_TIER.PERCENT_00_05]: 10,\n [FEE_TIER.PERCENT_00_30]: 60,\n [FEE_TIER.PERCENT_01_00]: 200,\n};\n\n/** All fee tiers supported by the current GalaChainDex contract. */\nexport const ALL_FEE_TIERS: readonly FEE_TIER[] = [\n FEE_TIER.PERCENT_00_00,\n FEE_TIER.PERCENT_00_05,\n FEE_TIER.PERCENT_00_30,\n FEE_TIER.PERCENT_01_00,\n];\n","import BigNumber from 'bignumber.js';\nimport { Decimal } from 'decimal.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { TICK_SPACING_BY_FEE } from '../types/fees.js';\n\n/** Minimum tick supported by GalaChainDex. */\nexport const GC_MIN_TICK = -887272;\n/** Maximum tick supported by GalaChainDex. */\nexport const GC_MAX_TICK = 887272;\n\nconst DexMath = BigNumber.clone({\n DECIMAL_PLACES: 60,\n ROUNDING_MODE: BigNumber.ROUND_DOWN,\n});\nconst DexDecimal = Decimal.clone({ precision: 60 });\n\n/** Convert a tick to the corresponding square-root price. */\nexport function tickToSqrtPrice(tick: number): BigNumber {\n return new BigNumber(new DexDecimal(1.0001).pow(tick / 2).toString());\n}\n\n/** Return the greatest tick whose square-root price is no greater than the input. */\nexport function sqrtPriceToTick(sqrtPrice: BigNumber.Value): number {\n let value: BigNumber;\n try {\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — this function's contract is to signal an invalid input via NaN, not\n // to throw, so an unparseable value is just another case for the guard below.\n value = new DexMath(sqrtPrice);\n } catch {\n return Number.NaN;\n }\n if (!value.isFinite() || value.isLessThanOrEqualTo(0)) return Number.NaN;\n\n const approximate = Math.log(value.toNumber() ** 2) / Math.log(1.0001);\n if (!Number.isFinite(approximate)) return Number.NaN;\n // Clamp the seed before the correction loops below — an unclamped seed derived from an\n // out-of-range sqrtPrice (extreme but finite, e.g. 1e20) leaves the loops running past\n // GC_MIN_TICK/GC_MAX_TICK for a long time; an infinite (overflowed) seed would never\n // enter the increasing loop and never terminate the decreasing one.\n let tick = Math.min(GC_MAX_TICK, Math.max(GC_MIN_TICK, Math.floor(approximate)));\n while (tick < GC_MAX_TICK && tickToSqrtPrice(tick + 1).isLessThanOrEqualTo(value)) tick += 1;\n while (tick > GC_MIN_TICK && tickToSqrtPrice(tick).isGreaterThan(value)) tick -= 1;\n return tick;\n}\n\n/** Return the greatest integer tick whose token1/token0 price is no greater than `price`. */\nexport function tickFromPrice(price: BigNumber.Value): number {\n const priceText =\n typeof price === 'string'\n ? price\n : typeof price === 'number'\n ? price.toString()\n : BigNumber.isBigNumber(price)\n ? price.toString()\n : 'NaN';\n const value = new DexDecimal(priceText);\n if (!value.isFinite() || value.lessThanOrEqualTo(0)) return Number.NaN;\n if (!Number.isFinite(value.toNumber())) return Number.NaN;\n const tick = value.ln().dividedBy(new DexDecimal(1.0001).ln()).floor().toNumber();\n return Number.isFinite(tick) ? tick : Number.NaN;\n}\n\n/** Align a tick down to the nearest multiple of a positive spacing. */\nexport function alignTickDown(tick: number, spacing: number): number {\n assertSpacing(spacing);\n return Math.floor(tick / spacing) * spacing;\n}\n\n/** Align a tick up to the nearest multiple of a positive spacing. */\nexport function alignTickUp(tick: number, spacing: number): number {\n assertSpacing(spacing);\n return Math.ceil(tick / spacing) * spacing;\n}\n\n/** Validate a position range against the global tick bounds and fee-tier spacing. */\nexport function assertTickRange(lower: number, upper: number, fee: FEE_TIER): void {\n const spacing = TICK_SPACING_BY_FEE[fee];\n if (spacing === undefined) throw new RangeError(`Unsupported fee tier: ${fee}`);\n if (!Number.isInteger(lower) || !Number.isInteger(upper)) {\n throw new RangeError('Ticks must be integers');\n }\n if (lower < GC_MIN_TICK || upper > GC_MAX_TICK || lower >= upper) {\n throw new RangeError(\n `Tick range must satisfy ${GC_MIN_TICK} <= lower < upper <= ${GC_MAX_TICK}`,\n );\n }\n if (lower % spacing !== 0 || upper % spacing !== 0) {\n throw new RangeError(`Ticks must be aligned to spacing ${spacing}`);\n }\n}\n\nfunction assertSpacing(spacing: number): void {\n if (!Number.isInteger(spacing) || spacing <= 0)\n throw new RangeError('Tick spacing must be positive');\n}\n","import BigNumber from 'bignumber.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 './ticks.js';\n\nexport function validateNumericAmount(\n amount: NumericAmount,\n parameterName: string,\n allowZero = false,\n): void {\n if (typeof amount === 'number') {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: use a decimal string or BigNumber, not a JavaScript number`,\n 'VALIDATION_ERROR',\n { type: 'INVALID_NUMERIC_AMOUNT', parameterName, value: amount, reason: 'number_input' },\n );\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(\n `Invalid ${parameterName}: must be a finite number`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_NUMERIC_AMOUNT',\n parameterName,\n value: amount,\n reason: 'not_finite',\n },\n );\n }\n\n if (!allowZero && bnAmount.isZero()) {\n throw new GSwapSDKError(`Invalid ${parameterName}: must be positive`, 'VALIDATION_ERROR', {\n type: 'INVALID_NUMERIC_AMOUNT',\n parameterName,\n value: amount,\n reason: 'zero_not_allowed',\n });\n }\n\n if (bnAmount.isNegative()) {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: must be ${allowZero ? 'non-negative' : 'positive'}`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_NUMERIC_AMOUNT',\n parameterName,\n value: amount,\n reason: 'negative',\n },\n );\n }\n}\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(\n 'Invalid price values: use decimal strings or BigNumber values, not JavaScript numbers',\n 'VALIDATION_ERROR',\n { type: 'INVALID_NUMERIC_AMOUNT', reason: 'number_input' },\n );\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(\n 'Invalid price values: all prices must be finite and positive',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_PRICE_VALUES',\n spotPrice,\n lowerPrice,\n upperPrice,\n },\n );\n }\n\n if (bnLowerPrice.isGreaterThan(bnUpperPrice)) {\n throw new GSwapSDKError(\n 'Invalid price range: lower price must be less than or equal to upper price',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_PRICE_RANGE',\n lowerPrice,\n upperPrice,\n },\n );\n }\n}\n\nexport function validateTokenDecimals(decimals: number, parameterName: string): void {\n if (decimals < 0 || !Number.isInteger(decimals)) {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: must be a non-negative integer`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TOKEN_DECIMALS',\n parameterName,\n value: decimals,\n },\n );\n }\n}\n\nexport function validateTickRange(tickLower: number, tickUpper: number): void {\n if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper)) {\n throw new GSwapSDKError('Invalid tick values: ticks must be integers', 'VALIDATION_ERROR', {\n type: 'INVALID_TICK_VALUES',\n tickLower,\n tickUpper,\n });\n }\n\n if (tickLower >= tickUpper) {\n throw new GSwapSDKError(\n 'Invalid tick range: tickLower must be less than tickUpper',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TICK_RANGE',\n tickLower,\n tickUpper,\n },\n );\n }\n\n if (tickLower < GC_MIN_TICK || tickUpper > GC_MAX_TICK) {\n throw new GSwapSDKError(\n `Invalid tick range: ticks must be between ${GC_MIN_TICK} and ${GC_MAX_TICK}`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TICK_BOUNDS',\n tickLower,\n tickUpper,\n minTick: GC_MIN_TICK,\n maxTick: GC_MAX_TICK,\n },\n );\n }\n}\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(\n 'Invalid fee tier: must be one of 0, 500, 3000, or 10000',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_FEE',\n value: fee,\n },\n );\n }\n}\n\nexport function validateTickSpacing(tickSpacing: number): void {\n if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) {\n throw new GSwapSDKError(\n 'Invalid tick spacing: must be a positive integer',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TICK_SPACING',\n value: tickSpacing,\n },\n );\n }\n}\n\nexport function validateWalletAddress(address?: string): asserts address is string {\n if (address === undefined) {\n throw new GSwapSDKError(\n 'Invalid wallet address: No wallet address provided',\n 'VALIDATION_ERROR',\n {\n type: 'MISSING_WALLET_ADDRESS',\n hint: 'Either provide a wallet address to the function you are calling, or set one when instantiating GSwapSDK',\n },\n );\n }\n\n if (!address || typeof address !== 'string' || address.trim().length === 0) {\n throw new GSwapSDKError(\n 'Invalid wallet address: must be a non-empty string',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_WALLET_ADDRESS',\n value: address,\n },\n );\n }\n}\n","import type { UserAsset, UserAssetsResult } from '../types/v2_results.js';\nimport { validateWalletAddress } from '../utils/validation.js';\nimport { getObjectProperty, GSwapSDKError } from './gswap_sdk_error.js';\nimport type { HttpClient } from './http_client.js';\n\n/**\n * Service for handling user asset operations.\n * Provides functionality to retrieve user token balances and asset information.\n */\nexport class Assets {\n constructor(\n private readonly dexBackendBaseUrl: string,\n private readonly httpClient: HttpClient,\n ) {}\n\n /**\n * Gets all token assets owned by a user with their balances.\n * @param ownerAddress - The wallet address to get assets for.\n * @param page - Page number for pagination (default: 1).\n * @param limit - Maximum number of assets to return per page (default: 10).\n * @returns User assets including token information and balances.\n * @example\n * ```typescript\n * const assets = await assetsService.getUserAssets('eth|123...abc', 1, 20);\n * console.log(`User has ${assets.count} different tokens`);\n * assets.tokens.forEach(token => {\n * console.log(`${token.symbol}: ${token.quantity}`);\n * });\n * ```\n */\n async getUserAssets(\n ownerAddress: string,\n page: number = 1,\n limit: number = 10,\n ): Promise<UserAssetsResult> {\n validateWalletAddress(ownerAddress);\n\n if (!Number.isInteger(page) || page < 1) {\n throw new GSwapSDKError('Invalid page: must be a positive integer', 'VALIDATION_ERROR', {\n page,\n });\n }\n\n if (!Number.isInteger(limit) || limit < 1 || limit > 100) {\n throw new GSwapSDKError(\n 'Invalid limit: must be an integer between 1 and 100',\n 'VALIDATION_ERROR',\n { limit },\n );\n }\n\n const json: unknown = await this.httpClient.sendGetRequest(\n this.dexBackendBaseUrl,\n '/user/assets',\n '',\n { address: ownerAddress, page: page.toString(), limit: limit.toString() },\n );\n return parseUserAssets(json);\n }\n}\n\nfunction parseUserAssets(value: unknown): UserAssetsResult {\n const data = getObjectProperty(value, 'data');\n // Not getObjectProperty — that's typed for object properties, and Array.isArray on its\n // Record<string, unknown> return type narrows to any[] instead of a real array type.\n const tokens: unknown = data?.['token'];\n if (!Array.isArray(tokens) || !tokens.every(isRawUserAsset)) {\n throw new GSwapSDKError(\n 'Backend returned an invalid user assets response.',\n 'INVALID_CHAIN_RESPONSE',\n {\n data: value,\n },\n );\n }\n const count = data?.['count'];\n return {\n tokens: tokens.map((token) => ({ ...token, decimals: parseInt(token.decimals, 10) })),\n count: typeof count === 'number' ? count : 0,\n };\n}\n\ntype RawUserAsset = Omit<UserAsset, 'decimals'> & { decimals: string };\n\nfunction isRawUserAsset(value: unknown): value is RawUserAsset {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Record<string, unknown>;\n return (\n typeof entry['image'] === 'string' &&\n typeof entry['name'] === 'string' &&\n typeof entry['decimals'] === 'string' &&\n /^\\d+$/u.test(entry['decimals']) &&\n typeof entry['verify'] === 'boolean' &&\n typeof entry['symbol'] === 'string' &&\n typeof entry['quantity'] === 'string'\n );\n}\n","import type { HTTPResponse, HttpRequestor } from '../types/http_requestor.js';\nimport { GSwapSDKError, parseJson } from '../classes/gswap_sdk_error.js';\n\nexport async function requestWithTimeout(\n requestor: HttpRequestor,\n url: string,\n options: RequestInit,\n timeoutMs: number,\n): Promise<HTTPResponse> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const externalSignal = options.signal;\n const abortFromCaller = (): void => controller.abort();\n externalSignal?.addEventListener('abort', abortFromCaller, { once: true });\n try {\n return await requestor(url, { ...options, signal: controller.signal });\n } catch (error: unknown) {\n if (controller.signal.aborted) {\n throw new GSwapSDKError(`Request timed out after ${timeoutMs} ms.`, 'REQUEST_TIMEOUT', {\n url,\n timeoutMs,\n cause: error,\n });\n }\n throw error;\n } finally {\n clearTimeout(timer);\n externalSignal?.removeEventListener('abort', abortFromCaller);\n }\n}\n\nexport async function readResponseBody(response: HTTPResponse): Promise<unknown> {\n const text = await response.text();\n return parseJson(text) ?? text;\n}\n\n/** Read a case-insensitive response header from either supported header shape. */\nexport function readHeader(response: HTTPResponse, name: string): string | undefined {\n const headers = response.headers;\n if (headers === undefined) return undefined;\n if (hasHeaderGetter(headers)) {\n const value = headers.get(name);\n return value === null || value === '' ? undefined : value;\n }\n const value = Object.entries(headers).find(\n ([key]) => key.toLowerCase() === name.toLowerCase(),\n )?.[1];\n return value === undefined || value === '' ? undefined : value;\n}\n\n/** Read a non-negative Retry-After header as milliseconds. */\nexport function readRetryAfter(response: HTTPResponse): number | undefined {\n const raw = readHeader(response, 'retry-after');\n if (raw === undefined) return undefined;\n const seconds = Number(raw);\n return Number.isFinite(seconds) && seconds >= 0 ? seconds * 1000 : undefined;\n}\n\n/** Read a non-negative integer block number header. */\nexport function readBlockNumberHeader(\n response: HTTPResponse,\n headerName = 'x-block-number',\n): number | undefined {\n const raw = readHeader(response, headerName);\n if (raw === undefined) return undefined;\n const blockNumber = Number(raw);\n return Number.isInteger(blockNumber) && blockNumber >= 0 ? blockNumber : undefined;\n}\n\nfunction hasHeaderGetter(\n headers: NonNullable<HTTPResponse['headers']>,\n): headers is { get(name: string): string | null } {\n return 'get' in headers && typeof headers.get === 'function';\n}\n","import type { HttpRequestor, HTTPResponse } from '../types/http_requestor.js';\nimport type { AppliedTrade, Position, TradeExecution } from '../types/v2_results.js';\nimport { GSwapSDKError, getObjectProperty, getStringProperty } from './gswap_sdk_error.js';\nimport {\n readBlockNumberHeader,\n readHeader,\n readResponseBody,\n readRetryAfter,\n requestWithTimeout,\n} from '../utils/transport.js';\n\n/** Result of one position-confirmation poll. */\nexport type PositionConfirmationResult =\n { confirmed: true; position: Position | null } | { confirmed: false; position?: Position | null };\n\n/** A submitted v2 transaction whose confirmation mode is explicit in the gateway response. */\nexport class SubmittedTransaction<TConfirmation = AppliedTrade | Position | null> {\n public readonly method: string;\n public readonly uniqueKey: string;\n public readonly transactionId: string | null;\n public readonly blockNumber: number | null;\n public readonly mode: 'sync' | 'queued';\n /** The synchronous gateway result, or `undefined` when `mode === 'queued'`. */\n public readonly result: unknown;\n private readonly backendBaseUrl: string;\n private readonly requestor: HttpRequestor;\n private readonly requestTimeoutMs: number;\n private readonly positionConfirmation:\n ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;\n\n /** Construct a submitted transaction from a successful gateway response.\n *\n * @example\n * ```ts\n * const transaction = new SubmittedTransaction({\n * method: 'RequestTrade', mode: 'queued', uniqueKey: 'swap-1',\n * transactionId: 'request-tx', result: undefined,\n * dexBackendBaseUrl: 'https://dex.example', httpRequestor,\n * });\n * ```\n */\n constructor(options: {\n method: string;\n uniqueKey: string;\n transactionId: string | null;\n mode: 'sync' | 'queued';\n result: unknown;\n dexBackendBaseUrl: string;\n httpRequestor: HttpRequestor;\n blockNumber?: number | null | undefined;\n requestTimeoutMs?: number | undefined;\n positionConfirmation?:\n ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;\n }) {\n this.method = options.method;\n this.uniqueKey = options.uniqueKey;\n this.transactionId = options.transactionId;\n this.blockNumber = options.blockNumber ?? null;\n this.mode = options.mode;\n this.result = options.result;\n this.backendBaseUrl = options.dexBackendBaseUrl.replace(/\\/$/u, '');\n this.requestor = options.httpRequestor;\n this.requestTimeoutMs = options.requestTimeoutMs ?? 30_000;\n this.positionConfirmation = options.positionConfirmation;\n }\n\n /** Confirm a queued RequestTrade or prove the affected position for a liquidity write.\n *\n * For RequestTrade, calling this method is required to learn the outcome: the queued\n * acknowledgement proves acceptance, not execution.\n *\n * @example\n * ```ts\n * const applied = await submitted.confirm({ initialDelayMs: 3_000 });\n * ```\n */\n public async confirm(options?: ConfirmOptions): Promise<TConfirmation> {\n if (this.method === 'RequestTrade') {\n return this.confirmApplied(options) as Promise<TConfirmation>;\n }\n return this.confirmPosition(options) as Promise<TConfirmation>;\n }\n\n private async confirmApplied(options?: ConfirmOptions): Promise<AppliedTrade> {\n // The AutoApplier waits at least 2 s before applying and the apply lands ~6-8 s after the\n // acknowledgement, so a read at t=0 is a guaranteed 404.\n const schedule = createConfirmationSchedule(options, 3_000);\n await schedule.waitForRead();\n const url = `${this.backendBaseUrl}/v1/chain/apply-results/${encodeURIComponent(this.uniqueKey)}?channel=asset&contract=dex-contract`;\n let lastError: unknown;\n\n while (true) {\n let response: HTTPResponse;\n let body: unknown;\n try {\n response = await requestWithTimeout(\n this.requestor,\n url,\n { method: 'GET' },\n this.requestTimeoutMs,\n );\n body = await readResponseBody(response);\n } catch (error: unknown) {\n lastError = error;\n if (!(await schedule.waitForRead())) break;\n continue;\n }\n if (response.status === 200) {\n return this.readAppliedResult(response, body, url);\n }\n if (response.status === 404 || response.status === 429 || isTransient(response.status)) {\n if (response.status === 429) {\n const retryAfter = readRetryAfter(response);\n if (retryAfter !== undefined) {\n if (!(await schedule.waitForRead(retryAfter))) break;\n continue;\n }\n }\n } else {\n throw new GSwapSDKError(bodyMessage(body), 'CONFIRMATION_FAILED', {\n status: response.status,\n body,\n url,\n });\n }\n if (!(await schedule.waitForRead())) break;\n }\n throw GSwapSDKError.confirmationTimeoutError(this.uniqueKey, lastError);\n }\n\n private readAppliedResult(response: HTTPResponse, body: unknown, url: string): AppliedTrade {\n const record = asRecord(body);\n const status = record?.['Status'];\n const applyTransactionId = readHeader(response, 'x-apply-transaction-id') ?? null;\n const blockNumber = readBlockNumberHeader(response, 'x-apply-block-number') ?? null;\n if (status === 0) {\n throw GSwapSDKError.fromChainError(\n getStringProperty(record, 'ErrorKey') ?? 'CHAIN_ERROR',\n getStringProperty(record, 'Message') ?? 'The chain rejected this trade.',\n {\n uniqueKey: this.uniqueKey,\n applyTransactionId,\n blockNumber,\n status: response.status,\n body,\n url,\n },\n );\n }\n if (status !== 1) throw malformedConfirmation(response, body, url);\n const result = parseTradeExecution(record?.['Data']);\n if (result === undefined) throw malformedConfirmation(response, body, url);\n return {\n uniqueKey: this.uniqueKey,\n transactionId: applyTransactionId,\n blockNumber,\n requestTransactionId: this.transactionId,\n result,\n };\n }\n\n /** Confirm a liquidity write against the position's observable effect.\n *\n * @returns The position after the write, or `null` for a confirmed full close.\n * @example\n * ```ts\n * const position = await submitted.confirm({ timeoutMs: 60_000 });\n * ```\n */\n private async confirmPosition(options?: ConfirmOptions): Promise<Position | null> {\n if (this.positionConfirmation === undefined) throw GSwapSDKError.noWalletAddressError();\n // A liquidity write has already executed when the gateway answers, so the first re-read\n // happens immediately unless the caller asks for a delay.\n const schedule = createConfirmationSchedule(options, 0);\n await schedule.waitForRead();\n while (true) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);\n try {\n const result = await this.positionConfirmation(controller.signal);\n if (result.confirmed) return result.position;\n } finally {\n clearTimeout(timer);\n }\n if (!(await schedule.waitForRead())) break;\n }\n throw GSwapSDKError.confirmationTimeoutError(this.uniqueKey);\n }\n}\n\n/**\n * Controls timeout and polling behavior for confirmation.\n *\n * - `timeoutMs` (default 60 000): overall deadline, counted from the `confirm()` call and\n * including `initialDelayMs`. At least one read is always made.\n * - `pollIntervalMs` (default 2 000, minimum 500): base interval, doubled with jitter up to 8 s.\n * - `initialDelayMs`: wait before the first read. Defaults to 3 000 for a queued RequestTrade\n * (the AutoApplier needs a few seconds) and 0 for liquidity writes (already executed).\n */\nexport interface ConfirmOptions {\n timeoutMs?: number | undefined;\n pollIntervalMs?: number | undefined;\n initialDelayMs?: number | undefined;\n}\n\ninterface ConfirmationSchedule {\n waitForRead(retryAfterMs?: number): Promise<boolean>;\n}\n\nfunction createConfirmationSchedule(\n options: ConfirmOptions | undefined,\n defaultInitialDelayMs: number,\n): ConfirmationSchedule {\n const timeoutMs = Math.max(0, options?.timeoutMs ?? 60_000);\n const pollIntervalMs = Math.max(500, options?.pollIntervalMs ?? 2_000);\n const initialDelayMs = Math.max(0, options?.initialDelayMs ?? defaultInitialDelayMs);\n const deadline = Date.now() + timeoutMs;\n let firstRead = true;\n let attempt = 0;\n return {\n async waitForRead(retryAfterMs?: number): Promise<boolean> {\n if (firstRead) {\n firstRead = false;\n const remaining = Math.max(0, deadline - Date.now());\n await delay(Math.min(initialDelayMs, remaining));\n return true;\n }\n const backoff = Math.min(8_000, pollIntervalMs * 2 ** Math.min(attempt, 5));\n attempt += 1;\n const waitMs = retryAfterMs === undefined ? jitter(backoff) : retryAfterMs;\n if (Date.now() + waitMs > deadline) return false;\n await delay(waitMs);\n return true;\n },\n };\n}\n\nfunction parseTradeExecution(value: unknown): TradeExecution | undefined {\n const record = asRecord(value);\n if (\n record === undefined ||\n typeof record['token0'] !== 'string' ||\n typeof record['token1'] !== 'string' ||\n typeof record['fee'] !== 'number'\n ) {\n return undefined;\n }\n const optionalFields = [\n 'sell0Qty',\n 'sell1Qty',\n 'buy0Qty',\n 'buy1Qty',\n 'tradingFees',\n 'protocolFees',\n 'totalFees',\n ] as const;\n for (const field of optionalFields) {\n if (field in record && typeof record[field] !== 'string') return undefined;\n }\n return {\n token0: record['token0'],\n token1: record['token1'],\n fee: record['fee'],\n ...Object.fromEntries(\n optionalFields.flatMap((field) =>\n typeof record[field] === 'string' ? [[field, record[field]]] : [],\n ),\n ),\n };\n}\n\nfunction malformedConfirmation(response: HTTPResponse, body: unknown, url: string): GSwapSDKError {\n return new GSwapSDKError(\n 'Transaction confirmation returned a malformed body',\n 'CONFIRMATION_FAILED',\n { status: response.status, body, url },\n );\n}\n\nfunction isTransient(status: number): boolean {\n return status === 500 || status === 502 || status === 503 || status === 504;\n}\n\nfunction bodyMessage(body: unknown): string {\n return (\n getStringProperty(body, 'message') ??\n getStringProperty(body, 'Message') ??\n getStringProperty(getObjectProperty(body, 'error'), 'message') ??\n getStringProperty(getObjectProperty(body, 'error'), 'Message') ??\n (typeof body === 'string' ? body : 'Transaction confirmation failed')\n );\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nfunction jitter(milliseconds: number): number {\n return Math.max(0, Math.round(milliseconds * (0.9 + Math.random() * 0.2)));\n}\n","import type { HttpRequestor, HTTPResponse } from '../types/http_requestor.js';\nimport { getObjectProperty, getStringProperty, GSwapSDKError } from './gswap_sdk_error.js';\nimport { SubmittedTransaction, type PositionConfirmationResult } from './submitted_transaction.js';\nimport {\n readBlockNumberHeader,\n readHeader,\n readResponseBody,\n readRetryAfter,\n requestWithTimeout,\n} from '../utils/transport.js';\nimport type { AppliedTrade, Position } from '../types/v2_results.js';\n\n/** Options for a chain-gateway client. */\nexport interface ChainGatewayOptions {\n dexBackendBaseUrl: string;\n httpRequestor?: HttpRequestor | undefined;\n walletAddress?: string | undefined;\n chainCallTimeoutMs?: number | undefined;\n}\n\n/** Optional attribution and operation-specific confirmation hooks for a write. */\nexport interface ChainSubmitOptions {\n walletAddress?: string | undefined;\n positionConfirmation?: ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;\n}\n\n/** Thin client for backend-routed v2 writes: synchronous liquidity writes and queued RequestTrade. */\nexport class ChainGateway {\n private readonly requestor: HttpRequestor;\n private readonly walletAddress: string | undefined;\n private readonly chainCallTimeoutMs: number;\n public readonly requestTimeoutMs: number;\n public readonly dexBackendBaseUrl: string;\n\n /** Create a chain gateway client. */\n constructor(options: ChainGatewayOptions) {\n this.dexBackendBaseUrl = trimTrailingSlash(options.dexBackendBaseUrl);\n this.requestor = options.httpRequestor ?? fetch.bind(globalThis);\n this.walletAddress = options.walletAddress;\n this.chainCallTimeoutMs = options.chainCallTimeoutMs ?? 30_000;\n this.requestTimeoutMs = this.chainCallTimeoutMs;\n }\n\n /** Submit a signed v2 DTO through the chain gateway. */\n public async submit(\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ): Promise<SubmittedTransaction<AppliedTrade>>;\n public async submit(\n method: string,\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ): Promise<SubmittedTransaction<Position | null>>;\n public async submit(\n method: string,\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ): Promise<SubmittedTransaction> {\n // The synchronous swap was removed from the contract and from this SDK. This is the only\n // place the retired name may appear in the write path; the class guard in\n // tests/foundation.test.ts pins that nothing signs or submits it.\n if (method === 'Trade') {\n throw new GSwapSDKError(\n 'The synchronous Trade method was removed; swaps are queued through RequestTrade.',\n 'METHOD_NOT_SUPPORTED',\n { method },\n );\n }\n const url = `${this.dexBackendBaseUrl}/v1/chain/asset/dex-contract/${method}`;\n const headers: Record<string, string> = { 'content-type': 'application/json' };\n const walletAddress = options?.walletAddress ?? this.walletAddress;\n if (walletAddress !== undefined) headers['X-Wallet-Address'] = walletAddress;\n let response: HTTPResponse;\n try {\n response = await requestWithTimeout(\n this.requestor,\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(signedBody),\n },\n this.chainCallTimeoutMs,\n );\n } catch (error: unknown) {\n if (error instanceof GSwapSDKError && error.code === 'REQUEST_TIMEOUT') {\n throw new GSwapSDKError(\n 'The submission outcome is unknown because the gateway request timed out. Confirm before retrying.',\n 'SUBMISSION_OUTCOME_UNKNOWN',\n { uniqueKey: getStringProperty(signedBody, 'uniqueKey') ?? '', cause: error },\n );\n }\n throw error;\n }\n const body = await readResponseBody(response);\n\n if (!response.ok) {\n throw gatewayError(response, body, url);\n }\n\n const envelope = asRecord(body);\n const data = asRecord(envelope?.['data'] ?? envelope?.['Data']);\n if (data === undefined) {\n throw invalidGatewayResponse(response, body, url, 'Expected a data object.');\n }\n\n const transactionId = getStringProperty(data, 'transactionId');\n const mode = getStringProperty(data, 'mode');\n const rawTransactionId = data['transactionId'];\n const bodyBlockNumber = data['blockNumber'];\n const invalidModeMessage =\n 'Gateway response must contain data.mode=\"sync\" with data.result, or data.mode=\"queued\".';\n if (mode !== 'sync' && mode !== 'queued') {\n throw invalidGatewayResponse(response, body, url, invalidModeMessage);\n }\n if (\n ('transactionId' in data && typeof rawTransactionId !== 'string') ||\n (bodyBlockNumber !== undefined && bodyBlockNumber !== null && !isBlockNumber(bodyBlockNumber))\n ) {\n throw invalidGatewayResponse(response, body, url, invalidModeMessage);\n }\n if (method === 'RequestTrade' && mode === 'sync') {\n throw invalidGatewayResponse(\n response,\n body,\n url,\n 'The gateway executed RequestTrade synchronously, which this SDK refuses; RequestTrade must be queued.',\n );\n }\n if (method === 'RequestTrade' && mode === 'queued') {\n const signedUniqueKey = getStringProperty(signedBody, 'uniqueKey');\n if (\n 'uniqueKey' in data &&\n (typeof data['uniqueKey'] !== 'string' || data['uniqueKey'] !== signedUniqueKey)\n ) {\n throw invalidGatewayResponse(\n response,\n body,\n url,\n 'Gateway response data.uniqueKey must match the signed RequestTrade uniqueKey.',\n );\n }\n } else if (mode === 'queued' || !('result' in data)) {\n throw invalidGatewayResponse(response, body, url, invalidModeMessage);\n }\n\n // Only synchronous writes carry an executed chain result in the gateway response.\n if (mode === 'sync') {\n const embeddedResult = asRecord(data['result']);\n if (embeddedResult !== undefined) {\n const resultStatus = embeddedResult['Status'];\n if (resultStatus !== undefined && resultStatus !== 1) {\n throw GSwapSDKError.fromChainError(\n getStringProperty(embeddedResult, 'ErrorKey') ?? 'CHAIN_ERROR',\n getStringProperty(embeddedResult, 'Message') ?? 'The chain rejected this write.',\n { status: response.status, body, url },\n );\n }\n }\n }\n\n const uniqueKey = getStringProperty(signedBody, 'uniqueKey') ?? '';\n const headerTransactionId = readHeader(response, 'x-transaction-id');\n const resolvedTransactionId =\n transactionId === undefined || transactionId === '' ? headerTransactionId : transactionId;\n const blockNumber: number | undefined =\n bodyBlockNumber === null || bodyBlockNumber === undefined\n ? readBlockNumberHeader(response)\n : isBlockNumber(bodyBlockNumber)\n ? bodyBlockNumber\n : undefined;\n return new SubmittedTransaction({\n method,\n uniqueKey,\n transactionId:\n resolvedTransactionId === undefined || resolvedTransactionId === ''\n ? null\n : resolvedTransactionId,\n blockNumber: blockNumber ?? null,\n mode,\n result: mode === 'queued' ? undefined : data['result'],\n dexBackendBaseUrl: this.dexBackendBaseUrl,\n httpRequestor: this.requestor,\n requestTimeoutMs: this.chainCallTimeoutMs,\n ...(options?.positionConfirmation === undefined\n ? {}\n : { positionConfirmation: options.positionConfirmation }),\n });\n }\n\n /** Expose the requestor for sibling read services that share this gateway transport. */\n public get httpRequestor(): HttpRequestor {\n return this.requestor;\n }\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/u, '');\n}\n\nfunction invalidGatewayResponse(\n response: HTTPResponse,\n body: unknown,\n url: string,\n message: string,\n): GSwapSDKError {\n return new GSwapSDKError(message, 'INVALID_GATEWAY_RESPONSE', {\n status: response.status,\n body,\n url,\n });\n}\n\nfunction gatewayError(response: HTTPResponse, body: unknown, url: string): GSwapSDKError {\n const object = asRecord(body);\n const nested = getObjectProperty(body, 'error');\n const code =\n getStringProperty(object, 'code') ??\n getStringProperty(nested, 'code') ??\n getStringProperty(nested, 'ErrorKey') ??\n 'HTTP_ERROR';\n const message =\n getStringProperty(object, 'message') ??\n getStringProperty(nested, 'message') ??\n getStringProperty(nested, 'Message') ??\n (typeof body === 'string' ? body : `Gateway request failed with HTTP ${response.status}`);\n const retryAfterMs = response.status === 429 ? readRetryAfter(response) : undefined;\n if (code === 'HTTP_ERROR') {\n return new GSwapSDKError(message, code, { status: response.status, body, url });\n }\n return GSwapSDKError.fromGatewayBounce(code, message, response.status, retryAfterMs);\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction isBlockNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0;\n}\n","import debug from 'debug';\n\nexport const debugLog = debug('GSWAP_SDK');\n","declare const __GSWAP_SDK_VERSION__: string | undefined;\n\n/** Package version embedded by the bundler, with a source-test fallback. */\nexport const SDK_VERSION =\n typeof __GSWAP_SDK_VERSION__ === 'string' ? __GSWAP_SDK_VERSION__ : '1.0.0';\n","import type { HttpRequestor } from '../types/http_requestor.js';\nimport { debugLog } from '../utils/debug.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport { readResponseBody, requestWithTimeout } from '../utils/transport.js';\nimport { SDK_VERSION } from '../version.js';\n\nexport class HttpClient {\n /** Create an HTTP client around fetch or an injected requestor. */\n constructor(\n private readonly httpRequestor: HttpRequestor = fetch,\n private readonly timeoutMs = 30_000,\n ) {}\n\n private async sendRequest<TReturnType>(\n method: 'POST' | 'GET',\n baseUrl: string,\n basePath: string,\n endpoint: string,\n body?: unknown,\n options?: Pick<RequestInit, 'signal'>,\n ): Promise<TReturnType> {\n const url = `${baseUrl}${basePath}${endpoint}`;\n debugLog(`Sending request to ${url} with body:`, body);\n\n const response = await requestWithTimeout(\n this.httpRequestor,\n url,\n {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `GalaChain-SDK/${SDK_VERSION}`,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n ...(options?.signal === undefined ? {} : { signal: options.signal }),\n },\n this.timeoutMs,\n );\n\n if (!response.ok) {\n throw await GSwapSDKError.fromErrorResponse(url, response);\n }\n\n const json = await readResponseBody(response);\n debugLog(`Response from ${baseUrl}${basePath}${endpoint}:`, json);\n\n return json as TReturnType;\n }\n\n /** Send a JSON POST request and decode its response. */\n async sendPostRequest<TReturnType>(\n baseUrl: string,\n basePath: string,\n endpoint: string,\n body: unknown,\n ): Promise<TReturnType> {\n return this.sendRequest('POST', baseUrl, basePath, endpoint, body);\n }\n\n /** Send a GET request with URL-encoded query parameters and decode its response. */\n async sendGetRequest<TReturnType>(\n baseUrl: string,\n basePath: string,\n endpoint: string,\n params?: Record<string, string>,\n options?: Pick<RequestInit, 'signal'>,\n ): Promise<TReturnType> {\n const searchParams = params ? new URLSearchParams(params) : undefined;\n const endpointWithParams = searchParams ? `${endpoint}?${searchParams.toString()}` : endpoint;\n\n return this.sendRequest('GET', baseUrl, basePath, endpointWithParams, undefined, options);\n }\n}\n","import { GSwapSDKError } from '../classes/gswap_sdk_error.js';\nimport type { GalaChainTokenClassKey } from '../types/token.js';\n\n/** A symbol or a GalaChain token class key accepted by v2 operations. */\nexport type TokenRef = string | GalaChainTokenClassKey;\n\n/** Return two trading symbols in the contract's plain-string order. */\nexport function orderSymbols(a: string, b: string): [string, string] {\n return a < b ? [a, b] : [b, a];\n}\n\n/** Read an ordered symbol pair from a tuple or object returned by a boundary helper.\n *\n * @example\n * ```ts\n * const pair = readOrderedSymbols(['GALA', 'GUSDC']);\n * console.log(pair.token0);\n * ```\n */\nexport function readOrderedSymbols(value: unknown): { token0: string; token1: string } {\n if (Array.isArray(value) && value.length >= 2) {\n const token0 = (value as unknown[])[0];\n const token1 = (value as unknown[])[1];\n if (typeof token0 === 'string' && typeof token1 === 'string') return { token0, token1 };\n }\n if (typeof value === 'object' && value !== null) {\n const record = value as Record<string, unknown>;\n const token0 = record['token0'];\n const token1 = record['token1'];\n if (typeof token0 === 'string' && typeof token1 === 'string') return { token0, token1 };\n }\n throw new GSwapSDKError('Unable to order trading symbols.', 'VALIDATION_ERROR', { value });\n}\n\n/** Return the `$`-joined composite key used by GalaChain object identities. */\nexport function compositeKeyOf(token: GalaChainTokenClassKey): string {\n return [token.collection, token.category, token.type, token.additionalKey].join('$');\n}\n\n/**\n * Parse a pipe- or dollar-separated token class key.\n *\n * The LAST three segments are always `category`, `type` and `additionalKey`; everything before\n * them is the `collection`. Parsing from the right is required because real collections contain\n * the `$` delimiter themselves (for example `$GMUSIC`), so a plain left-to-right `split('$')`\n * shifts every field. Nothing here says anything about the token's symbol: a class key carries\n * no symbol, which must come from the token class or trading-symbol registry.\n *\n * @example\n * ```ts\n * parseTokenClassKey('$GMUSIC$Unit$none$none').collection; // '$GMUSIC'\n * ```\n */\nexport function parseTokenClassKey(tokenClassKey: TokenRef): GalaChainTokenClassKey {\n if (typeof tokenClassKey === 'object') {\n return {\n collection: tokenClassKey.collection,\n category: tokenClassKey.category,\n type: tokenClassKey.type,\n additionalKey: tokenClassKey.additionalKey,\n };\n }\n\n const delimiter = tokenClassKey.includes('|') ? '|' : '$';\n const segments = tokenClassKey.split(delimiter);\n const tail = segments.slice(-3);\n const collection = segments.slice(0, -3).join(delimiter);\n if (segments.length < 4 || collection.length === 0 || tail.some((part) => part.length === 0)) {\n throw new GSwapSDKError(\n 'Invalid token class key: expected a collection followed by category, type and additionalKey',\n 'VALIDATION_ERROR',\n {\n tokenClassKey,\n },\n );\n }\n\n const [category, type, additionalKey] = tail;\n return {\n collection,\n category: category as string,\n type: type as string,\n additionalKey: additionalKey as string,\n };\n}\n","import type { FEE_TIER } from '../types/fees.js';\nimport type { CompositePool, PoolInfo, PoolListInfo, Slot0 } from '../types/v2_results.js';\nimport { orderSymbols, readOrderedSymbols, type TokenRef } from '../utils/ordering.js';\nimport type { ChainGateway } from './gateway.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport { HttpClient } from './http_client.js';\nimport type { Symbols } from './symbols.js';\nimport { validateFee } from '../utils/validation.js';\n\ninterface BackendEnvelope<T> {\n data: T;\n}\n\ntype PoolGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {\n requestTimeoutMs?: number | undefined;\n};\ntype PoolSymbols = Pick<Symbols, 'resolve'>;\n\n/** Read-only pool and current-price access for the current GalaChainDex contract. */\nexport class Pools {\n /**\n * Creates a pool service.\n *\n * @example\n * ```ts\n * const pools = new Pools(gateway, symbols);\n * ```\n */\n constructor(\n private readonly gateway: PoolGateway,\n private readonly symbols: PoolSymbols,\n ) {\n this.http = new HttpClient(gateway.httpRequestor, gateway.requestTimeoutMs ?? 30_000);\n }\n\n private readonly http: HttpClient;\n\n /**\n * Fetches every current-contract pool from the swap backend.\n *\n * @example\n * ```ts\n * const pools = await service.getPools();\n * console.log(pools.length);\n * ```\n */\n public async getPools(options?: { signal?: AbortSignal | undefined }): Promise<PoolListInfo[]> {\n const response = await this.http.sendGetRequest<BackendEnvelope<unknown>>(\n this.gateway.dexBackendBaseUrl,\n '/v2/trade',\n '/pools',\n undefined,\n options?.signal === undefined ? undefined : { signal: options.signal },\n );\n if (!Array.isArray(response.data) || !response.data.every(isPoolListInfo)) {\n throw new GSwapSDKError('Backend returned an invalid pool list.', 'INVALID_CHAIN_RESPONSE', {\n data: response.data,\n });\n }\n return response.data;\n }\n\n /**\n * Fetches one pool from the backend, preserving whether the request order was flipped.\n *\n * @example\n * ```ts\n * const pool = await service.getPool('GUSDC', 'GALA', 3000);\n * console.log(pool.flippedFromRequest);\n * ```\n */\n public async getPool(token0: TokenRef, token1: TokenRef, fee: FEE_TIER): Promise<PoolInfo> {\n validateFee(fee);\n return this.getBackend<PoolInfo>('/pool', await this.backendParams(token0, token1, fee));\n }\n\n /**\n * Fetches the current sqrt price, price, and tick for one pool.\n *\n * @example\n * ```ts\n * const slot0 = await service.getSlot0('GALA', 'GUSDC', 3000);\n * console.log(slot0.tick);\n * ```\n */\n public async getSlot0(token0: TokenRef, token1: TokenRef, fee: FEE_TIER): Promise<Slot0> {\n validateFee(fee);\n return this.getBackend<Slot0>('/slot0', await this.backendParams(token0, token1, fee));\n }\n\n /**\n * Fetches the complete chain composite pool snapshot, in canonical symbol order.\n *\n * @example\n * ```ts\n * const composite = await service.getCompositePool('GALA', 'GUSDC', 3000);\n * console.log(composite.positions?.length ?? 0);\n * ```\n */\n public async getCompositePool(\n token0: TokenRef,\n token1: TokenRef,\n fee: FEE_TIER,\n ): Promise<CompositePool> {\n validateFee(fee);\n const first = await resolveSymbol(this.symbols, token0);\n const second = await resolveSymbol(this.symbols, token1);\n const ordered = readOrderedSymbols(orderSymbols(first, second));\n return this.getBackend<CompositePool>('/composite-pool', {\n token0: ordered.token0,\n token1: ordered.token1,\n fee: String(fee),\n });\n }\n\n private async backendParams(\n token0: TokenRef,\n token1: TokenRef,\n fee: FEE_TIER,\n ): Promise<Record<string, string>> {\n return {\n token0: await resolveSymbol(this.symbols, token0),\n token1: await resolveSymbol(this.symbols, token1),\n fee: String(fee),\n };\n }\n\n private async getBackend<T>(endpoint: string, params: Record<string, string>): Promise<T> {\n try {\n const response = await this.http.sendGetRequest<BackendEnvelope<T>>(\n this.gateway.dexBackendBaseUrl,\n '/v2/trade',\n endpoint,\n params,\n );\n return response.data;\n } catch (error: unknown) {\n if (error instanceof GSwapSDKError) throw error;\n throw new GSwapSDKError('Pool request failed.', 'HTTP_ERROR', { cause: error });\n }\n }\n}\n\nasync function resolveSymbol(symbols: PoolSymbols, token: TokenRef): Promise<string> {\n const resolved = await symbols.resolve(token);\n if (resolved.symbol.length > 0) return resolved.symbol;\n throw new GSwapSDKError('Token could not be resolved to a trading symbol.', 'SYMBOL_NOT_FOUND', {\n token,\n });\n}\n\nfunction isPoolListInfo(value: unknown): value is PoolListInfo {\n if (typeof value !== 'object' || value === null) return false;\n const row = value as Record<string, unknown>;\n const requiredNumbers = ['fee', 'tickSpacing', 'protocolFees', 'tradingFees'];\n const optionalStrings = [\n 'token0CompositeKey',\n 'token1CompositeKey',\n 'creator',\n 'price',\n 'sqrtPrice',\n 'token0Tvl',\n 'token1Tvl',\n ];\n const optionalNumbers = [\n 'tick',\n 'tvlUsd',\n 'volume1d',\n 'volume7d',\n 'volume30d',\n 'trades1d',\n 'fee24h',\n 'apr1d',\n 'token0Price',\n 'token1Price',\n ];\n return (\n row['contractVersion'] === 'v2' &&\n typeof row['token0'] === 'string' &&\n typeof row['token1'] === 'string' &&\n typeof row['poolName'] === 'string' &&\n typeof row['poolRef'] === 'string' &&\n requiredNumbers.every((key) => isFiniteNumber(row[key])) &&\n optionalStrings.every((key) => isOptionalString(row[key])) &&\n optionalNumbers.every((key) => isOptionalNumber(row[key]))\n );\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nfunction isOptionalString(value: unknown): value is string | undefined {\n return value === undefined || typeof value === 'string';\n}\n\nfunction isOptionalNumber(value: unknown): value is number | undefined {\n return value === undefined || isFiniteNumber(value);\n}\n","import BigNumber from 'bignumber.js';\nimport { GSwapSDKError } 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 type { GalaChainSigner } from './signers.js';\nimport type { Symbols } 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 { type TokenRef, compositeKeyOf, parseTokenClassKey } from '../utils/ordering.js';\nimport { validateFee, validateNumericAmount } from '../utils/validation.js';\nimport { alignTickDown, alignTickUp, assertTickRange, tickFromPrice } from '../utils/ticks.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};\ntype PositionSymbols = Pick<Symbols, 'resolve' | 'orderPair'> & { invalidate?: () => void };\n\ninterface BackendEnvelope<TData> {\n data: TData;\n}\n\ninterface PositionWire {\n token0CompositeKey?: string;\n token1CompositeKey?: string;\n token0Symbol: string;\n token1Symbol: string;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n liquidity: string;\n amount0: string;\n amount1: string;\n inRange: boolean;\n owner: string;\n currentTick?: number;\n sqrtPrice?: string;\n pool?: string;\n poolRef?: string;\n fees0?: string;\n fees1?: string;\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 ) {\n this.http = new HttpClient(gateway.httpRequestor, gateway.requestTimeoutMs ?? 30_000);\n }\n\n private readonly http: HttpClient;\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.\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<PositionWire[]>('/positions', { user: owner });\n return response.data.map((position) => this.mapPosition(position));\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 pair = await this.symbols.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n const response = await this.getNullable<PositionWire>(\n '/position',\n {\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 signal,\n );\n return response === null ? null : this.mapPosition(response.data);\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: this.requestToken(args.token0),\n token1: this.requestToken(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: this.requestToken(args.token0),\n token1: this.requestToken(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: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount: NumericAmount;\n amountIsToken0: boolean;\n }) {\n validateFee(args.fee);\n const pair = await this.symbols.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 validateNumericAmount(args.amount, 'amount');\n const amount = new BigNumber(args.amount).toFixed();\n const dto: AddLiquidityDTO = {\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.uniqueKey(),\n ...(pair.flipped !== args.amountIsToken0\n ? { depositQuantityToken0: amount }\n : { depositQuantityToken1: amount }),\n };\n return this.submit('AddLiquidity', dto as unknown as Record<string, unknown>, {\n kind: 'add',\n identity: {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n },\n });\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 }) {\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('Price bounds must be finite and positive.', 'VALIDATION_ERROR');\n }\n if (minPrice.isGreaterThan(maxPrice)) {\n throw new GSwapSDKError(\n 'minPrice must be less than or equal to maxPrice.',\n 'VALIDATION_ERROR',\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 });\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: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount0?: NumericAmount | undefined;\n amount1?: NumericAmount | undefined;\n }) {\n validateFee(args.fee);\n const pair = await this.symbols.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('Provide at most one of amount0 or amount1.', 'VALIDATION_ERROR');\n }\n if (args.amount0 !== undefined) validateNumericAmount(args.amount0, 'amount0');\n if (args.amount1 !== undefined) validateNumericAmount(args.amount1, 'amount1');\n const withdrawal =\n args.amount0 !== undefined\n ? pair.flipped\n ? { withdrawalQuantityToken1: new BigNumber(args.amount0).toFixed() }\n : { withdrawalQuantityToken0: new BigNumber(args.amount0).toFixed() }\n : args.amount1 !== undefined\n ? pair.flipped\n ? { withdrawalQuantityToken0: new BigNumber(args.amount1).toFixed() }\n : { withdrawalQuantityToken1: new BigNumber(args.amount1).toFixed() }\n : {};\n const dto: RemoveLiquidityDTO = {\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.uniqueKey(),\n ...withdrawal,\n };\n const isFullClose = args.amount0 === undefined && args.amount1 === undefined;\n return this.submit('RemoveLiquidity', dto as unknown as Record<string, unknown>, {\n kind: isFullClose ? 'removeFull' : 'removePartial',\n identity: {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n },\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: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n }) {\n validateFee(args.fee);\n const pair = await this.symbols.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 const dto: CollectPositionFeesDTO = {\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.uniqueKey(),\n };\n return this.submit('CollectPositionFees', dto as unknown as Record<string, unknown>, {\n kind: 'collect',\n identity: {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n },\n });\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 * VALIDATION_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: {\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 isPrivate?: boolean | undefined;\n privateAccess?: string[] | undefined;\n }) {\n const hasPrice = args.startingPrice !== undefined;\n const hasSqrtPrice = args.startingSqrtPrice !== undefined;\n if (hasPrice === hasSqrtPrice) {\n throw new GSwapSDKError(\n 'Provide exactly one of startingPrice or startingSqrtPrice.',\n 'VALIDATION_ERROR',\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('Starting price must be finite and positive.', 'VALIDATION_ERROR');\n }\n const canonicalPrice = flipped ? new BigNumber(1).dividedBy(sourcePrice) : sourcePrice;\n const dto: CreatePoolDTO = {\n token0Key: token0.classKey,\n token1Key: token1.classKey,\n token0Symbol: token0.symbol,\n token1Symbol: token1.symbol,\n fee: args.fee,\n uniqueKey: this.uniqueKey(),\n ...(hasPrice\n ? { startingPrice: canonicalPrice.toFixed() }\n : { startingSqrtPrice: canonicalPrice.toFixed() }),\n ...(args.isPrivate === undefined ? {} : { isPrivate: args.isPrivate }),\n ...(args.privateAccess === undefined ? {} : { privateAccess: args.privateAccess }),\n };\n const transaction = await this.submit('CreatePool', dto, {\n kind: 'createPool',\n token0: token0.symbol,\n token1: token1.symbol,\n fee: args.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 this.signer.signObject(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 if (!(error instanceof GSwapSDKError) || error.details === undefined) return false;\n return error.details['status'] === 404;\n }\n\n private mapPosition(position: PositionWire): Position {\n return {\n token0Symbol: position.token0Symbol,\n token1Symbol: position.token1Symbol,\n ...(position.token0CompositeKey === undefined\n ? {}\n : { token0CompositeKey: position.token0CompositeKey }),\n ...(position.token1CompositeKey === undefined\n ? {}\n : { token1CompositeKey: position.token1CompositeKey }),\n fee: position.fee,\n tickLower: position.tickLower,\n tickUpper: position.tickUpper,\n liquidity: position.liquidity,\n amount0: position.amount0,\n amount1: position.amount1,\n inRange: position.inRange,\n ...(position.currentTick === undefined ? {} : { currentTick: position.currentTick }),\n ...(position.sqrtPrice === undefined ? {} : { sqrtPrice: position.sqrtPrice }),\n pool: position.poolRef ?? position.pool ?? '',\n owner: position.owner,\n ...(position.fees0 === undefined ? {} : { fees0: position.fees0 }),\n ...(position.fees1 === undefined ? {} : { fees1: position.fees1 }),\n };\n }\n\n private requestToken(ref: TokenRef): string {\n return typeof ref === 'string' ? ref : compositeKeyOf(ref);\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(`Unsupported fee tier: ${fee}.`, 'VALIDATION_ERROR');\n }\n return spacing;\n }\n\n private rejectNumber(value: unknown, parameterName: string): void {\n if (typeof value === 'number') {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: use a decimal string or BigNumber, not a JavaScript number`,\n 'VALIDATION_ERROR',\n );\n }\n }\n\n private uniqueKey(): string {\n return `gswap-sdk-${globalThis.crypto.randomUUID()}`;\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 this.symbols.resolve(lookupRef);\n if (\n symbolOverride !== undefined &&\n symbolOverride !== '' &&\n symbolOverride !== resolved.symbol\n ) {\n throw new GSwapSDKError(\n `Supplied symbol ${symbolOverride} disagrees with the registered trading symbol ${resolved.symbol}.`,\n 'VALIDATION_ERROR',\n { token: ref, suppliedSymbol: symbolOverride, registeredSymbol: resolved.symbol },\n );\n }\n const suppliedClassKey = this.tryParseClassKey(ref);\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 (!(error instanceof GSwapSDKError) || error.code !== '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(\n 'Token is not registered in the trading-symbol registry yet; pass token0Symbol/token1Symbol (the token class symbol) to propose one. A symbol cannot be derived from a class key.',\n 'VALIDATION_ERROR',\n { token: ref },\n );\n }\n if (!/^[A-Za-z0-9]+$/u.test(symbolOverride)) {\n throw new GSwapSDKError(\n 'Invalid trading symbol: must be ASCII letters and digits only.',\n 'VALIDATION_ERROR',\n { symbol: symbolOverride },\n );\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","import BigNumber from 'bignumber.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 type { QuoteResult } from '../types/v2_results.js';\nimport type { TokenRef } from '../utils/ordering.js';\nimport { validateNumericAmount } from '../utils/validation.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport type { HttpClient } from './http_client.js';\nimport type { Symbols } from './symbols.js';\n\ninterface QuoteWire {\n contractVersion: 'v2';\n fee: number;\n amountIn: string;\n amountOut: string;\n currentSqrtPrice?: string;\n newSqrtPrice?: string;\n currentPrice?: string;\n newPrice?: string;\n newTick: number;\n tradingFees: string;\n protocolFees: string;\n totalFees: string;\n feeTokenSymbol: string;\n token0Symbol: string;\n token1Symbol: string;\n tokenInIsToken0: boolean;\n}\n\ninterface BackendEnvelope<T> {\n data: T;\n}\n\ntype QuoteSymbols = Pick<Symbols, 'resolve'>;\n\n/** Read-only quote service backed by the v2 offline quote engine. */\nexport class Quoting {\n /**\n * Creates a quote service.\n *\n * @example\n * ```ts\n * const quoting = new Quoting('https://swap-backend.stage.defi.ovh.gala.com', http, symbols);\n * ```\n */\n constructor(\n private readonly dexBackendBaseUrl: string,\n private readonly http: HttpClient,\n private readonly symbols: QuoteSymbols,\n ) {}\n\n /**\n * Quotes the output for a positive exact-input amount.\n *\n * @example\n * ```ts\n * const quote = await quoting.quoteExactInput('GALA', 'GUSDC', '100');\n * console.log(quote.amountOut);\n * ```\n */\n public async quoteExactInput(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n amountIn: NumericAmount,\n fee?: FEE_TIER,\n ): Promise<QuoteResult> {\n validateNumericAmount(amountIn, 'amountIn');\n return this.quote(tokenIn, tokenOut, { amountIn: toDecimalString(amountIn) }, fee);\n }\n\n /**\n * Quotes the input for a positive exact-output amount.\n *\n * @example\n * ```ts\n * const quote = await quoting.quoteExactOutput('GALA', 'GUSDC', '10', 3000);\n * console.log(quote.amountIn);\n * ```\n */\n public async quoteExactOutput(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n amountOut: NumericAmount,\n fee?: FEE_TIER,\n ): Promise<QuoteResult> {\n validateNumericAmount(amountOut, 'amountOut');\n return this.quote(tokenIn, tokenOut, { amountOut: toDecimalString(amountOut) }, fee);\n }\n\n private async quote(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n amount: { amountIn: string } | { amountOut: string },\n fee?: FEE_TIER,\n ): Promise<QuoteResult> {\n validateOptionalFee(fee);\n\n const tokenInSymbol = await resolveSymbol(this.symbols, tokenIn);\n const tokenOutSymbol = await resolveSymbol(this.symbols, tokenOut);\n const params: Record<string, string> = {\n tokenIn: tokenInSymbol,\n tokenOut: tokenOutSymbol,\n ...amount,\n };\n if (fee !== undefined) params['fee'] = String(fee);\n\n try {\n const response = await this.http.sendGetRequest<BackendEnvelope<QuoteWire>>(\n this.dexBackendBaseUrl,\n '/v2/trade',\n '/quote',\n params,\n );\n return mapQuote(response.data);\n } catch (error: unknown) {\n throw mapQuoteError(error, tokenIn, tokenOut, fee);\n }\n }\n}\n\nfunction mapQuote(value: unknown): QuoteResult {\n if (!isQuoteWire(value)) {\n throw new GSwapSDKError('Backend returned an invalid quote.', 'INVALID_CHAIN_RESPONSE', {\n data: value,\n });\n }\n const wire = value;\n const currentPrice =\n wire.currentPrice !== undefined\n ? new BigNumber(wire.currentPrice)\n : orientPrice(wire.currentSqrtPrice!, wire.tokenInIsToken0);\n const newPrice =\n wire.newPrice !== undefined\n ? new BigNumber(wire.newPrice)\n : orientPrice(wire.newSqrtPrice!, wire.tokenInIsToken0);\n const priceImpact = newPrice.minus(currentPrice).dividedBy(currentPrice);\n\n return {\n contractVersion: wire.contractVersion,\n fee: wire.fee,\n amountIn: wire.amountIn,\n amountOut: wire.amountOut,\n ...(wire.currentSqrtPrice === undefined ? {} : { currentSqrtPrice: wire.currentSqrtPrice }),\n ...(wire.newSqrtPrice === undefined ? {} : { newSqrtPrice: wire.newSqrtPrice }),\n feeTier: wire.fee,\n newTick: wire.newTick,\n tradingFees: wire.tradingFees,\n protocolFees: wire.protocolFees,\n totalFees: wire.totalFees,\n feeTokenSymbol: wire.feeTokenSymbol,\n token0Symbol: wire.token0Symbol,\n token1Symbol: wire.token1Symbol,\n tokenInIsToken0: wire.tokenInIsToken0,\n currentPrice,\n newPrice,\n priceImpact,\n };\n}\n\n// The default BigNumber.DECIMAL_PLACES (20) underflows 1/poolPrice to exactly 0 for a\n// pool price above ~1e20 (a real, in-range price for a low-unit-value token quoted\n// against a high-value one) — 60dp matches the precision ticks.ts's DexMath already\n// uses for this same class of division.\nconst HighPrecision = BigNumber.clone({ DECIMAL_PLACES: 60 });\n\nfunction orientPrice(sqrtPrice: string, tokenInIsToken0: boolean): BigNumber {\n const poolPrice = new HighPrecision(sqrtPrice).pow(2);\n return tokenInIsToken0 ? poolPrice : new HighPrecision(1).dividedBy(poolPrice);\n}\n\nfunction isQuoteWire(value: unknown): value is QuoteWire {\n if (typeof value !== 'object' || value === null) return false;\n const wire = value as Record<string, unknown>;\n const requiredStrings = [\n 'amountIn',\n 'amountOut',\n 'tradingFees',\n 'protocolFees',\n 'totalFees',\n 'feeTokenSymbol',\n 'token0Symbol',\n 'token1Symbol',\n ];\n return (\n wire['contractVersion'] === 'v2' &&\n typeof wire['fee'] === 'number' &&\n Number.isFinite(wire['fee']) &&\n requiredStrings.every((key) => typeof wire[key] === 'string') &&\n typeof wire['newTick'] === 'number' &&\n Number.isInteger(wire['newTick']) &&\n typeof wire['tokenInIsToken0'] === 'boolean' &&\n optionalPositiveDecimal(wire['currentSqrtPrice']) &&\n optionalPositiveDecimal(wire['newSqrtPrice']) &&\n optionalPositiveDecimal(wire['currentPrice']) &&\n optionalPositiveDecimal(wire['newPrice']) &&\n (wire['currentSqrtPrice'] !== undefined || wire['currentPrice'] !== undefined) &&\n (wire['newSqrtPrice'] !== undefined || wire['newPrice'] !== undefined)\n );\n}\n\nfunction optionalPositiveDecimal(value: unknown): boolean {\n if (value === undefined) return true;\n if (typeof value !== 'string') return false;\n try {\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — this validates an untrusted backend field, so an unparseable value\n // must fail validation cleanly (INVALID_CHAIN_RESPONSE), not throw raw.\n const decimal = new BigNumber(value);\n return decimal.isFinite() && decimal.isGreaterThan(0);\n } catch {\n return false;\n }\n}\n\nfunction mapQuoteError(\n error: unknown,\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER | undefined,\n): GSwapSDKError {\n if (error instanceof GSwapSDKError) {\n const status = readStatus(error.details);\n const message = readMessage(error.details) ?? error.message;\n if (status === 404 || /no pool|no pools|pool does not exist/iu.test(message)) {\n return GSwapSDKError.noPoolAvailableError(tokenIn, tokenOut, fee);\n }\n if (status === 400 && /insufficient liquidity/iu.test(message)) {\n return GSwapSDKError.insufficientLiquidityError(tokenIn, tokenOut, fee);\n }\n return error;\n }\n return new GSwapSDKError('Quote request failed.', 'HTTP_ERROR', {\n cause: error,\n tokenIn,\n tokenOut,\n fee,\n });\n}\n\nfunction readStatus(details: Record<string, unknown> | undefined): number | undefined {\n const status = details?.['status'];\n return typeof status === 'number' ? status : undefined;\n}\n\nfunction readMessage(details: Record<string, unknown> | undefined): string | undefined {\n const direct = details?.['message'];\n if (typeof direct === 'string') return direct;\n const body = details?.['body'];\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return undefined;\n const message = (body as Record<string, unknown>)['message'];\n return typeof message === 'string' ? message : undefined;\n}\n\nfunction validateOptionalFee(fee: FEE_TIER | undefined): void {\n if (fee !== undefined && !ALL_FEE_TIERS.some((tier) => Number(tier) === Number(fee))) {\n throw new GSwapSDKError(`Invalid fee tier: ${fee}`, 'VALIDATION_ERROR', { fee });\n }\n}\n\nfunction toDecimalString(amount: NumericAmount): string {\n return new BigNumber(amount).toFixed();\n}\n\nasync function resolveSymbol(symbols: QuoteSymbols, token: TokenRef): Promise<string> {\n const resolved = await symbols.resolve(token);\n if (resolved.symbol.length > 0) return resolved.symbol;\n throw new GSwapSDKError('Token could not be resolved to a trading symbol.', 'SYMBOL_NOT_FOUND', {\n token,\n });\n}\n","import type { GalaChainTokenClassKey } from '../types/token.js';\nimport type { TradingSymbol } from '../types/v2_results.js';\nimport type { TokenRef } from '../utils/ordering.js';\nimport { compositeKeyOf, orderSymbols, parseTokenClassKey } from '../utils/ordering.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport type { ChainGateway } from './gateway.js';\nimport { HttpClient } from './http_client.js';\n\nconst SYMBOL_CACHE_TTL_MS = 60_000;\n\n/** Symbol registry client for the current GalaChainDex contract. */\nexport class Symbols {\n private cachedSymbols: TradingSymbol[] | undefined;\n private cachedAt = 0;\n private refreshInFlight: Promise<TradingSymbol[]> | undefined;\n\n private readonly http: HttpClient;\n\n /** Create a symbol service backed by the swap backend. */\n constructor(\n private readonly gateway: Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {\n requestTimeoutMs?: number | undefined;\n },\n ) {\n this.http = new HttpClient(gateway.httpRequestor, gateway.requestTimeoutMs);\n }\n\n /** List all registered GalaChainDex trading symbols, cached for 60 seconds. */\n public async list(): Promise<TradingSymbol[]> {\n if (this.cachedSymbols !== undefined && Date.now() - this.cachedAt < SYMBOL_CACHE_TTL_MS) {\n return this.cachedSymbols;\n }\n if (this.refreshInFlight !== undefined) return this.refreshInFlight;\n this.refreshInFlight = this.http\n .sendGetRequest<{ data: unknown }>(this.gateway.dexBackendBaseUrl, '/v2/trade', '/symbols')\n .then((response) => parseSymbols(response.data))\n .then((symbols) => {\n this.cachedSymbols = symbols;\n this.cachedAt = Date.now();\n return symbols;\n })\n .finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n\n /** Invalidate the cached symbol registry after a write changes registration state.\n *\n * @example\n * ```ts\n * gSwap.symbols.invalidate();\n * ```\n */\n public invalidate(): void {\n this.cachedSymbols = undefined;\n this.cachedAt = 0;\n }\n\n /** Force one registry refresh, bypassing the cache.\n *\n * @example\n * ```ts\n * const symbols = await gSwap.symbols.refresh();\n * ```\n */\n public async refresh(): Promise<TradingSymbol[]> {\n this.invalidate();\n // list() would otherwise return an ALREADY in-flight refresh that started before this\n // call (built from pre-invalidation state) — bypassing it too is what makes this\n // actually force a fresh fetch, not just satisfy the cache-freshness check.\n this.refreshInFlight = undefined;\n return this.list();\n }\n\n /** Resolve a symbol or token class key to its registered symbol metadata. */\n public async resolve(ref: TokenRef): Promise<TradingSymbol> {\n let symbols = await this.list();\n const composite =\n typeof ref === 'string'\n ? isCompositeKey(ref)\n ? compositeKeyOf(parseTokenClassKey(ref))\n : undefined\n : compositeKeyOf(ref);\n const resolved = symbols.find(\n (entry) =>\n entry.symbol === ref || (composite !== undefined && compositeKeyOf(entry) === composite),\n );\n if (resolved === undefined) {\n symbols = await this.refresh();\n const refreshed = symbols.find(\n (entry) =>\n entry.symbol === ref || (composite !== undefined && compositeKeyOf(entry) === composite),\n );\n if (refreshed === undefined) throw GSwapSDKError.unknownTokenError(ref);\n return refreshed;\n }\n return resolved;\n }\n\n /** Resolve and put two token references in canonical trading-symbol order. */\n public async orderPair(\n a: TokenRef,\n b: TokenRef,\n ): Promise<{\n token0: TradingSymbol;\n token1: TradingSymbol;\n flipped: boolean;\n }> {\n const [resolvedA, resolvedB] = await Promise.all([this.resolve(a), this.resolve(b)]);\n const [token0Symbol, token1Symbol] = orderSymbols(resolvedA.symbol, resolvedB.symbol);\n return {\n token0: token0Symbol === resolvedA.symbol ? resolvedA : resolvedB,\n token1: token1Symbol === resolvedB.symbol ? resolvedB : resolvedA,\n flipped: token0Symbol !== resolvedA.symbol,\n };\n }\n}\n\nfunction parseSymbols(value: unknown): TradingSymbol[] {\n if (!Array.isArray(value) || !value.every(isTradingSymbol)) {\n throw new GSwapSDKError('Backend returned an invalid symbol list.', 'INVALID_CHAIN_RESPONSE', {\n data: value,\n });\n }\n return value;\n}\n\nfunction isTradingSymbol(value: unknown): value is TradingSymbol {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Record<string, unknown>;\n return (\n typeof entry['symbol'] === 'string' &&\n typeof entry['collection'] === 'string' &&\n typeof entry['category'] === 'string' &&\n typeof entry['type'] === 'string' &&\n typeof entry['additionalKey'] === 'string' &&\n typeof entry['decimals'] === 'number' &&\n Number.isInteger(entry['decimals']) &&\n entry['decimals'] >= 0\n );\n}\n\nfunction isCompositeKey(ref: string): boolean {\n return ref.includes('|') || ref.includes('$');\n}\n\n/** Alias exported for callers that use the contract's shorter type name. */\nexport type TokenClassKey = GalaChainTokenClassKey;\n","import BigNumber from 'bignumber.js';\nimport type { NumericAmount } from '../types/amounts.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { orderSymbols, readOrderedSymbols, type TokenRef } from '../utils/ordering.js';\nimport { validateFee, validateNumericAmount } from '../utils/validation.js';\nimport type { ChainSubmitOptions } from './gateway.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport type { GalaChainSigner } from './signers.js';\nimport { SubmittedTransaction, type ConfirmOptions } from './submitted_transaction.js';\nimport type { AppliedTrade } from '../types/v2_results.js';\nimport type { HttpRequestor } from '../types/http_requestor.js';\nimport type { Symbols } from './symbols.js';\n\n/** The swap backend's apply-results key constraint (`apply-results.dto.ts`). */\nconst UNIQUE_KEY_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/u;\n\nexport type SwapAmount =\n | {\n exactIn: NumericAmount;\n exactOut?: undefined;\n amountOutMinimum?: NumericAmount | undefined;\n amountInMaximum?: undefined;\n }\n | {\n exactIn?: undefined;\n exactOut: NumericAmount;\n amountOutMinimum?: undefined;\n amountInMaximum?: NumericAmount | undefined;\n };\ninterface SwapGateway {\n submit: (\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<SubmittedTransaction<AppliedTrade>>;\n readonly dexBackendBaseUrl: string;\n readonly httpRequestor: HttpRequestor;\n readonly requestTimeoutMs: number;\n}\ntype SwapSymbols = Pick<Symbols, 'resolve'>;\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: SwapSymbols,\n private readonly signer?: GalaChainSigner,\n private readonly walletAddress?: string,\n ) {}\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 ): Promise<SubmittedTransaction<AppliedTrade>> {\n validateFee(fee);\n\n const dto = await this.buildRequestTradeDto(tokenIn, tokenOut, fee, amount);\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n const signedDto = await this.signer.signObject('RequestTrade', dto);\n const submitOptions =\n this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress };\n return this.gateway.submit('RequestTrade', signedDto, submitOptions);\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('gswap-sdk-2f1c…');\n * ```\n */\n public async confirmSwap(uniqueKey: string, options?: ConfirmOptions): Promise<AppliedTrade> {\n if (!UNIQUE_KEY_PATTERN.test(uniqueKey)) {\n throw new GSwapSDKError(\n 'uniqueKey must be 1-128 characters of A-Z, a-z, 0-9, \".\", \"_\", \":\" or \"-\".',\n 'VALIDATION_ERROR',\n { uniqueKey },\n );\n }\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 });\n return transaction.confirm({ initialDelayMs: 0, ...options });\n }\n\n private async buildRequestTradeDto(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n ): Promise<Record<string, unknown>> {\n const tokenInSymbol = await resolveSymbol(this.symbols, tokenIn);\n const tokenOutSymbol = await resolveSymbol(this.symbols, tokenOut);\n const ordered = readOrderedSymbols(orderSymbols(tokenInSymbol, tokenOutSymbol));\n const tokenInIsToken0 = tokenInSymbol === ordered.token0;\n\n const dto: Record<string, unknown> = {\n token0: ordered.token0,\n token1: ordered.token1,\n fee,\n uniqueKey: `gswap-sdk-${globalThis.crypto.randomUUID()}`,\n };\n\n if ('exactIn' in amount) {\n const exactIn = amount.exactIn;\n if (exactIn === undefined) {\n throw new GSwapSDKError('exactIn is required for an exact-input swap.', 'VALIDATION_ERROR');\n }\n validateNumericAmount(exactIn, 'exactIn');\n dto[tokenInIsToken0 ? 'sell0Qty' : 'sell1Qty'] = toDecimalString(exactIn);\n if (amount.amountOutMinimum !== undefined) {\n validateNumericAmount(amount.amountOutMinimum, 'amountOutMinimum', true);\n dto['amountOutMinimum'] = toDecimalString(amount.amountOutMinimum);\n }\n } else {\n const exactOut = amount.exactOut;\n if (exactOut === undefined) {\n throw new GSwapSDKError(\n 'exactOut is required for an exact-output swap.',\n 'VALIDATION_ERROR',\n );\n }\n validateNumericAmount(exactOut, 'exactOut');\n dto[tokenInIsToken0 ? 'buy1Qty' : 'buy0Qty'] = toDecimalString(exactOut);\n if (amount.amountInMaximum !== undefined) {\n validateNumericAmount(amount.amountInMaximum, 'amountInMaximum', true);\n dto['amountInMaximum'] = toDecimalString(amount.amountInMaximum);\n }\n }\n return dto;\n }\n}\n\nfunction toDecimalString(amount: NumericAmount): string {\n return new BigNumber(amount).toFixed();\n}\n\nasync function resolveSymbol(symbols: SwapSymbols, token: TokenRef): Promise<string> {\n const resolved = await symbols.resolve(token);\n if (resolved.symbol.length > 0) return resolved.symbol;\n throw new GSwapSDKError('Token could not be resolved to a trading symbol.', 'SYMBOL_NOT_FOUND', {\n token,\n });\n}\n","/** SDK deployment environment. */\nexport type GSwapEnv = 'prod' | 'stage';\n\n/** Backend URL used by one SDK deployment environment. */\nexport interface GSwapEnvironmentConfig {\n dexBackendBaseUrl: string;\n}\n\n/** Built-in GalaSwap deployment environments. */\nexport const GSWAP_ENVIRONMENTS: Readonly<Record<GSwapEnv, GSwapEnvironmentConfig>> = {\n prod: {\n dexBackendBaseUrl: 'https://dex-backend-prod1.defi.gala.com',\n },\n stage: {\n dexBackendBaseUrl: 'https://swap-backend.stage.defi.ovh.gala.com',\n },\n};\n","import { Assets } from './assets.js';\nimport { ChainGateway } from './gateway.js';\nimport { HttpClient } from './http_client.js';\nimport { Pools } from './pools.js';\nimport { Positions } from './positions.js';\nimport { Quoting } from './quoting.js';\nimport type { GalaChainSigner } from './signers.js';\nimport { Symbols } from './symbols.js';\nimport { Swaps } from './swaps.js';\nimport type { HttpRequestor } from '../types/http_requestor.js';\nimport type { GSwapEnv } from '../types/env.js';\nimport { GSWAP_ENVIRONMENTS } from '../types/env.js';\n\n/** Options for constructing a backend-routed SDK client. */\nexport interface GSwapOptions {\n signer?: GalaChainSigner | undefined;\n walletAddress?: string | undefined;\n env?: GSwapEnv | undefined;\n dexBackendBaseUrl?: string | undefined;\n httpRequestor?: HttpRequestor | undefined;\n chainCallTimeoutMs?: number | undefined;\n}\n\n/** Main entry point for the current GalaChainDex SDK. */\nexport class GSwap {\n public readonly dexBackendBaseUrl: string;\n public readonly chainCallTimeoutMs: number;\n public readonly signer: GalaChainSigner | undefined;\n public readonly walletAddress: string | undefined;\n public readonly gateway: ChainGateway;\n public readonly symbols: Symbols;\n public readonly quoting: Quoting;\n public readonly pools: Pools;\n public readonly positions: Positions;\n public readonly swaps: Swaps;\n public readonly assets: Assets;\n\n /**\n * Create an SDK client for prod or stage.\n *\n * @example\n * ```typescript\n * const gSwap = new GSwap({ env: 'stage' });\n * const symbols = await gSwap.symbols.list();\n * ```\n */\n constructor(options?: GSwapOptions) {\n const environment = GSWAP_ENVIRONMENTS[options?.env ?? 'prod'];\n this.dexBackendBaseUrl = trimTrailingSlash(\n options?.dexBackendBaseUrl ?? environment.dexBackendBaseUrl,\n );\n this.chainCallTimeoutMs = options?.chainCallTimeoutMs ?? 30_000;\n this.signer = options?.signer;\n this.walletAddress = options?.walletAddress;\n\n const httpClient = new HttpClient(options?.httpRequestor, this.chainCallTimeoutMs);\n this.gateway = new ChainGateway({\n dexBackendBaseUrl: this.dexBackendBaseUrl,\n chainCallTimeoutMs: this.chainCallTimeoutMs,\n ...(options?.httpRequestor === undefined ? {} : { httpRequestor: options.httpRequestor }),\n ...(this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress }),\n });\n this.symbols = new Symbols(this.gateway);\n this.quoting = new Quoting(this.dexBackendBaseUrl, httpClient, this.symbols);\n this.pools = new Pools(this.gateway, this.symbols);\n this.positions = new Positions(this.gateway, this.symbols, this.signer, this.walletAddress);\n this.swaps = new Swaps(this.gateway, this.symbols, this.signer, this.walletAddress);\n this.assets = new Assets(this.dexBackendBaseUrl, httpClient);\n }\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/u, '');\n}\n","/**\n * Genuine EIP-712 typed-data signing for the four v2 dex-contract operations proven (2026-09-16,\n * live bisection against stage — see defi-backend's `chain-findings-artifact` memory /\n * https://claude.ai/artifact/3N9MevSjoQdU7gqnVB3dfU) to recover the `client|` identity correctly\n * via `eth_signTypedData_v4`, unlike `personal_sign` (which only ever resolves the bare `eth|`\n * form — see `BrowserWalletSigner`'s own doc comment). Mirrors frontend_v2's\n * `src/Services/eip712Types.ts` + `readWriteUtilsV2.ts`'s `EIP712_FIELD_COMPLETERS` exactly —\n * ported here rather than shared as a package because gswap-sdk has no frontend_v2 dependency\n * and should not gain one for four small functions.\n */\n\nexport type EIP712Types = Record<string, Array<{ name: string; type: string }>>;\n\n/**\n * Derives the EIP-712 `types` for a DTO from its runtime shape.\n *\n * The generated `types` travel with the signed payload and are what BOTH sides hash, so they\n * must enumerate EVERY field the chain-side DTO will carry. GalaChain refuses any signature\n * whose `types` leave a DTO field uncovered (`assertNoUnsignedFields`, the fix for the\n * 2026-08-18 unsigned-field-injection drain); when that happens signature recovery fails\n * outright and the chain reports \"Missing signerPublicKey or signerAddress field in dto\".\n */\nexport function generateEIP712Types(\n typeName: string,\n params: Record<string, unknown>,\n): EIP712Types {\n const types: EIP712Types = {};\n types[typeName] = [];\n\n // Every `name` this is ever called with (the top-level `typeName`, or a nested struct's own\n // name) is unconditionally assigned `types[name] = []` on the line immediately before any\n // recursive call that could reach here; TypeScript still types `types[name]` as\n // possibly-undefined (index-signature access), so the guard below stays for real type safety\n // even though no current call path can actually trigger it.\n function fieldsFor(name: string): Array<{ name: string; type: string }> {\n const fields = types[name];\n /* c8 ignore next */\n if (!fields) throw new Error(`Missing EIP-712 type definition for ${name}`);\n return fields;\n }\n\n function addField(\n name: string,\n fieldValue: unknown,\n parentTypeName: string,\n onlyGetType = false,\n ): string | undefined {\n if (Array.isArray(fieldValue)) {\n const type =\n fieldValue.length > 0 ? addField(name, fieldValue[0], parentTypeName, true) : 'string';\n if (!onlyGetType) fieldsFor(parentTypeName).push({ name, type: (type ?? name) + '[]' });\n } else if (typeof fieldValue === 'object' && fieldValue !== null) {\n if (types[name]) {\n throw new Error('Name collisions not yet supported');\n }\n types[name] = [];\n Object.entries(fieldValue).forEach(([key, value]) => {\n addField(key, value, name);\n });\n if (!onlyGetType) fieldsFor(parentTypeName).push({ name, type: name });\n } else {\n let eipType: string;\n switch (typeof fieldValue) {\n case 'string':\n eipType = 'string';\n break;\n case 'number':\n eipType = 'int256';\n break;\n case 'boolean':\n eipType = 'bool';\n break;\n case 'bigint':\n case 'symbol':\n case 'undefined':\n case 'function':\n case 'object':\n throw new Error(\n `Unsupported type, ${typeof fieldValue}, value: ${Object.prototype.toString.call(fieldValue)}`,\n );\n }\n if (onlyGetType) {\n return eipType;\n }\n fieldsFor(parentTypeName).push({ name, type: eipType });\n }\n return undefined;\n }\n\n Object.entries(params).forEach(([key, value]) => {\n addField(key, value, typeName);\n });\n\n return types;\n}\n\n/** Matches every genuine-EIP-712 probe that has actually recovered `client|` on stage. */\nexport const EIP712_DOMAIN: { name: string; chainId: number } = { name: 'ethereum', chainId: 1 };\n\n/**\n * The four v2 operations proven to recover the signer correctly via genuine EIP-712: `RequestTrade`\n * never had the problem (one numeric field). `AddLiquidity`/`RemoveLiquidity`/\n * `CollectPositionFees` each need their `types` completed with a handful of fields their real\n * server-side DTO always carries — see the `complete*Fields` functions below. `CreatePool` is a\n * genuinely different, unsolved problem (nested `TokenClassKey` structs, not a flat\n * missing-field gap) and is NOT in this set — callers must keep using `personal-sign` for it.\n */\nexport const EIP712_CAPABLE_METHODS: ReadonlySet<string> = new Set([\n 'RequestTrade',\n 'AddLiquidity',\n 'RemoveLiquidity',\n 'CollectPositionFees',\n]);\n\n/**\n * Every `complete*Fields` function below shares the same two live-proven rules:\n * 1. Numeric completeness fields MUST be JS `number`, never numeric strings —\n * `generateEIP712Types` infers a field's Solidity type from `typeof`, and declaring one as\n * EIP-712 `string` instead of `int256` breaks recovery identically to omitting the field\n * entirely (verified live on AddLiquidity: `amount0Min: '0'` fails with the exact same\n * \"Missing signerPublicKey\" error as `amount0Min` being absent; `amount0Min: 0` succeeds).\n * 2. `positionId` has no such constraint — an empty string works, and does not target an\n * existing position (`positionId: ''` created a fresh position on AddLiquidity, not an add\n * to position id `''`; on RemoveLiquidity/CollectPositionFees the real position is still\n * resolved from `token0`/`token1`/`fee`/`tickLower`/`tickUpper`, not from this field).\n */\nfunction numericOr0(dto: Record<string, unknown>, field: string): number {\n return typeof dto[field] === 'number' ? dto[field] : 0;\n}\n\n/**\n * `AddLiquidity`'s real server-side DTO always carries `amount0Desired`/`amount0Min`/\n * `amount1Desired`/`amount1Min`/`positionId` once reconstructed, regardless of which deposit\n * convention the caller used (`Positions.addLiquidityByTicks` only ever sends\n * `depositQuantityToken0`/`depositQuantityToken1`). Proven empirically by bisection: none of the\n * five alone fixes recovery, all five together does (live 201, tx `407d9b24...`, block\n * `2429022`).\n */\nfunction completeAddLiquidityFields(dto: Record<string, unknown>): Record<string, unknown> {\n return {\n ...dto,\n amount0Desired: numericOr0(dto, 'amount0Desired'),\n amount0Min: numericOr0(dto, 'amount0Min'),\n amount1Desired: numericOr0(dto, 'amount1Desired'),\n amount1Min: numericOr0(dto, 'amount1Min'),\n positionId: dto['positionId'] ?? '',\n };\n}\n\n/**\n * `RemoveLiquidity`'s real server-side DTO always carries `amount`/`amount0Min`/`amount1Min`/\n * `positionId` — `Positions.removeLiquidity` only ever sends a `withdrawalQuantityTokenX` (or\n * neither, for a full close). Proven empirically: every subset of these four fails, all four\n * together succeeds (live, random-signer probe — recovery confirmed by the response moving from\n * \"Missing signerPublicKey\" to a genuine position-not-found 404).\n */\nfunction completeRemoveLiquidityFields(dto: Record<string, unknown>): Record<string, unknown> {\n return {\n ...dto,\n amount: numericOr0(dto, 'amount'),\n amount0Min: numericOr0(dto, 'amount0Min'),\n amount1Min: numericOr0(dto, 'amount1Min'),\n positionId: dto['positionId'] ?? '',\n };\n}\n\n/**\n * `CollectPositionFees`'s real server-side DTO always carries `amount0Requested`/\n * `amount1Requested`/`positionId` — `Positions.collectPositionFees` sends only the five identity\n * fields. Proven empirically the same way as `completeRemoveLiquidityFields`.\n */\nfunction completeCollectPositionFeesFields(dto: Record<string, unknown>): Record<string, unknown> {\n return {\n ...dto,\n amount0Requested: numericOr0(dto, 'amount0Requested'),\n amount1Requested: numericOr0(dto, 'amount1Requested'),\n positionId: dto['positionId'] ?? '',\n };\n}\n\nexport const EIP712_FIELD_COMPLETERS: Readonly<\n Record<string, (dto: Record<string, unknown>) => Record<string, unknown>>\n> = {\n AddLiquidity: completeAddLiquidityFields,\n RemoveLiquidity: completeRemoveLiquidityFields,\n CollectPositionFees: completeCollectPositionFeesFields,\n};\n\n/**\n * Completes a DTO's fields for EIP-712 signing (a no-op for methods with no known gap, e.g.\n * `RequestTrade`) and derives its `types`. Exported separately from the signing call itself so tests\n * can assert on the exact payload without needing a live provider.\n */\nexport function buildEIP712Payload(\n methodName: string,\n dto: Record<string, unknown>,\n): { completedDto: Record<string, unknown>; types: EIP712Types } {\n const completer = EIP712_FIELD_COMPLETERS[methodName];\n const completedDto = completer ? completer(dto) : dto;\n const types = generateEIP712Types(methodName, completedDto);\n return { completedDto, types };\n}\n","import { serialize, signatures } from '@gala-chain/api';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport {\n buildEIP712Payload,\n EIP712_CAPABLE_METHODS,\n EIP712_DOMAIN,\n type EIP712Types,\n} from '../utils/eip712.js';\n\n// Personal-sign prefix, computed the way THE CHAIN verifies it.\n//\n// GalaChain (SDK 3.x) recovers a personal-signed DTO from\n// keccak256(<prefix field> + <canonical JSON of the DTO WITHOUT the prefix field>)\n// and a browser wallet's `personal_sign` (EIP-191) hashes\n// \"\\u0019Ethereum Signed Message:\\n\" + <byte length of message> + <message>.\n// They agree exactly when the wallet signs the bare canonical DTO and `prefix` is the EIP-191\n// header for that message's UTF-8 BYTE length. Any other message still yields a valid-looking\n// signature — it just recovers to an address nobody holds. This SDK used to embed `prefix` in\n// the signed message (the SDK 1.10 client recipe): observed on stage 2026-09-23, such a\n// MetaMask-signed CreatePool executed on chain under a phantom creator, and defi-backend's\n// bouncer now rejects that shape outright.\n//\n// `@gala-chain/connect`'s prefix helper must NOT be used for wallet `personal_sign`: its\n// fixpoint counts the prefix itself and targets the SDK's raw-payload signer. The same header\n// is also what Gala Wallet's `gala_signChainDto` (personal-sign scheme) prepends before hashing,\n// so one value serves both paths.\n//\n// Built via String.fromCharCode rather than a literal escape ON PURPOSE: the EIP-191 control\n// byte is invisible either way once it's a real character in the string, but a literal escape\n// in source is itself a raw control byte sitting in the file the moment any tool decodes it\n// (an editor save, a diff, a copy-paste) — this keeps the source text itself ordinary and\n// constructs the byte at runtime instead.\nconst ETHEREUM_SIGNED_MESSAGE = String.fromCharCode(0x19) + 'Ethereum Signed Message:\\n';\n\n/** The EIP-191 header for `dto`'s canonical JSON (UTF-8 byte length; any `prefix` on it is ignored). */\nfunction personalSignPrefixFor(dto: Record<string, unknown>): string {\n const withoutPrefix: Record<string, unknown> = { ...dto };\n delete withoutPrefix['prefix'];\n const message = serialize(withoutPrefix);\n return ETHEREUM_SIGNED_MESSAGE + String(new TextEncoder().encode(message).length);\n}\n\n/** The signing schemes supported by the Gala Wallet signer. */\nexport type GalaWalletScheme = 'native' | 'personal-sign';\n\n/** The request surface used by an EIP-1193 browser wallet. */\nexport interface BrowserWalletProvider {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n}\n\ninterface GalaWalletProvider {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n}\n\ninterface WindowWithGala {\n gala?: GalaWalletProvider;\n}\n\ninterface GlobalWithWindow {\n window?: WindowWithGala;\n}\n\ntype SignedDto<T extends Record<string, unknown>> = T & { signature: string };\n\n/**\n * A signer for complete GalaChain write bodies.\n *\n * Implementations return the DTO fields together with the signature that belongs in the\n * gateway request body. Signer identity is recovered from that signature; implementations do\n * not add signer hints, typed-data metadata, or a domain.\n */\nexport interface GalaChainSigner {\n /**\n * Signs a DTO for a named GalaChain contract method.\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n */\n signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;\n}\n\nfunction getWalletProvider(): GalaWalletProvider {\n const globalObject = globalThis as GlobalWithWindow;\n const wallet = globalObject.window?.gala;\n if (!wallet) {\n throw new GSwapSDKError(\n 'Gala wallet is not available. Please ensure the Gala wallet is connected.',\n 'GALA_WALLET_NOT_AVAILABLE',\n );\n }\n return wallet;\n}\n\nfunction getNativeSignature(value: unknown): string {\n if (typeof value !== 'string') {\n throw new GSwapSDKError('Wallet returned an invalid signature.', 'INVALID_SIGNATURE');\n }\n if (!/^[0-9a-fA-F]{130}$/u.test(value)) {\n throw new GSwapSDKError('Wallet returned an invalid native signature.', 'INVALID_SIGNATURE');\n }\n return value;\n}\n\nfunction getPersonalSignature(value: unknown): string {\n if (typeof value !== 'string' || !/^(?:0x)?[0-9a-fA-F]{130}$/u.test(value)) {\n throw new GSwapSDKError(\n 'Wallet returned an invalid personal-sign signature.',\n 'INVALID_SIGNATURE',\n );\n }\n return value;\n}\n\nfunction normalizeEthereumAccount(address: string, allowGalaPrefix: boolean): string {\n const normalized = allowGalaPrefix && address.startsWith('eth|') ? address.slice(4) : address;\n if (!/^0x[0-9a-fA-F]{40}$/u.test(normalized)) {\n throw new GSwapSDKError(\n 'Wallet address must be the selected Ethereum account in 0x-prefixed form.',\n 'VALIDATION_ERROR',\n { type: 'INVALID_WALLET_ADDRESS', value: address },\n );\n }\n return `0x${normalized.slice(2).toLowerCase()}`;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n if (typeof error === 'object' && error !== null && 'message' in error) {\n const message = error.message;\n return typeof message === 'string' ? message : '';\n }\n return '';\n}\n\n// Deliberately does NOT match a generic \"invalid params\" (JSON-RPC -32602) — that code fires\n// for many validation failures unrelated to scheme support (e.g. a malformed DTO), and a false\n// match here would permanently latch effectiveScheme to 'personal-sign' for every future call\n// on this signer, even though native signing was never actually unsupported.\nfunction isUnsupportedNativeSchemeError(error: unknown): boolean {\n return /unsupported|unknown scheme/i.test(getErrorMessage(error));\n}\n\nfunction personalSign<T extends Record<string, unknown>>(\n provider: GalaWalletProvider | BrowserWalletProvider,\n dto: T,\n walletAddress: string,\n methodName?: string,\n): Promise<T & { prefix: string; signature: string }> {\n const prefix = personalSignPrefixFor(dto);\n const payload = { ...dto, prefix };\n // A browser wallet's `personal_sign` applies the EIP-191 header ITSELF, so it must sign the\n // bare DTO; Gala Wallet's `gala_signChainDto` (personal-sign scheme) instead extracts the\n // `prefix` field from what it is handed and prepends it before hashing, so it is handed the\n // prefixed payload. Both submit `{ ...dto, prefix, signature }`.\n const params =\n methodName !== undefined\n ? [serialize(payload), walletAddress, methodName]\n : [serialize(dto), walletAddress];\n\n return provider\n .request({ method: methodName !== undefined ? 'gala_signChainDto' : 'personal_sign', params })\n .then((value) => ({ ...payload, signature: getPersonalSignature(value) }));\n}\n\n/**\n * Signs a DTO via genuine EIP-712 (`eth_signTypedData_v4`) — correctly resolves the `client|`\n * identity, unlike `personal_sign`, for the operations in `EIP712_CAPABLE_METHODS`.\n *\n * Constructs the raw JSON-RPC payload by hand (`{domain, types: {...types, EIP712Domain},\n * primaryType, message}`) rather than depending on ethers.js, matching exactly what\n * `ethers.TypedDataEncoder.getPayload`/`Wallet.signTypedData` produce internally — verified\n * byte-for-byte equivalent (same recovered address from the same signature against both\n * constructions) before this shipped, since gswap-sdk deliberately has no ethers dependency.\n */\nfunction signEIP712<T extends Record<string, unknown>>(\n provider: BrowserWalletProvider,\n methodName: string,\n dto: T,\n walletAddress: string,\n): Promise<T & { types: EIP712Types; domain: typeof EIP712_DOMAIN; signature: string }> {\n const { completedDto, types } = buildEIP712Payload(methodName, dto);\n const prefix = personalSignPrefixFor(completedDto);\n const message = { ...completedDto, prefix };\n const eip712Domain = [\n { name: 'name', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n ];\n const payload = {\n domain: EIP712_DOMAIN,\n types: { ...types, EIP712Domain: eip712Domain },\n primaryType: methodName,\n message,\n };\n\n return provider\n .request({\n method: 'eth_signTypedData_v4',\n params: [walletAddress, JSON.stringify(payload)],\n })\n .then((value) => ({\n ...(message as T & { prefix: string }),\n types,\n domain: EIP712_DOMAIN,\n signature: getPersonalSignature(value),\n }));\n}\n\n/**\n * A GalaChain native signer backed by a secp256k1 private key.\n *\n * Native signing produces the bare GalaChain signature format, without a personal-sign prefix\n * or EIP-712 metadata. The private-key identity is recovered by the chain.\n */\nexport class PrivateKeySigner implements GalaChainSigner {\n private readonly keyBuffer: Buffer;\n\n /**\n * Creates a native signer from a hex or base64 secp256k1 private key.\n *\n * @example\n * ```typescript\n * const signer = new PrivateKeySigner('1'.padStart(64, '0'));\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n */\n constructor(privateKey: string) {\n this.keyBuffer = signatures.normalizePrivateKey(privateKey);\n }\n\n /**\n * Signs the DTO with GalaChain native signing.\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('RequestTrade', {\n * token0: 'GALA',\n * token1: 'GUSDC',\n * fee: 3000,\n * });\n * ```\n */\n public signObject<T extends Record<string, unknown>>(\n _methodName: string,\n dto: T,\n ): Promise<SignedDto<T>> {\n const signature = signatures.getSignature(dto, this.keyBuffer);\n return Promise.resolve({ ...dto, signature });\n }\n}\n\n/**\n * A Gala Wallet signer using native GalaChain signing, with an opt-in personal-sign mode and\n * automatic fallback for older wallets.\n *\n * The selected Ethereum account is passed to Gala Wallet. Personal-sign resolves the bare\n * `eth|` identity; the legacy EIP-712 `eth_signTypedData` path is not used. The fallback calls\n * `gala_signChainDto([serialize({ ...dto, prefix }), walletAddress, methodName])`.\n */\nexport class GalaWalletSigner implements GalaChainSigner {\n /** The wallet address supplied to Gala Wallet for each signing request. */\n public readonly walletAddress: string;\n\n /** The scheme currently used, including any automatic native-to-personal fallback. */\n public effectiveScheme: GalaWalletScheme;\n\n /**\n * Creates a Gala Wallet signer.\n *\n * @example\n * ```typescript\n * const signer = new GalaWalletSigner('0x0123456789012345678901234567890123456789');\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n *\n * @param walletAddress - The selected Ethereum account (`0x` plus 40 hex digits); Gala Wallet's\n * `eth|0x...` form is also accepted and normalized.\n * @param options - Select native signing or personal-sign explicitly.\n */\n constructor(walletAddress: string, options: { scheme?: GalaWalletScheme | undefined } = {}) {\n this.walletAddress = normalizeEthereumAccount(walletAddress, true);\n this.effectiveScheme = options.scheme ?? 'native';\n }\n\n /**\n * Signs a DTO through `gala_signChainDto`.\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('AddLiquidity', {\n * token0: 'GALA',\n * token1: 'GUSDC',\n * tickLower: -60,\n * tickUpper: 60,\n * });\n * ```\n */\n public async signObject<T extends Record<string, unknown>>(\n methodName: string,\n dto: T,\n ): Promise<SignedDto<T>> {\n const wallet = getWalletProvider();\n\n if (this.effectiveScheme === 'personal-sign') {\n return personalSign(wallet, dto, this.walletAddress, methodName);\n }\n\n try {\n const signature = await wallet.request({\n method: 'gala_signChainDto',\n params: [serialize(dto), this.walletAddress, methodName, 'native'],\n });\n return { ...dto, signature: getNativeSignature(signature) };\n } catch (error: unknown) {\n if (!isUnsupportedNativeSchemeError(error)) {\n throw error;\n }\n this.effectiveScheme = 'personal-sign';\n return personalSign(wallet, dto, this.walletAddress, methodName);\n }\n }\n}\n\n/**\n * A personal-sign signer for MetaMask and other EIP-1193 browser wallets.\n *\n * The chain recovers this signature using the EIP-191 wrap applied by the wallet to\n * `personal_sign`. This is the browser-wallet path used by the v2 frontend and resolves the\n * bare `eth|` identity.\n */\nexport class BrowserWalletSigner implements GalaChainSigner {\n /**\n * Creates a browser-wallet signer.\n *\n * Defaults to `personal_sign` — unchanged from every existing integration, since it only ever\n * resolves the bare `eth|` identity and changing that silently would be a real behavior\n * break for anyone already depending on it. Pass `{ scheme: 'eip712' }` to correctly resolve\n * a registered `client|` alias instead, for `RequestTrade`/`AddLiquidity`/`RemoveLiquidity`/\n * `CollectPositionFees` (`EIP712_CAPABLE_METHODS`) — `CreatePool` and any other method still\n * falls back to `personal_sign` even in `'eip712'` mode, since its EIP-712 signing is a\n * separate, unsolved chain-side problem.\n *\n * @example\n * ```typescript\n * const signer = new BrowserWalletSigner(window.ethereum, '0x0123456789012345678901234567890123456789');\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n * @example\n * ```typescript\n * // Correctly resolves a registered client| alias instead of the bare eth| address.\n * const signer = new BrowserWalletSigner(window.ethereum, walletAddress, { scheme: 'eip712' });\n * ```\n */\n constructor(\n private readonly provider: BrowserWalletProvider,\n walletAddress: string,\n options: { scheme?: 'personal-sign' | 'eip712' } = {},\n ) {\n this.walletAddress = normalizeEthereumAccount(walletAddress, false);\n this.scheme = options.scheme ?? 'personal-sign';\n }\n\n public readonly walletAddress: string;\n private readonly scheme: 'personal-sign' | 'eip712';\n\n /**\n * Signs the DTO with `eth_signTypedData_v4` (when constructed with `{ scheme: 'eip712' }` and\n * `methodName` is in `EIP712_CAPABLE_METHODS`) or the EIP-1193 `personal_sign` method\n * (otherwise — the default).\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('RequestTrade', {\n * token0: 'GALA',\n * token1: 'GUSDC',\n * fee: 3000,\n * });\n * ```\n */\n public signObject<T extends Record<string, unknown>>(\n methodName: string,\n dto: T,\n ): Promise<SignedDto<T>> {\n if (this.scheme === 'eip712' && EIP712_CAPABLE_METHODS.has(methodName)) {\n return signEIP712(this.provider, methodName, dto, this.walletAddress);\n }\n return personalSign(this.provider, dto, this.walletAddress);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["BigNumber","Decimal","BigNumber","asRecord","trimTrailingSlash","resolveSymbol","BigNumber","toDecimalString","resolveSymbol","BigNumber","BigNumber","serialize","globalObject","signatures"],"sources":["../src/classes/gswap_sdk_error.ts","../src/types/fees.ts","../src/utils/ticks.ts","../src/utils/validation.ts","../src/classes/assets.ts","../src/utils/transport.ts","../src/classes/submitted_transaction.ts","../src/classes/gateway.ts","../src/types/env.ts","../src/utils/debug.ts","../src/utils/reconnection.ts","../src/classes/gdex_stream.ts","../src/version.ts","../src/classes/http_client.ts","../src/utils/ordering.ts","../src/classes/pools.ts","../src/classes/positions.ts","../src/classes/quoting.ts","../src/classes/symbols.ts","../src/classes/swaps.ts","../src/classes/gswap.ts","../src/utils/eip712.ts","../src/classes/signers.ts"],"sourcesContent":["import type { GalaChainTokenClassKey } from '../types/token.js';\nimport type { HTTPResponse } from '../types/http_requestor.js';\n\n/** Error raised by the SDK for validation, gateway, chain, or transaction failures. */\nexport class GSwapSDKError extends Error {\n public readonly chainMessage: string | undefined;\n public readonly retryAfterMs: number | undefined;\n\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n chainMessage?: string,\n retryAfterMs?: number,\n ) {\n super(message);\n this.name = 'GSwapSDKError';\n this.chainMessage = chainMessage;\n this.retryAfterMs = retryAfterMs;\n }\n\n /** Create the standard missing-signer error. */\n public static noSignerError(): GSwapSDKError {\n return new GSwapSDKError(\n 'This method requires a signer. Please provide a signer to the GSwap constructor.',\n 'NO_SIGNER',\n );\n }\n\n /** Create the error used when confirming a position write without a configured wallet address. */\n public static noWalletAddressError(): GSwapSDKError {\n return new GSwapSDKError(\n 'Cannot confirm this write: no walletAddress was provided to the GSwap constructor, so ' +\n 'the resulting position cannot be looked up to confirm it landed on chain.',\n 'NO_WALLET_ADDRESS',\n );\n }\n\n /** Create the error used when no pool can quote the requested pair. */\n public static noPoolAvailableError(\n tokenIn: GalaChainTokenClassKey | string,\n tokenOut: GalaChainTokenClassKey | string,\n fee?: number,\n ): GSwapSDKError {\n return new GSwapSDKError('No pool is available for the requested pair.', 'NO_POOL_AVAILABLE', {\n tokenIn,\n tokenOut,\n ...(fee === undefined ? {} : { fee }),\n });\n }\n\n /** Create the error used when a pool lacks liquidity for a quote. */\n public static insufficientLiquidityError(\n tokenIn: GalaChainTokenClassKey | string,\n tokenOut: GalaChainTokenClassKey | string,\n fee?: number,\n ): GSwapSDKError {\n return new GSwapSDKError(\n 'The selected pool has insufficient liquidity for the requested quote.',\n 'INSUFFICIENT_LIQUIDITY',\n { tokenIn, tokenOut, ...(fee === undefined ? {} : { fee }) },\n );\n }\n\n /** Convert a chain-gateway bounce into a typed SDK error. */\n public static fromGatewayBounce(\n code: string,\n message: string,\n status: number,\n retryAfterMs?: number,\n ): GSwapSDKError {\n const details: Record<string, unknown> = { status, chainMessage: message };\n if (retryAfterMs !== undefined) details['retryAfterMs'] = retryAfterMs;\n const sdkMessage =\n code === 'CHAIN_DISPATCH_FAILED' ? message : `Gateway rejected ${code}: ${message}`;\n return new GSwapSDKError(sdkMessage, code, details, message, retryAfterMs);\n }\n\n /** Convert a GalaChain `Status: 0` response into a typed SDK error. */\n public static fromChainError(\n errorKey: string,\n message: string,\n details?: Record<string, unknown>,\n ): GSwapSDKError {\n return new GSwapSDKError(\n `GalaChain error ${errorKey}: ${message}`,\n errorKey,\n { ...details, errorKey, message },\n message,\n );\n }\n\n /** Create the error used when a token is not registered by the current DEX contract. */\n public static unknownTokenError(token: GalaChainTokenClassKey | string): GSwapSDKError {\n const tokenText = typeof token === 'string' ? token : JSON.stringify(token);\n return new GSwapSDKError(\n `Token ${tokenText} has no trading symbol on the new DEX contract (no gcdex pool includes it yet).`,\n 'UNKNOWN_TOKEN',\n { token },\n );\n }\n\n /** Create the error used when apply-results confirmation does not arrive in time. */\n public static confirmationTimeoutError(uniqueKey: string, cause?: unknown): GSwapSDKError {\n return new GSwapSDKError(\n 'Transaction confirmation timed out; the trade may still apply. Confirm the same uniqueKey again later instead of resubmitting.',\n 'CONFIRMATION_TIMEOUT',\n { uniqueKey, ...(cause === undefined ? {} : { cause }) },\n );\n }\n\n /** Convert an unexpected HTTP response into an SDK error. */\n public static async fromErrorResponse(\n url: string,\n response: HTTPResponse,\n ): Promise<GSwapSDKError> {\n const bodyText = await response.text();\n const bodyJson: unknown = parseJson(bodyText);\n const errorObject = getObjectProperty(bodyJson, 'error');\n const errorKey = getStringProperty(errorObject, 'ErrorKey');\n const message = getStringProperty(errorObject, 'Message');\n\n if (errorKey !== undefined && message !== undefined) {\n return new GSwapSDKError(\n `GalaChain Error ${errorKey} from ${url}: ${message}`,\n errorKey,\n { message, errorKey, status: response.status, body: bodyJson, url },\n message,\n );\n }\n\n return new GSwapSDKError(`Unexpected HTTP Error ${response.status} from ${url}`, 'HTTP_ERROR', {\n status: response.status,\n body: bodyJson ?? bodyText,\n url,\n });\n }\n}\n\n/** Narrow an object property without trusting a cast at a network boundary. */\nexport function getObjectProperty(\n value: unknown,\n property: string,\n): Record<string, unknown> | undefined {\n if (typeof value !== 'object' || value === null || !(property in value)) return undefined;\n const propertyValue = (value as Record<string, unknown>)[property];\n return typeof propertyValue === 'object' && propertyValue !== null\n ? (propertyValue as Record<string, unknown>)\n : undefined;\n}\n\n/** Read a string property from an unknown object. */\nexport function getStringProperty(value: unknown, property: string): string | undefined {\n if (typeof value !== 'object' || value === null || !(property in value)) return undefined;\n const propertyValue = (value as Record<string, unknown>)[property];\n return typeof propertyValue === 'string' ? propertyValue : undefined;\n}\n\n/** Parse a response body, preserving non-JSON text for error reporting. */\nexport function parseJson(text: string): unknown {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return undefined;\n }\n}\n","/**\n * Fee tiers for pools.\n */\nexport enum FEE_TIER {\n /** No trading fee. */\n PERCENT_00_00 = 0,\n /** 0.05% fee tier */\n PERCENT_00_05 = 500,\n /** 0.3% fee tier */\n PERCENT_00_30 = 3000,\n /** 1.0% fee tier */\n PERCENT_01_00 = 10000,\n}\n\n/** Tick spacing required by the current GalaChainDex contract for each fee tier. */\nexport const TICK_SPACING_BY_FEE: Readonly<Record<FEE_TIER, number>> = {\n [FEE_TIER.PERCENT_00_00]: 200,\n [FEE_TIER.PERCENT_00_05]: 10,\n [FEE_TIER.PERCENT_00_30]: 60,\n [FEE_TIER.PERCENT_01_00]: 200,\n};\n\n/** All fee tiers supported by the current GalaChainDex contract. */\nexport const ALL_FEE_TIERS: readonly FEE_TIER[] = [\n FEE_TIER.PERCENT_00_00,\n FEE_TIER.PERCENT_00_05,\n FEE_TIER.PERCENT_00_30,\n FEE_TIER.PERCENT_01_00,\n];\n","import BigNumber from 'bignumber.js';\nimport { Decimal } from 'decimal.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { TICK_SPACING_BY_FEE } from '../types/fees.js';\n\n/** Minimum tick supported by GalaChainDex. */\nexport const GC_MIN_TICK = -887272;\n/** Maximum tick supported by GalaChainDex. */\nexport const GC_MAX_TICK = 887272;\n\nconst DexMath = BigNumber.clone({\n DECIMAL_PLACES: 60,\n ROUNDING_MODE: BigNumber.ROUND_DOWN,\n});\nconst DexDecimal = Decimal.clone({ precision: 60 });\n\n/** Convert a tick to the corresponding square-root price. */\nexport function tickToSqrtPrice(tick: number): BigNumber {\n return new BigNumber(new DexDecimal(1.0001).pow(tick / 2).toString());\n}\n\n/** Return the greatest tick whose square-root price is no greater than the input. */\nexport function sqrtPriceToTick(sqrtPrice: BigNumber.Value): number {\n let value: BigNumber;\n try {\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — this function's contract is to signal an invalid input via NaN, not\n // to throw, so an unparseable value is just another case for the guard below.\n value = new DexMath(sqrtPrice);\n } catch {\n return Number.NaN;\n }\n if (!value.isFinite() || value.isLessThanOrEqualTo(0)) return Number.NaN;\n\n const approximate = Math.log(value.toNumber() ** 2) / Math.log(1.0001);\n if (!Number.isFinite(approximate)) return Number.NaN;\n // Clamp the seed before the correction loops below — an unclamped seed derived from an\n // out-of-range sqrtPrice (extreme but finite, e.g. 1e20) leaves the loops running past\n // GC_MIN_TICK/GC_MAX_TICK for a long time; an infinite (overflowed) seed would never\n // enter the increasing loop and never terminate the decreasing one.\n let tick = Math.min(GC_MAX_TICK, Math.max(GC_MIN_TICK, Math.floor(approximate)));\n while (tick < GC_MAX_TICK && tickToSqrtPrice(tick + 1).isLessThanOrEqualTo(value)) tick += 1;\n while (tick > GC_MIN_TICK && tickToSqrtPrice(tick).isGreaterThan(value)) tick -= 1;\n return tick;\n}\n\n/** Return the greatest integer tick whose token1/token0 price is no greater than `price`. */\nexport function tickFromPrice(price: BigNumber.Value): number {\n const priceText =\n typeof price === 'string'\n ? price\n : typeof price === 'number'\n ? price.toString()\n : BigNumber.isBigNumber(price)\n ? price.toString()\n : 'NaN';\n const value = new DexDecimal(priceText);\n if (!value.isFinite() || value.lessThanOrEqualTo(0)) return Number.NaN;\n if (!Number.isFinite(value.toNumber())) return Number.NaN;\n const tick = value.ln().dividedBy(new DexDecimal(1.0001).ln()).floor().toNumber();\n return Number.isFinite(tick) ? tick : Number.NaN;\n}\n\n/** Align a tick down to the nearest multiple of a positive spacing. */\nexport function alignTickDown(tick: number, spacing: number): number {\n assertSpacing(spacing);\n return Math.floor(tick / spacing) * spacing;\n}\n\n/** Align a tick up to the nearest multiple of a positive spacing. */\nexport function alignTickUp(tick: number, spacing: number): number {\n assertSpacing(spacing);\n return Math.ceil(tick / spacing) * spacing;\n}\n\n/** Validate a position range against the global tick bounds and fee-tier spacing. */\nexport function assertTickRange(lower: number, upper: number, fee: FEE_TIER): void {\n const spacing = TICK_SPACING_BY_FEE[fee];\n if (spacing === undefined) throw new RangeError(`Unsupported fee tier: ${fee}`);\n if (!Number.isInteger(lower) || !Number.isInteger(upper)) {\n throw new RangeError('Ticks must be integers');\n }\n if (lower < GC_MIN_TICK || upper > GC_MAX_TICK || lower >= upper) {\n throw new RangeError(\n `Tick range must satisfy ${GC_MIN_TICK} <= lower < upper <= ${GC_MAX_TICK}`,\n );\n }\n if (lower % spacing !== 0 || upper % spacing !== 0) {\n throw new RangeError(`Ticks must be aligned to spacing ${spacing}`);\n }\n}\n\nfunction assertSpacing(spacing: number): void {\n if (!Number.isInteger(spacing) || spacing <= 0)\n throw new RangeError('Tick spacing must be positive');\n}\n","import BigNumber from 'bignumber.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 './ticks.js';\n\nexport function validateNumericAmount(\n amount: NumericAmount,\n parameterName: string,\n allowZero = false,\n): void {\n if (typeof amount === 'number') {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: use a decimal string or BigNumber, not a JavaScript number`,\n 'VALIDATION_ERROR',\n { type: 'INVALID_NUMERIC_AMOUNT', parameterName, value: amount, reason: 'number_input' },\n );\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(\n `Invalid ${parameterName}: must be a finite number`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_NUMERIC_AMOUNT',\n parameterName,\n value: amount,\n reason: 'not_finite',\n },\n );\n }\n\n if (!allowZero && bnAmount.isZero()) {\n throw new GSwapSDKError(`Invalid ${parameterName}: must be positive`, 'VALIDATION_ERROR', {\n type: 'INVALID_NUMERIC_AMOUNT',\n parameterName,\n value: amount,\n reason: 'zero_not_allowed',\n });\n }\n\n if (bnAmount.isNegative()) {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: must be ${allowZero ? 'non-negative' : 'positive'}`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_NUMERIC_AMOUNT',\n parameterName,\n value: amount,\n reason: 'negative',\n },\n );\n }\n}\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(\n 'Invalid price values: use decimal strings or BigNumber values, not JavaScript numbers',\n 'VALIDATION_ERROR',\n { type: 'INVALID_NUMERIC_AMOUNT', reason: 'number_input' },\n );\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(\n 'Invalid price values: all prices must be finite and positive',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_PRICE_VALUES',\n spotPrice,\n lowerPrice,\n upperPrice,\n },\n );\n }\n\n if (bnLowerPrice.isGreaterThan(bnUpperPrice)) {\n throw new GSwapSDKError(\n 'Invalid price range: lower price must be less than or equal to upper price',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_PRICE_RANGE',\n lowerPrice,\n upperPrice,\n },\n );\n }\n}\n\nexport function validateTokenDecimals(decimals: number, parameterName: string): void {\n if (decimals < 0 || !Number.isInteger(decimals)) {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: must be a non-negative integer`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TOKEN_DECIMALS',\n parameterName,\n value: decimals,\n },\n );\n }\n}\n\nexport function validateTickRange(tickLower: number, tickUpper: number): void {\n if (!Number.isInteger(tickLower) || !Number.isInteger(tickUpper)) {\n throw new GSwapSDKError('Invalid tick values: ticks must be integers', 'VALIDATION_ERROR', {\n type: 'INVALID_TICK_VALUES',\n tickLower,\n tickUpper,\n });\n }\n\n if (tickLower >= tickUpper) {\n throw new GSwapSDKError(\n 'Invalid tick range: tickLower must be less than tickUpper',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TICK_RANGE',\n tickLower,\n tickUpper,\n },\n );\n }\n\n if (tickLower < GC_MIN_TICK || tickUpper > GC_MAX_TICK) {\n throw new GSwapSDKError(\n `Invalid tick range: ticks must be between ${GC_MIN_TICK} and ${GC_MAX_TICK}`,\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TICK_BOUNDS',\n tickLower,\n tickUpper,\n minTick: GC_MIN_TICK,\n maxTick: GC_MAX_TICK,\n },\n );\n }\n}\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(\n 'Invalid fee tier: must be one of 0, 500, 3000, or 10000',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_FEE',\n value: fee,\n },\n );\n }\n}\n\nexport function validateTickSpacing(tickSpacing: number): void {\n if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) {\n throw new GSwapSDKError(\n 'Invalid tick spacing: must be a positive integer',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_TICK_SPACING',\n value: tickSpacing,\n },\n );\n }\n}\n\nexport function validateWalletAddress(address?: string): asserts address is string {\n if (address === undefined) {\n throw new GSwapSDKError(\n 'Invalid wallet address: No wallet address provided',\n 'VALIDATION_ERROR',\n {\n type: 'MISSING_WALLET_ADDRESS',\n hint: 'Either provide a wallet address to the function you are calling, or set one when instantiating GSwapSDK',\n },\n );\n }\n\n if (!address || typeof address !== 'string' || address.trim().length === 0) {\n throw new GSwapSDKError(\n 'Invalid wallet address: must be a non-empty string',\n 'VALIDATION_ERROR',\n {\n type: 'INVALID_WALLET_ADDRESS',\n value: address,\n },\n );\n }\n}\n","import type { UserAsset, UserAssetsResult } from '../types/v2_results.js';\nimport { validateWalletAddress } from '../utils/validation.js';\nimport { getObjectProperty, GSwapSDKError } from './gswap_sdk_error.js';\nimport type { HttpClient } from './http_client.js';\n\n/**\n * Service for handling user asset operations.\n * Provides functionality to retrieve user token balances and asset information.\n */\nexport class Assets {\n constructor(\n private readonly dexBackendBaseUrl: string,\n private readonly httpClient: HttpClient,\n ) {}\n\n /**\n * Gets all token assets owned by a user with their balances.\n * @param ownerAddress - The wallet address to get assets for.\n * @param page - Page number for pagination (default: 1).\n * @param limit - Maximum number of assets to return per page (default: 10).\n * @returns User assets including token information and balances.\n * @example\n * ```typescript\n * const assets = await assetsService.getUserAssets('eth|123...abc', 1, 20);\n * console.log(`User has ${assets.count} different tokens`);\n * assets.tokens.forEach(token => {\n * console.log(`${token.symbol}: ${token.quantity}`);\n * });\n * ```\n */\n async getUserAssets(\n ownerAddress: string,\n page: number = 1,\n limit: number = 10,\n ): Promise<UserAssetsResult> {\n validateWalletAddress(ownerAddress);\n\n if (!Number.isInteger(page) || page < 1) {\n throw new GSwapSDKError('Invalid page: must be a positive integer', 'VALIDATION_ERROR', {\n page,\n });\n }\n\n if (!Number.isInteger(limit) || limit < 1 || limit > 100) {\n throw new GSwapSDKError(\n 'Invalid limit: must be an integer between 1 and 100',\n 'VALIDATION_ERROR',\n { limit },\n );\n }\n\n const json: unknown = await this.httpClient.sendGetRequest(\n this.dexBackendBaseUrl,\n '/user/assets',\n '',\n { address: ownerAddress, page: page.toString(), limit: limit.toString() },\n );\n return parseUserAssets(json);\n }\n}\n\nfunction parseUserAssets(value: unknown): UserAssetsResult {\n const data = getObjectProperty(value, 'data');\n // Not getObjectProperty — that's typed for object properties, and Array.isArray on its\n // Record<string, unknown> return type narrows to any[] instead of a real array type.\n const tokens: unknown = data?.['token'];\n if (!Array.isArray(tokens) || !tokens.every(isRawUserAsset)) {\n throw new GSwapSDKError(\n 'Backend returned an invalid user assets response.',\n 'INVALID_CHAIN_RESPONSE',\n {\n data: value,\n },\n );\n }\n const count = data?.['count'];\n return {\n tokens: tokens.map((token) => ({ ...token, decimals: parseInt(token.decimals, 10) })),\n count: typeof count === 'number' ? count : 0,\n };\n}\n\ntype RawUserAsset = Omit<UserAsset, 'decimals'> & { decimals: string };\n\nfunction isRawUserAsset(value: unknown): value is RawUserAsset {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Record<string, unknown>;\n return (\n typeof entry['image'] === 'string' &&\n typeof entry['name'] === 'string' &&\n typeof entry['decimals'] === 'string' &&\n /^\\d+$/u.test(entry['decimals']) &&\n typeof entry['verify'] === 'boolean' &&\n typeof entry['symbol'] === 'string' &&\n typeof entry['quantity'] === 'string'\n );\n}\n","import type { HTTPResponse, HttpRequestor } from '../types/http_requestor.js';\nimport { GSwapSDKError, parseJson } from '../classes/gswap_sdk_error.js';\n\nexport async function requestWithTimeout(\n requestor: HttpRequestor,\n url: string,\n options: RequestInit,\n timeoutMs: number,\n): Promise<HTTPResponse> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n const externalSignal = options.signal;\n const abortFromCaller = (): void => controller.abort();\n externalSignal?.addEventListener('abort', abortFromCaller, { once: true });\n try {\n return await requestor(url, { ...options, signal: controller.signal });\n } catch (error: unknown) {\n if (controller.signal.aborted) {\n throw new GSwapSDKError(`Request timed out after ${timeoutMs} ms.`, 'REQUEST_TIMEOUT', {\n url,\n timeoutMs,\n cause: error,\n });\n }\n throw error;\n } finally {\n clearTimeout(timer);\n externalSignal?.removeEventListener('abort', abortFromCaller);\n }\n}\n\nexport async function readResponseBody(response: HTTPResponse): Promise<unknown> {\n const text = await response.text();\n return parseJson(text) ?? text;\n}\n\n/** Read a case-insensitive response header from either supported header shape. */\nexport function readHeader(response: HTTPResponse, name: string): string | undefined {\n const headers = response.headers;\n if (headers === undefined) return undefined;\n if (hasHeaderGetter(headers)) {\n const value = headers.get(name);\n return value === null || value === '' ? undefined : value;\n }\n const value = Object.entries(headers).find(\n ([key]) => key.toLowerCase() === name.toLowerCase(),\n )?.[1];\n return value === undefined || value === '' ? undefined : value;\n}\n\n/** Read a non-negative Retry-After header as milliseconds. */\nexport function readRetryAfter(response: HTTPResponse): number | undefined {\n const raw = readHeader(response, 'retry-after');\n if (raw === undefined) return undefined;\n const seconds = Number(raw);\n return Number.isFinite(seconds) && seconds >= 0 ? seconds * 1000 : undefined;\n}\n\n/** Read a non-negative integer block number header. */\nexport function readBlockNumberHeader(\n response: HTTPResponse,\n headerName = 'x-block-number',\n): number | undefined {\n const raw = readHeader(response, headerName);\n if (raw === undefined) return undefined;\n const blockNumber = Number(raw);\n return Number.isInteger(blockNumber) && blockNumber >= 0 ? blockNumber : undefined;\n}\n\nfunction hasHeaderGetter(\n headers: NonNullable<HTTPResponse['headers']>,\n): headers is { get(name: string): string | null } {\n return 'get' in headers && typeof headers.get === 'function';\n}\n","import type { HttpRequestor, HTTPResponse } from '../types/http_requestor.js';\nimport type { AppliedTrade, Position, TradeExecution } from '../types/v2_results.js';\nimport { GSwapSDKError, getObjectProperty, getStringProperty } from './gswap_sdk_error.js';\nimport {\n readBlockNumberHeader,\n readHeader,\n readResponseBody,\n readRetryAfter,\n requestWithTimeout,\n} from '../utils/transport.js';\n\n/** Result of one position-confirmation poll. */\nexport type PositionConfirmationResult =\n { confirmed: true; position: Position | null } | { confirmed: false; position?: Position | null };\n\n/** A submitted v2 transaction whose confirmation mode is explicit in the gateway response. */\nexport class SubmittedTransaction<TConfirmation = AppliedTrade | Position | null> {\n public readonly method: string;\n public readonly uniqueKey: string;\n public readonly transactionId: string | null;\n public readonly blockNumber: number | null;\n public readonly mode: 'sync' | 'queued';\n /** The synchronous gateway result, or `undefined` when `mode === 'queued'`. */\n public readonly result: unknown;\n private readonly backendBaseUrl: string;\n private readonly requestor: HttpRequestor;\n private readonly requestTimeoutMs: number;\n private readonly positionConfirmation:\n ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;\n\n /** Construct a submitted transaction from a successful gateway response.\n *\n * @example\n * ```ts\n * const transaction = new SubmittedTransaction({\n * method: 'RequestTrade', mode: 'queued', uniqueKey: 'swap-1',\n * transactionId: 'request-tx', result: undefined,\n * dexBackendBaseUrl: 'https://dex.example', httpRequestor,\n * });\n * ```\n */\n constructor(options: {\n method: string;\n uniqueKey: string;\n transactionId: string | null;\n mode: 'sync' | 'queued';\n result: unknown;\n dexBackendBaseUrl: string;\n httpRequestor: HttpRequestor;\n blockNumber?: number | null | undefined;\n requestTimeoutMs?: number | undefined;\n positionConfirmation?:\n ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;\n }) {\n this.method = options.method;\n this.uniqueKey = options.uniqueKey;\n this.transactionId = options.transactionId;\n this.blockNumber = options.blockNumber ?? null;\n this.mode = options.mode;\n this.result = options.result;\n this.backendBaseUrl = options.dexBackendBaseUrl.replace(/\\/$/u, '');\n this.requestor = options.httpRequestor;\n this.requestTimeoutMs = options.requestTimeoutMs ?? 30_000;\n this.positionConfirmation = options.positionConfirmation;\n }\n\n /** Confirm a queued RequestTrade or prove the affected position for a liquidity write.\n *\n * For RequestTrade, calling this method is required to learn the outcome: the queued\n * acknowledgement proves acceptance, not execution.\n *\n * @example\n * ```ts\n * const applied = await submitted.confirm({ initialDelayMs: 3_000 });\n * ```\n */\n public async confirm(options?: ConfirmOptions): Promise<TConfirmation> {\n if (this.method === 'RequestTrade') {\n return this.confirmApplied(options) as Promise<TConfirmation>;\n }\n return this.confirmPosition(options) as Promise<TConfirmation>;\n }\n\n private async confirmApplied(options?: ConfirmOptions): Promise<AppliedTrade> {\n // The AutoApplier waits at least 2 s before applying and the apply lands ~6-8 s after the\n // acknowledgement, so a read at t=0 is a guaranteed 404.\n const schedule = createConfirmationSchedule(options, 3_000);\n await schedule.waitForRead();\n const url = `${this.backendBaseUrl}/v1/chain/apply-results/${encodeURIComponent(this.uniqueKey)}?channel=asset&contract=dex-contract`;\n let lastError: unknown;\n\n while (true) {\n let response: HTTPResponse;\n let body: unknown;\n try {\n response = await requestWithTimeout(\n this.requestor,\n url,\n { method: 'GET' },\n this.requestTimeoutMs,\n );\n body = await readResponseBody(response);\n } catch (error: unknown) {\n lastError = error;\n if (!(await schedule.waitForRead())) break;\n continue;\n }\n if (response.status === 200) {\n return this.readAppliedResult(response, body, url);\n }\n if (response.status === 404 || response.status === 429 || isTransient(response.status)) {\n if (response.status === 429) {\n const retryAfter = readRetryAfter(response);\n if (retryAfter !== undefined) {\n if (!(await schedule.waitForRead(retryAfter))) break;\n continue;\n }\n }\n } else {\n throw new GSwapSDKError(bodyMessage(body), 'CONFIRMATION_FAILED', {\n status: response.status,\n body,\n url,\n });\n }\n if (!(await schedule.waitForRead())) break;\n }\n throw GSwapSDKError.confirmationTimeoutError(this.uniqueKey, lastError);\n }\n\n private readAppliedResult(response: HTTPResponse, body: unknown, url: string): AppliedTrade {\n const record = asRecord(body);\n const status = record?.['Status'];\n const applyTransactionId = readHeader(response, 'x-apply-transaction-id') ?? null;\n const blockNumber = readBlockNumberHeader(response, 'x-apply-block-number') ?? null;\n if (status === 0) {\n throw GSwapSDKError.fromChainError(\n getStringProperty(record, 'ErrorKey') ?? 'CHAIN_ERROR',\n getStringProperty(record, 'Message') ?? 'The chain rejected this trade.',\n {\n uniqueKey: this.uniqueKey,\n applyTransactionId,\n blockNumber,\n status: response.status,\n body,\n url,\n },\n );\n }\n if (status !== 1) throw malformedConfirmation(response, body, url);\n const result = parseTradeExecution(record?.['Data']);\n if (result === undefined) throw malformedConfirmation(response, body, url);\n return {\n uniqueKey: this.uniqueKey,\n transactionId: applyTransactionId,\n blockNumber,\n requestTransactionId: this.transactionId,\n result,\n };\n }\n\n /** Confirm a liquidity write against the position's observable effect.\n *\n * @returns The position after the write, or `null` for a confirmed full close.\n * @example\n * ```ts\n * const position = await submitted.confirm({ timeoutMs: 60_000 });\n * ```\n */\n private async confirmPosition(options?: ConfirmOptions): Promise<Position | null> {\n if (this.positionConfirmation === undefined) throw GSwapSDKError.noWalletAddressError();\n // A liquidity write has already executed when the gateway answers, so the first re-read\n // happens immediately unless the caller asks for a delay.\n const schedule = createConfirmationSchedule(options, 0);\n await schedule.waitForRead();\n while (true) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);\n try {\n const result = await this.positionConfirmation(controller.signal);\n if (result.confirmed) return result.position;\n } finally {\n clearTimeout(timer);\n }\n if (!(await schedule.waitForRead())) break;\n }\n throw GSwapSDKError.confirmationTimeoutError(this.uniqueKey);\n }\n}\n\n/**\n * Controls timeout and polling behavior for confirmation.\n *\n * - `timeoutMs` (default 60 000): overall deadline, counted from the `confirm()` call and\n * including `initialDelayMs`. At least one read is always made.\n * - `pollIntervalMs` (default 2 000, minimum 500): base interval, doubled with jitter up to 8 s.\n * - `initialDelayMs`: wait before the first read. Defaults to 3 000 for a queued RequestTrade\n * (the AutoApplier needs a few seconds) and 0 for liquidity writes (already executed).\n */\nexport interface ConfirmOptions {\n timeoutMs?: number | undefined;\n pollIntervalMs?: number | undefined;\n initialDelayMs?: number | undefined;\n}\n\ninterface ConfirmationSchedule {\n waitForRead(retryAfterMs?: number): Promise<boolean>;\n}\n\nfunction createConfirmationSchedule(\n options: ConfirmOptions | undefined,\n defaultInitialDelayMs: number,\n): ConfirmationSchedule {\n const timeoutMs = Math.max(0, options?.timeoutMs ?? 60_000);\n const pollIntervalMs = Math.max(500, options?.pollIntervalMs ?? 2_000);\n const initialDelayMs = Math.max(0, options?.initialDelayMs ?? defaultInitialDelayMs);\n const deadline = Date.now() + timeoutMs;\n let firstRead = true;\n let attempt = 0;\n return {\n async waitForRead(retryAfterMs?: number): Promise<boolean> {\n if (firstRead) {\n firstRead = false;\n const remaining = Math.max(0, deadline - Date.now());\n await delay(Math.min(initialDelayMs, remaining));\n return true;\n }\n const backoff = Math.min(8_000, pollIntervalMs * 2 ** Math.min(attempt, 5));\n attempt += 1;\n const waitMs = retryAfterMs === undefined ? jitter(backoff) : retryAfterMs;\n if (Date.now() + waitMs > deadline) return false;\n await delay(waitMs);\n return true;\n },\n };\n}\n\nfunction parseTradeExecution(value: unknown): TradeExecution | undefined {\n const record = asRecord(value);\n if (\n record === undefined ||\n typeof record['token0'] !== 'string' ||\n typeof record['token1'] !== 'string' ||\n typeof record['fee'] !== 'number'\n ) {\n return undefined;\n }\n const optionalFields = [\n 'sell0Qty',\n 'sell1Qty',\n 'buy0Qty',\n 'buy1Qty',\n 'tradingFees',\n 'protocolFees',\n 'totalFees',\n ] as const;\n for (const field of optionalFields) {\n if (field in record && typeof record[field] !== 'string') return undefined;\n }\n return {\n token0: record['token0'],\n token1: record['token1'],\n fee: record['fee'],\n ...Object.fromEntries(\n optionalFields.flatMap((field) =>\n typeof record[field] === 'string' ? [[field, record[field]]] : [],\n ),\n ),\n };\n}\n\nfunction malformedConfirmation(response: HTTPResponse, body: unknown, url: string): GSwapSDKError {\n return new GSwapSDKError(\n 'Transaction confirmation returned a malformed body',\n 'CONFIRMATION_FAILED',\n { status: response.status, body, url },\n );\n}\n\nfunction isTransient(status: number): boolean {\n return status === 500 || status === 502 || status === 503 || status === 504;\n}\n\nfunction bodyMessage(body: unknown): string {\n return (\n getStringProperty(body, 'message') ??\n getStringProperty(body, 'Message') ??\n getStringProperty(getObjectProperty(body, 'error'), 'message') ??\n getStringProperty(getObjectProperty(body, 'error'), 'Message') ??\n (typeof body === 'string' ? body : 'Transaction confirmation failed')\n );\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction delay(milliseconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nfunction jitter(milliseconds: number): number {\n return Math.max(0, Math.round(milliseconds * (0.9 + Math.random() * 0.2)));\n}\n","import type { HttpRequestor, HTTPResponse } from '../types/http_requestor.js';\nimport { getObjectProperty, getStringProperty, GSwapSDKError } from './gswap_sdk_error.js';\nimport { SubmittedTransaction, type PositionConfirmationResult } from './submitted_transaction.js';\nimport {\n readBlockNumberHeader,\n readHeader,\n readResponseBody,\n readRetryAfter,\n requestWithTimeout,\n} from '../utils/transport.js';\nimport type { AppliedTrade, Position } from '../types/v2_results.js';\n\n/** Options for a chain-gateway client. */\nexport interface ChainGatewayOptions {\n dexBackendBaseUrl: string;\n httpRequestor?: HttpRequestor | undefined;\n walletAddress?: string | undefined;\n chainCallTimeoutMs?: number | undefined;\n}\n\n/** Optional attribution and operation-specific confirmation hooks for a write. */\nexport interface ChainSubmitOptions {\n walletAddress?: string | undefined;\n positionConfirmation?: ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;\n}\n\n/** Thin client for backend-routed v2 writes: synchronous liquidity writes and queued RequestTrade. */\nexport class ChainGateway {\n private readonly requestor: HttpRequestor;\n private readonly walletAddress: string | undefined;\n private readonly chainCallTimeoutMs: number;\n public readonly requestTimeoutMs: number;\n public readonly dexBackendBaseUrl: string;\n\n /** Create a chain gateway client. */\n constructor(options: ChainGatewayOptions) {\n this.dexBackendBaseUrl = trimTrailingSlash(options.dexBackendBaseUrl);\n this.requestor = options.httpRequestor ?? fetch.bind(globalThis);\n this.walletAddress = options.walletAddress;\n this.chainCallTimeoutMs = options.chainCallTimeoutMs ?? 30_000;\n this.requestTimeoutMs = this.chainCallTimeoutMs;\n }\n\n /** Submit a signed v2 DTO through the chain gateway. */\n public async submit(\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ): Promise<SubmittedTransaction<AppliedTrade>>;\n public async submit(\n method: string,\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ): Promise<SubmittedTransaction<Position | null>>;\n public async submit(\n method: string,\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ): Promise<SubmittedTransaction> {\n // The synchronous swap was removed from the contract and from this SDK. This is the only\n // place the retired name may appear in the write path; the class guard in\n // tests/foundation.test.ts pins that nothing signs or submits it.\n if (method === 'Trade') {\n throw new GSwapSDKError(\n 'The synchronous Trade method was removed; swaps are queued through RequestTrade.',\n 'METHOD_NOT_SUPPORTED',\n { method },\n );\n }\n const url = `${this.dexBackendBaseUrl}/v1/chain/asset/dex-contract/${method}`;\n const headers: Record<string, string> = { 'content-type': 'application/json' };\n const walletAddress = options?.walletAddress ?? this.walletAddress;\n if (walletAddress !== undefined) headers['X-Wallet-Address'] = walletAddress;\n let response: HTTPResponse;\n try {\n response = await requestWithTimeout(\n this.requestor,\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(signedBody),\n },\n this.chainCallTimeoutMs,\n );\n } catch (error: unknown) {\n if (error instanceof GSwapSDKError && error.code === 'REQUEST_TIMEOUT') {\n throw new GSwapSDKError(\n 'The submission outcome is unknown because the gateway request timed out. Confirm before retrying.',\n 'SUBMISSION_OUTCOME_UNKNOWN',\n { uniqueKey: getStringProperty(signedBody, 'uniqueKey') ?? '', cause: error },\n );\n }\n throw error;\n }\n const body = await readResponseBody(response);\n\n if (!response.ok) {\n throw gatewayError(response, body, url);\n }\n\n const envelope = asRecord(body);\n const data = asRecord(envelope?.['data'] ?? envelope?.['Data']);\n if (data === undefined) {\n throw invalidGatewayResponse(response, body, url, 'Expected a data object.');\n }\n\n const transactionId = getStringProperty(data, 'transactionId');\n const mode = getStringProperty(data, 'mode');\n const rawTransactionId = data['transactionId'];\n const bodyBlockNumber = data['blockNumber'];\n const invalidModeMessage =\n 'Gateway response must contain data.mode=\"sync\" with data.result, or data.mode=\"queued\".';\n if (mode !== 'sync' && mode !== 'queued') {\n throw invalidGatewayResponse(response, body, url, invalidModeMessage);\n }\n if (\n ('transactionId' in data && typeof rawTransactionId !== 'string') ||\n (bodyBlockNumber !== undefined && bodyBlockNumber !== null && !isBlockNumber(bodyBlockNumber))\n ) {\n throw invalidGatewayResponse(response, body, url, invalidModeMessage);\n }\n if (method === 'RequestTrade' && mode === 'sync') {\n throw invalidGatewayResponse(\n response,\n body,\n url,\n 'The gateway executed RequestTrade synchronously, which this SDK refuses; RequestTrade must be queued.',\n );\n }\n if (method === 'RequestTrade' && mode === 'queued') {\n const signedUniqueKey = getStringProperty(signedBody, 'uniqueKey');\n if (\n 'uniqueKey' in data &&\n (typeof data['uniqueKey'] !== 'string' || data['uniqueKey'] !== signedUniqueKey)\n ) {\n throw invalidGatewayResponse(\n response,\n body,\n url,\n 'Gateway response data.uniqueKey must match the signed RequestTrade uniqueKey.',\n );\n }\n } else if (mode === 'queued' || !('result' in data)) {\n throw invalidGatewayResponse(response, body, url, invalidModeMessage);\n }\n\n // Only synchronous writes carry an executed chain result in the gateway response.\n if (mode === 'sync') {\n const embeddedResult = asRecord(data['result']);\n if (embeddedResult !== undefined) {\n const resultStatus = embeddedResult['Status'];\n if (resultStatus !== undefined && resultStatus !== 1) {\n throw GSwapSDKError.fromChainError(\n getStringProperty(embeddedResult, 'ErrorKey') ?? 'CHAIN_ERROR',\n getStringProperty(embeddedResult, 'Message') ?? 'The chain rejected this write.',\n { status: response.status, body, url },\n );\n }\n }\n }\n\n const uniqueKey = getStringProperty(signedBody, 'uniqueKey') ?? '';\n const headerTransactionId = readHeader(response, 'x-transaction-id');\n const resolvedTransactionId =\n transactionId === undefined || transactionId === '' ? headerTransactionId : transactionId;\n const blockNumber: number | undefined =\n bodyBlockNumber === null || bodyBlockNumber === undefined\n ? readBlockNumberHeader(response)\n : isBlockNumber(bodyBlockNumber)\n ? bodyBlockNumber\n : undefined;\n return new SubmittedTransaction({\n method,\n uniqueKey,\n transactionId:\n resolvedTransactionId === undefined || resolvedTransactionId === ''\n ? null\n : resolvedTransactionId,\n blockNumber: blockNumber ?? null,\n mode,\n result: mode === 'queued' ? undefined : data['result'],\n dexBackendBaseUrl: this.dexBackendBaseUrl,\n httpRequestor: this.requestor,\n requestTimeoutMs: this.chainCallTimeoutMs,\n ...(options?.positionConfirmation === undefined\n ? {}\n : { positionConfirmation: options.positionConfirmation }),\n });\n }\n\n /** Expose the requestor for sibling read services that share this gateway transport. */\n public get httpRequestor(): HttpRequestor {\n return this.requestor;\n }\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/u, '');\n}\n\nfunction invalidGatewayResponse(\n response: HTTPResponse,\n body: unknown,\n url: string,\n message: string,\n): GSwapSDKError {\n return new GSwapSDKError(message, 'INVALID_GATEWAY_RESPONSE', {\n status: response.status,\n body,\n url,\n });\n}\n\nfunction gatewayError(response: HTTPResponse, body: unknown, url: string): GSwapSDKError {\n const object = asRecord(body);\n const nested = getObjectProperty(body, 'error');\n const code =\n getStringProperty(object, 'code') ??\n getStringProperty(nested, 'code') ??\n getStringProperty(nested, 'ErrorKey') ??\n 'HTTP_ERROR';\n const message =\n getStringProperty(object, 'message') ??\n getStringProperty(nested, 'message') ??\n getStringProperty(nested, 'Message') ??\n (typeof body === 'string' ? body : `Gateway request failed with HTTP ${response.status}`);\n const retryAfterMs = response.status === 429 ? readRetryAfter(response) : undefined;\n if (code === 'HTTP_ERROR') {\n return new GSwapSDKError(message, code, { status: response.status, body, url });\n }\n return GSwapSDKError.fromGatewayBounce(code, message, response.status, retryAfterMs);\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction isBlockNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 0;\n}\n","/** SDK deployment environment. */\nexport type GSwapEnv = 'prod' | 'stage';\n\n/** Backend URLs used by one SDK deployment environment. */\nexport interface GSwapEnvironmentConfig {\n dexBackendBaseUrl: string;\n /** The realtime stream endpoint (raw WebSocket, JSON-RPC 2.0). */\n dexBackendWsUrl: string;\n}\n\n/** Built-in GalaSwap deployment environments. */\nexport const GSWAP_ENVIRONMENTS: Readonly<Record<GSwapEnv, GSwapEnvironmentConfig>> = {\n prod: {\n dexBackendBaseUrl: 'https://dex-backend-prod1.defi.gala.com',\n dexBackendWsUrl: 'wss://dex-backend-prod1.defi.gala.com/ws',\n },\n stage: {\n dexBackendBaseUrl: 'https://swap-backend.stage.defi.ovh.gala.com',\n dexBackendWsUrl: 'wss://swap-backend.stage.defi.ovh.gala.com/ws',\n },\n};\n","import debug from 'debug';\n\nexport const debugLog = debug('GSWAP_SDK');\n","/** Options for {@link ReconnectionBackoff}. */\nexport interface ReconnectionBackoffOptions {\n /** Attempts allowed before giving up. */\n maxAttempts: number;\n /** Delay before the first attempt, in milliseconds. */\n baseDelayMs: number;\n /** Ceiling the doubling delay never exceeds, in milliseconds. */\n maxDelayMs?: number;\n}\n\n/** Counts reconnect attempts and doubles the delay between them, up to a ceiling. */\nexport class ReconnectionBackoff {\n private attempts = 0;\n private delayMs: number;\n private readonly maxDelayMs: number;\n\n constructor(private readonly options: ReconnectionBackoffOptions) {\n this.delayMs = options.baseDelayMs;\n this.maxDelayMs = options.maxDelayMs ?? 30_000;\n }\n\n /** Whether another attempt is allowed. */\n shouldRetry(): boolean {\n return this.attempts < this.options.maxAttempts;\n }\n\n /** The delay to wait before the next attempt. */\n nextDelayMs(): number {\n return this.delayMs;\n }\n\n /** Record that an attempt is being made, and double the next delay. */\n recordAttempt(): void {\n this.attempts += 1;\n this.delayMs = Math.min(this.delayMs * 2, this.maxDelayMs);\n }\n\n /** Forget every attempt: the connection is healthy again. */\n reset(): void {\n this.attempts = 0;\n this.delayMs = this.options.baseDelayMs;\n }\n\n get attemptCount(): number {\n return this.attempts;\n }\n\n get maxAttempts(): number {\n return this.options.maxAttempts;\n }\n}\n","import { GSWAP_ENVIRONMENTS } from '../types/env.js';\nimport { debugLog } from '../utils/debug.js';\nimport { ReconnectionBackoff } from '../utils/reconnection.js';\n\nconst GDEX_SUBPROTOCOL = 'gdex.jsonrpc.v1';\nconst RATE_LIMITED = -32003;\nconst MAX_RESUBSCRIBE_RATE_RETRIES = 5;\nconst WEBSOCKET_OPEN = 1;\n\n/** Options for {@link GdexStreamService}. */\nexport interface GdexStreamConfig {\n /** Stream endpoint. Defaults to production (`wss://dex-backend-prod1.defi.gala.com/ws`). */\n url?: string | undefined;\n /** Reconnect attempts after an unexpected close. Default 5. */\n reconnectAttempts?: number | undefined;\n /** Delay before the first reconnect attempt; doubles each attempt. Default 2000 ms. */\n reconnectDelayMs?: number | undefined;\n /** How long a request waits for its response. Default 15000 ms. */\n requestTimeoutMs?: number | undefined;\n /**\n * A standards-compatible WebSocket constructor. Required on Node.js older than 22, which has no\n * global `WebSocket` (pass the one from the `ws` package).\n */\n webSocketImpl?: unknown;\n}\n\n/** The channels of the realtime stream. */\nexport type GdexChannel = 'pool' | 'balance' | 'poolCreated' | 'swap' | 'liquidity' | 'blocks';\n\n/** A pool named by its two token class keys (pipe form) and fee tier. */\nexport interface GdexPoolKey {\n token0ClassKey: string;\n token1ClassKey: string;\n fee: number;\n}\n\n/** A pool named either by its key or by its hash (`v2:<poolRef>` for a v2 pool). */\nexport type GdexPoolSelector = { pool: GdexPoolKey } | { poolHash: string };\n\n/** Options common to every subscription. */\nexport interface GdexSubscribeOptions {\n /** Send the current state right after the subscribe response. */\n snapshot?: boolean | undefined;\n /** Trim each event to these fields; identity and envelope fields always stay. */\n fields?: string[] | undefined;\n}\n\n/** Filters for {@link GdexStreamService.subscribeLiquidity}; all optional. */\nexport interface GdexLiquidityFilter {\n /** Only this pool, named by its key. */\n pool?: GdexPoolKey | undefined;\n /** Only this pool, named by its hash (`v2:<poolRef>` for a v2 pool). */\n poolHash?: string | undefined;\n /** Only events for this LP wallet (the position's owner). */\n owner?: string | undefined;\n /** Only this transaction. */\n transactionId?: string | undefined;\n /** Contract version filter. */\n version?: 'v1' | 'v2' | 'all' | undefined;\n}\n\n/** One committed add, remove or collect, as the `liquidity` channel reports it. */\nexport interface GdexLiquidityEvent {\n version: 'v1' | 'v2';\n pool: GdexPoolKey;\n poolHash: string;\n transactionId: string;\n /** `add`, `remove` or `collect`. */\n action: 'add' | 'remove' | 'collect';\n /** The position's owner (the LP wallet). */\n owner: string;\n /** v1: the position id. v2: the chain position key `<pool>|<tickLow>|<tickHigh>|<owner>`. */\n positionId?: string;\n tickLower?: number;\n tickUpper?: number;\n /** v2 only: the position's liquidity after the operation; `\"0\"` means it is closed. */\n liquidityAfter?: string;\n /** Principal moved: deposited by an add, withdrawn by a remove, `\"0\"` for a collect. */\n amount0: string;\n amount1: string;\n /** Fees paid out. v2: always present (`\"0\"` for an add). v1: present on a collect only. */\n fees0?: string;\n fees1?: string;\n /** v2 only. */\n token0Symbol?: string;\n token1Symbol?: string;\n blockNumber: number;\n timestamp: string;\n}\n\nconst LIQUIDITY_ACTIONS: readonly unknown[] = ['add', 'remove', 'collect'];\n\n/** Whether a stream payload carries every field of a {@link GdexLiquidityEvent}. */\nexport function isGdexLiquidityEvent(\n value: Record<string, unknown>,\n): value is Record<string, unknown> & GdexLiquidityEvent {\n const { pool } = value;\n return (\n (value['version'] === 'v1' || value['version'] === 'v2') &&\n typeof pool === 'object' &&\n pool !== null &&\n typeof value['poolHash'] === 'string' &&\n typeof value['transactionId'] === 'string' &&\n LIQUIDITY_ACTIONS.includes(value['action']) &&\n typeof value['owner'] === 'string' &&\n typeof value['amount0'] === 'string' &&\n typeof value['amount1'] === 'string' &&\n typeof value['blockNumber'] === 'number' &&\n typeof value['timestamp'] === 'string'\n );\n}\n\n/** A live subscription. */\nexport interface GdexSubscription {\n subscriptionId: string;\n unsubscribe(): Promise<void>;\n}\n\n/** A JSON-RPC error answered by the stream. */\nexport class GdexStreamError extends Error {\n readonly code: number;\n readonly data?: unknown;\n\n constructor(code: number, message: string, data?: unknown) {\n super(message);\n this.name = 'GdexStreamError';\n this.code = code;\n if (data !== undefined) this.data = data;\n }\n}\n\ninterface WebSocketLike {\n readonly readyState: number;\n send(data: string): void;\n close(code?: number, reason?: string): void;\n onopen: ((event: unknown) => void) | null;\n onmessage: ((event: { data: unknown }) => void) | null;\n onclose: ((event: { code?: number; reason?: string }) => void) | null;\n onerror: ((event: unknown) => void) | null;\n}\n\ninterface WebSocketConstructor {\n new (url: string, protocols?: string | string[]): WebSocketLike;\n}\n\ninterface PendingRequest {\n resolve(value: unknown): void;\n reject(error: Error): void;\n timeout: ReturnType<typeof setTimeout>;\n}\n\ntype EventCallback = (event: Record<string, unknown>) => void;\n\ninterface ActiveSubscription {\n serverId: string;\n readonly params: Record<string, unknown>;\n readonly callback: EventCallback;\n readonly handle: MutableGdexSubscription;\n active: boolean;\n}\n\ninterface MutableGdexSubscription extends GdexSubscription {\n subscriptionId: string;\n}\n\ninterface JsonRpcResponse {\n id?: unknown;\n method?: unknown;\n result?: unknown;\n error?: { code?: unknown; message?: unknown; data?: unknown };\n params?: unknown;\n}\n\n/**\n * Client for the gSwap realtime stream (gdex WebSocket Protocol v1): JSON-RPC 2.0 over one raw\n * WebSocket, with automatic reconnect and resubscribe.\n *\n * @example\n * ```typescript\n * const stream = new GdexStreamService();\n * await stream.connect();\n * await stream.subscribeLiquidity(event => console.log(event.action, event.owner), {\n * owner: 'client|618ae395c1c653111d3315be',\n * });\n * ```\n */\nexport class GdexStreamService {\n private readonly url: string;\n private readonly requestTimeoutMs: number;\n private readonly webSocketConstructor: WebSocketConstructor;\n private readonly backoff: ReconnectionBackoff;\n private socket: WebSocketLike | undefined;\n private connectPromise: Promise<void> | undefined;\n private nextRequestId = 0;\n private readonly pending = new Map<number, PendingRequest>();\n private readonly subscriptionsByServerId = new Map<string, ActiveSubscription>();\n private readonly activeSubscriptions = new Set<ActiveSubscription>();\n private intentionalClose = false;\n private reconnecting = false;\n private reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n private reconnectDelayResolve: (() => void) | undefined;\n\n constructor(config: GdexStreamConfig = {}) {\n this.url = config.url ?? GSWAP_ENVIRONMENTS.prod.dexBackendWsUrl;\n this.requestTimeoutMs = config.requestTimeoutMs ?? 15_000;\n this.backoff = new ReconnectionBackoff({\n maxAttempts: config.reconnectAttempts ?? 5,\n baseDelayMs: config.reconnectDelayMs ?? 2_000,\n });\n\n const implementation =\n config.webSocketImpl ?? (globalThis as { WebSocket?: unknown }).WebSocket;\n if (typeof implementation !== 'function') {\n throw new Error(\n 'GdexStreamService requires a standards-compatible WebSocket constructor. ' +\n 'Node.js versions before 22 must provide one with config.webSocketImpl (for example, from the \"ws\" package).',\n );\n }\n this.webSocketConstructor = implementation as WebSocketConstructor;\n }\n\n /** Open the connection. Resolves at once when already connected. */\n connect(): Promise<void> {\n if (this.isConnected()) return Promise.resolve();\n if (this.connectPromise) return this.connectPromise;\n this.intentionalClose = false;\n this.clearReconnectTimer();\n this.connectPromise = this.openSocket();\n return this.connectPromise;\n }\n\n /** Close the connection and stop reconnecting. */\n disconnect(): void {\n this.intentionalClose = true;\n this.reconnecting = false;\n this.clearReconnectTimer();\n this.rejectPending(new Error('GDEX stream disconnected'));\n const socket = this.socket;\n this.socket = undefined;\n this.connectPromise = undefined;\n socket?.close(1000, 'client disconnect');\n }\n\n isConnected(): boolean {\n return this.socket?.readyState === WEBSOCKET_OPEN;\n }\n\n /** Raw JSON-RPC escape hatch. */\n request<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T> {\n if (!this.isConnected() || !this.socket) {\n return Promise.reject(new Error('GDEX stream is not connected. Call connect() first.'));\n }\n\n const id = ++this.nextRequestId;\n const frame: Record<string, unknown> = { jsonrpc: '2.0', id, method };\n if (params !== undefined) frame['params'] = params;\n\n return new Promise<T>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`GDEX request \"${method}\" timed out after ${this.requestTimeoutMs}ms`));\n }, this.requestTimeoutMs);\n this.pending.set(id, { resolve: (value) => resolve(value as T), reject, timeout });\n\n try {\n this.socket?.send(JSON.stringify(frame));\n } catch (error) {\n clearTimeout(timeout);\n this.pending.delete(id);\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n }\n\n serverInfo(): Promise<Record<string, unknown>> {\n return this.request('gdex_serverInfo');\n }\n\n ping(): Promise<{ pong: boolean; serverTime: string }> {\n return this.request('gdex_ping');\n }\n\n getPool(selector: GdexPoolSelector): Promise<Record<string, unknown>> {\n return this.request('gdex_getPool', selector);\n }\n\n getBalance(owner: string, tokenClassKey?: string): Promise<Record<string, unknown>> {\n return this.request(\n 'gdex_getBalance',\n tokenClassKey === undefined ? { owner } : { owner, tokenClassKey },\n );\n }\n\n getPositions(opts: {\n owner: string;\n pool?: GdexPoolKey;\n poolHash?: string;\n limit?: number;\n bookmark?: string;\n }): Promise<{ positions: Record<string, unknown>[]; bookmark: string }> {\n return this.request('gdex_getPositions', opts);\n }\n\n getBlockHeight(): Promise<{ blockNumber: number; timestamp: string }> {\n return this.request('gdex_getBlockHeight');\n }\n\n quote(params: {\n tokenIn: string;\n tokenOut: string;\n fee?: number;\n amountIn?: string;\n amountOut?: string;\n }): Promise<Record<string, unknown>> {\n return this.request('gdex_quote', params);\n }\n\n getToken(tokenClassKey: string): Promise<Record<string, unknown>> {\n return this.request('gdex_getToken', { tokenClassKey });\n }\n\n /** One event per committed swap. Omit the pool to receive every pool's swaps. */\n subscribeSwaps(\n cb: (event: Record<string, unknown>) => void,\n opts: GdexSubscribeOptions & {\n pool?: GdexPoolKey;\n poolHash?: string;\n transactionId?: string;\n } = {},\n ): Promise<GdexSubscription> {\n return this.subscribe('swap', cb, opts);\n }\n\n /** State changes of one pool. */\n subscribePool(\n selector: GdexPoolSelector,\n cb: (event: Record<string, unknown>) => void,\n opts: GdexSubscribeOptions = {},\n ): Promise<GdexSubscription> {\n return this.subscribe('pool', cb, { ...selector, ...opts });\n }\n\n /** Balance changes of one wallet. */\n subscribeBalances(\n owner: string,\n cb: (event: Record<string, unknown>) => void,\n opts: GdexSubscribeOptions & { tokenClassKey?: string } = {},\n ): Promise<GdexSubscription> {\n return this.subscribe('balance', cb, { owner, ...opts });\n }\n\n /** Each newly created pool. */\n subscribePoolCreated(\n cb: (event: Record<string, unknown>) => void,\n opts: GdexSubscribeOptions & { tokenClassKey?: string } = {},\n ): Promise<GdexSubscription> {\n return this.subscribe('poolCreated', cb, opts);\n }\n\n /**\n * One event per committed AddLiquidity, RemoveLiquidity and CollectPositionFees, on both contract\n * versions. Every filter is optional; with none, every liquidity event arrives. These events never\n * appear on {@link subscribeSwaps}. There is no snapshot: read positions with {@link getPositions}.\n * Deduplicate by `transactionId` plus `positionId`: a v1 BatchSubmit can hold several operations\n * under one transaction id.\n */\n subscribeLiquidity(\n cb: (event: GdexLiquidityEvent) => void,\n opts: GdexSubscribeOptions & GdexLiquidityFilter = {},\n ): Promise<GdexSubscription> {\n return this.subscribe(\n 'liquidity',\n (event) => {\n if (isGdexLiquidityEvent(event)) cb(event);\n else debugLog('Ignoring a malformed liquidity event from the GDEX stream');\n },\n opts,\n );\n }\n\n /** Each block-height advance. */\n subscribeBlocks(\n cb: (event: Record<string, unknown>) => void,\n opts: GdexSubscribeOptions = {},\n ): Promise<GdexSubscription> {\n return this.subscribe('blocks', cb, opts);\n }\n\n private openSocket(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n let opened = false;\n const socket = new this.webSocketConstructor(this.url, GDEX_SUBPROTOCOL);\n this.socket = socket;\n\n socket.onopen = () => {\n if (this.socket !== socket) return;\n opened = true;\n this.connectPromise = undefined;\n if (!this.reconnecting) this.backoff.reset();\n debugLog('Connected to GDEX stream');\n resolve();\n };\n socket.onmessage = (event) => this.handleMessage(event.data);\n socket.onerror = () => {\n if (!opened) reject(new Error(`Failed to connect to GDEX stream at ${this.url}`));\n };\n socket.onclose = (event) => {\n if (this.socket !== socket) return;\n this.socket = undefined;\n this.connectPromise = undefined;\n if (!opened)\n reject(new Error(`GDEX stream closed before connecting (code ${event.code ?? 0})`));\n this.rejectPending(new Error(`GDEX stream connection closed (code ${event.code ?? 0})`));\n if (!this.intentionalClose && !this.reconnecting) this.startReconnectLoop();\n };\n });\n }\n\n private handleMessage(data: unknown): void {\n if (typeof data !== 'string') {\n debugLog('Ignoring non-text GDEX WebSocket frame');\n return;\n }\n\n let message: JsonRpcResponse;\n try {\n message = JSON.parse(data) as JsonRpcResponse;\n } catch {\n debugLog('Ignoring invalid JSON from GDEX stream');\n return;\n }\n\n if (typeof message.id === 'number') {\n const pending = this.pending.get(message.id);\n if (!pending) return;\n clearTimeout(pending.timeout);\n this.pending.delete(message.id);\n if (message.error) {\n const code = typeof message.error.code === 'number' ? message.error.code : -32603;\n const errorMessage =\n typeof message.error.message === 'string' ? message.error.message : 'GDEX request failed';\n pending.reject(new GdexStreamError(code, errorMessage, message.error.data));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n if (message.method !== 'gdex_subscription' || !this.isRecord(message.params)) return;\n const subscriptionId = message.params['subscription'];\n const result = message.params['result'];\n if (typeof subscriptionId !== 'string' || !this.isRecord(result)) return;\n const subscription = this.subscriptionsByServerId.get(subscriptionId);\n if (!subscription?.active) return;\n try {\n subscription.callback(result);\n } catch (error) {\n debugLog('GDEX subscription callback failed', error);\n }\n }\n\n private async subscribe(\n channel: GdexChannel,\n callback: EventCallback,\n options: object,\n ): Promise<GdexSubscription> {\n const params: Record<string, unknown> = { channel, ...options };\n const result = await this.request<{ subscriptionId: string }>('gdex_subscribe', params);\n // Assigned after the handle because unsubscribe closes over the completed subscription record.\n // eslint-disable-next-line prefer-const\n let active: ActiveSubscription;\n const handle: MutableGdexSubscription = {\n subscriptionId: result.subscriptionId,\n unsubscribe: async () => this.unsubscribe(active),\n };\n active = { serverId: result.subscriptionId, params, callback, handle, active: true };\n this.activeSubscriptions.add(active);\n this.subscriptionsByServerId.set(active.serverId, active);\n return handle;\n }\n\n private async unsubscribe(subscription: ActiveSubscription): Promise<void> {\n if (!subscription.active) return;\n subscription.active = false;\n this.activeSubscriptions.delete(subscription);\n this.subscriptionsByServerId.delete(subscription.serverId);\n if (this.isConnected()) {\n await this.request('gdex_unsubscribe', { subscriptionId: subscription.serverId });\n }\n }\n\n private startReconnectLoop(): void {\n if (this.reconnecting || this.intentionalClose) return;\n this.reconnecting = true;\n void this.reconnectLoop();\n }\n\n private async reconnectLoop(): Promise<void> {\n while (!this.intentionalClose && this.backoff.shouldRetry()) {\n const delay = this.backoff.nextDelayMs();\n this.backoff.recordAttempt();\n debugLog(\n `GDEX reconnect attempt ${this.backoff.attemptCount}/${this.backoff.maxAttempts} in ${delay}ms`,\n );\n await this.waitForReconnectDelay(delay);\n // `disconnect()` can run while the asynchronous delay is pending.\n if (this.intentionalClose) break;\n\n try {\n await this.openSocket();\n await this.resubscribeAll();\n this.backoff.reset();\n this.reconnecting = false;\n return;\n } catch (error) {\n debugLog(\n `GDEX reconnect failed: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n this.reconnecting = false;\n if (!this.intentionalClose) debugLog('GDEX reconnection attempts exhausted');\n }\n\n private async resubscribeAll(): Promise<void> {\n this.subscriptionsByServerId.clear();\n for (const subscription of this.activeSubscriptions) {\n if (!subscription.active) continue;\n const params = { ...subscription.params, snapshot: true };\n const result = await this.resubscribeWithRateLimitRetry(params);\n // The consumer can unsubscribe while the asynchronous subscribe request is pending.\n if (!subscription.active) {\n await this.request('gdex_unsubscribe', { subscriptionId: result.subscriptionId });\n continue;\n }\n subscription.serverId = result.subscriptionId;\n subscription.handle.subscriptionId = result.subscriptionId;\n this.subscriptionsByServerId.set(result.subscriptionId, subscription);\n }\n }\n\n private async resubscribeWithRateLimitRetry(\n params: Record<string, unknown>,\n ): Promise<{ subscriptionId: string }> {\n for (let attempt = 0; ; attempt++) {\n try {\n return await this.request('gdex_subscribe', params);\n } catch (error) {\n if (\n !(error instanceof GdexStreamError) ||\n error.code !== RATE_LIMITED ||\n attempt >= MAX_RESUBSCRIBE_RATE_RETRIES\n ) {\n throw error;\n }\n const retryAfterMs = this.readRetryAfterMs(error.data);\n debugLog(`GDEX resubscribe rate limited; retrying in ${retryAfterMs}ms`);\n await new Promise<void>((resolve) => setTimeout(resolve, retryAfterMs));\n }\n }\n }\n\n private waitForReconnectDelay(delay: number): Promise<void> {\n return new Promise((resolve) => {\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n this.reconnectDelayResolve = undefined;\n resolve();\n }, delay);\n this.reconnectDelayResolve = resolve;\n });\n }\n\n private clearReconnectTimer(): void {\n if (this.reconnectTimer !== undefined) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n const resolve = this.reconnectDelayResolve;\n this.reconnectDelayResolve = undefined;\n resolve?.();\n }\n\n private rejectPending(error: Error): void {\n for (const pending of this.pending.values()) {\n clearTimeout(pending.timeout);\n pending.reject(error);\n }\n this.pending.clear();\n }\n\n private readRetryAfterMs(data: unknown): number {\n if (\n !this.isRecord(data) ||\n typeof data['retryAfterMs'] !== 'number' ||\n data['retryAfterMs'] < 0\n )\n return 1_000;\n return data['retryAfterMs'];\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n}\n","declare const __GSWAP_SDK_VERSION__: string | undefined;\n\n/** Package version embedded by the bundler, with a source-test fallback. */\nexport const SDK_VERSION =\n typeof __GSWAP_SDK_VERSION__ === 'string' ? __GSWAP_SDK_VERSION__ : '1.1.0';\n","import type { HttpRequestor } from '../types/http_requestor.js';\nimport { debugLog } from '../utils/debug.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport { readResponseBody, requestWithTimeout } from '../utils/transport.js';\nimport { SDK_VERSION } from '../version.js';\n\nexport class HttpClient {\n /** Create an HTTP client around fetch or an injected requestor. */\n constructor(\n private readonly httpRequestor: HttpRequestor = fetch,\n private readonly timeoutMs = 30_000,\n ) {}\n\n private async sendRequest<TReturnType>(\n method: 'POST' | 'GET',\n baseUrl: string,\n basePath: string,\n endpoint: string,\n body?: unknown,\n options?: Pick<RequestInit, 'signal'>,\n ): Promise<TReturnType> {\n const url = `${baseUrl}${basePath}${endpoint}`;\n debugLog(`Sending request to ${url} with body:`, body);\n\n const response = await requestWithTimeout(\n this.httpRequestor,\n url,\n {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': `GalaChain-SDK/${SDK_VERSION}`,\n },\n ...(body ? { body: JSON.stringify(body) } : {}),\n ...(options?.signal === undefined ? {} : { signal: options.signal }),\n },\n this.timeoutMs,\n );\n\n if (!response.ok) {\n throw await GSwapSDKError.fromErrorResponse(url, response);\n }\n\n const json = await readResponseBody(response);\n debugLog(`Response from ${baseUrl}${basePath}${endpoint}:`, json);\n\n return json as TReturnType;\n }\n\n /** Send a JSON POST request and decode its response. */\n async sendPostRequest<TReturnType>(\n baseUrl: string,\n basePath: string,\n endpoint: string,\n body: unknown,\n ): Promise<TReturnType> {\n return this.sendRequest('POST', baseUrl, basePath, endpoint, body);\n }\n\n /** Send a GET request with URL-encoded query parameters and decode its response. */\n async sendGetRequest<TReturnType>(\n baseUrl: string,\n basePath: string,\n endpoint: string,\n params?: Record<string, string>,\n options?: Pick<RequestInit, 'signal'>,\n ): Promise<TReturnType> {\n const searchParams = params ? new URLSearchParams(params) : undefined;\n const endpointWithParams = searchParams ? `${endpoint}?${searchParams.toString()}` : endpoint;\n\n return this.sendRequest('GET', baseUrl, basePath, endpointWithParams, undefined, options);\n }\n}\n","import { GSwapSDKError } from '../classes/gswap_sdk_error.js';\nimport type { GalaChainTokenClassKey } from '../types/token.js';\n\n/** A symbol or a GalaChain token class key accepted by v2 operations. */\nexport type TokenRef = string | GalaChainTokenClassKey;\n\n/** Return two trading symbols in the contract's plain-string order. */\nexport function orderSymbols(a: string, b: string): [string, string] {\n return a < b ? [a, b] : [b, a];\n}\n\n/** Read an ordered symbol pair from a tuple or object returned by a boundary helper.\n *\n * @example\n * ```ts\n * const pair = readOrderedSymbols(['GALA', 'GUSDC']);\n * console.log(pair.token0);\n * ```\n */\nexport function readOrderedSymbols(value: unknown): { token0: string; token1: string } {\n if (Array.isArray(value) && value.length >= 2) {\n const token0 = (value as unknown[])[0];\n const token1 = (value as unknown[])[1];\n if (typeof token0 === 'string' && typeof token1 === 'string') return { token0, token1 };\n }\n if (typeof value === 'object' && value !== null) {\n const record = value as Record<string, unknown>;\n const token0 = record['token0'];\n const token1 = record['token1'];\n if (typeof token0 === 'string' && typeof token1 === 'string') return { token0, token1 };\n }\n throw new GSwapSDKError('Unable to order trading symbols.', 'VALIDATION_ERROR', { value });\n}\n\n/** Return the `$`-joined composite key used by GalaChain object identities. */\nexport function compositeKeyOf(token: GalaChainTokenClassKey): string {\n return [token.collection, token.category, token.type, token.additionalKey].join('$');\n}\n\n/**\n * Parse a pipe- or dollar-separated token class key.\n *\n * The LAST three segments are always `category`, `type` and `additionalKey`; everything before\n * them is the `collection`. Parsing from the right is required because real collections contain\n * the `$` delimiter themselves (for example `$GMUSIC`), so a plain left-to-right `split('$')`\n * shifts every field. Nothing here says anything about the token's symbol: a class key carries\n * no symbol, which must come from the token class or trading-symbol registry.\n *\n * @example\n * ```ts\n * parseTokenClassKey('$GMUSIC$Unit$none$none').collection; // '$GMUSIC'\n * ```\n */\nexport function parseTokenClassKey(tokenClassKey: TokenRef): GalaChainTokenClassKey {\n if (typeof tokenClassKey === 'object') {\n return {\n collection: tokenClassKey.collection,\n category: tokenClassKey.category,\n type: tokenClassKey.type,\n additionalKey: tokenClassKey.additionalKey,\n };\n }\n\n const delimiter = tokenClassKey.includes('|') ? '|' : '$';\n const segments = tokenClassKey.split(delimiter);\n const tail = segments.slice(-3);\n const collection = segments.slice(0, -3).join(delimiter);\n if (segments.length < 4 || collection.length === 0 || tail.some((part) => part.length === 0)) {\n throw new GSwapSDKError(\n 'Invalid token class key: expected a collection followed by category, type and additionalKey',\n 'VALIDATION_ERROR',\n {\n tokenClassKey,\n },\n );\n }\n\n const [category, type, additionalKey] = tail;\n return {\n collection,\n category: category as string,\n type: type as string,\n additionalKey: additionalKey as string,\n };\n}\n","import type { FEE_TIER } from '../types/fees.js';\nimport type { CompositePool, PoolInfo, PoolListInfo, Slot0 } from '../types/v2_results.js';\nimport { orderSymbols, readOrderedSymbols, type TokenRef } from '../utils/ordering.js';\nimport type { ChainGateway } from './gateway.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport { HttpClient } from './http_client.js';\nimport type { Symbols } from './symbols.js';\nimport { validateFee } from '../utils/validation.js';\n\ninterface BackendEnvelope<T> {\n data: T;\n}\n\ntype PoolGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {\n requestTimeoutMs?: number | undefined;\n};\ntype PoolSymbols = Pick<Symbols, 'resolve'>;\n\n/** Read-only pool and current-price access for the current GalaChainDex contract. */\nexport class Pools {\n /**\n * Creates a pool service.\n *\n * @example\n * ```ts\n * const pools = new Pools(gateway, symbols);\n * ```\n */\n constructor(\n private readonly gateway: PoolGateway,\n private readonly symbols: PoolSymbols,\n ) {\n this.http = new HttpClient(gateway.httpRequestor, gateway.requestTimeoutMs ?? 30_000);\n }\n\n private readonly http: HttpClient;\n\n /**\n * Fetches every current-contract pool from the swap backend.\n *\n * @example\n * ```ts\n * const pools = await service.getPools();\n * console.log(pools.length);\n * ```\n */\n public async getPools(options?: { signal?: AbortSignal | undefined }): Promise<PoolListInfo[]> {\n const response = await this.http.sendGetRequest<BackendEnvelope<unknown>>(\n this.gateway.dexBackendBaseUrl,\n '/v2/trade',\n '/pools',\n undefined,\n options?.signal === undefined ? undefined : { signal: options.signal },\n );\n if (!Array.isArray(response.data) || !response.data.every(isPoolListInfo)) {\n throw new GSwapSDKError('Backend returned an invalid pool list.', 'INVALID_CHAIN_RESPONSE', {\n data: response.data,\n });\n }\n return response.data;\n }\n\n /**\n * Fetches one pool from the backend, preserving whether the request order was flipped.\n *\n * @example\n * ```ts\n * const pool = await service.getPool('GUSDC', 'GALA', 3000);\n * console.log(pool.flippedFromRequest);\n * ```\n */\n public async getPool(token0: TokenRef, token1: TokenRef, fee: FEE_TIER): Promise<PoolInfo> {\n validateFee(fee);\n return this.getBackend<PoolInfo>('/pool', await this.backendParams(token0, token1, fee));\n }\n\n /**\n * Fetches the current sqrt price, price, and tick for one pool.\n *\n * @example\n * ```ts\n * const slot0 = await service.getSlot0('GALA', 'GUSDC', 3000);\n * console.log(slot0.tick);\n * ```\n */\n public async getSlot0(token0: TokenRef, token1: TokenRef, fee: FEE_TIER): Promise<Slot0> {\n validateFee(fee);\n return this.getBackend<Slot0>('/slot0', await this.backendParams(token0, token1, fee));\n }\n\n /**\n * Fetches the complete chain composite pool snapshot, in canonical symbol order.\n *\n * @example\n * ```ts\n * const composite = await service.getCompositePool('GALA', 'GUSDC', 3000);\n * console.log(composite.positions?.length ?? 0);\n * ```\n */\n public async getCompositePool(\n token0: TokenRef,\n token1: TokenRef,\n fee: FEE_TIER,\n ): Promise<CompositePool> {\n validateFee(fee);\n const first = await resolveSymbol(this.symbols, token0);\n const second = await resolveSymbol(this.symbols, token1);\n const ordered = readOrderedSymbols(orderSymbols(first, second));\n return this.getBackend<CompositePool>('/composite-pool', {\n token0: ordered.token0,\n token1: ordered.token1,\n fee: String(fee),\n });\n }\n\n private async backendParams(\n token0: TokenRef,\n token1: TokenRef,\n fee: FEE_TIER,\n ): Promise<Record<string, string>> {\n return {\n token0: await resolveSymbol(this.symbols, token0),\n token1: await resolveSymbol(this.symbols, token1),\n fee: String(fee),\n };\n }\n\n private async getBackend<T>(endpoint: string, params: Record<string, string>): Promise<T> {\n try {\n const response = await this.http.sendGetRequest<BackendEnvelope<T>>(\n this.gateway.dexBackendBaseUrl,\n '/v2/trade',\n endpoint,\n params,\n );\n return response.data;\n } catch (error: unknown) {\n if (error instanceof GSwapSDKError) throw error;\n throw new GSwapSDKError('Pool request failed.', 'HTTP_ERROR', { cause: error });\n }\n }\n}\n\nasync function resolveSymbol(symbols: PoolSymbols, token: TokenRef): Promise<string> {\n const resolved = await symbols.resolve(token);\n if (resolved.symbol.length > 0) return resolved.symbol;\n throw new GSwapSDKError('Token could not be resolved to a trading symbol.', 'SYMBOL_NOT_FOUND', {\n token,\n });\n}\n\nfunction isPoolListInfo(value: unknown): value is PoolListInfo {\n if (typeof value !== 'object' || value === null) return false;\n const row = value as Record<string, unknown>;\n const requiredNumbers = ['fee', 'tickSpacing', 'protocolFees', 'tradingFees'];\n const optionalStrings = [\n 'token0CompositeKey',\n 'token1CompositeKey',\n 'creator',\n 'price',\n 'sqrtPrice',\n 'token0Tvl',\n 'token1Tvl',\n ];\n const optionalNumbers = [\n 'tick',\n 'tvlUsd',\n 'volume1d',\n 'volume7d',\n 'volume30d',\n 'trades1d',\n 'fee24h',\n 'apr1d',\n 'token0Price',\n 'token1Price',\n ];\n return (\n row['contractVersion'] === 'v2' &&\n typeof row['token0'] === 'string' &&\n typeof row['token1'] === 'string' &&\n typeof row['poolName'] === 'string' &&\n typeof row['poolRef'] === 'string' &&\n requiredNumbers.every((key) => isFiniteNumber(row[key])) &&\n optionalStrings.every((key) => isOptionalString(row[key])) &&\n optionalNumbers.every((key) => isOptionalNumber(row[key]))\n );\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nfunction isOptionalString(value: unknown): value is string | undefined {\n return value === undefined || typeof value === 'string';\n}\n\nfunction isOptionalNumber(value: unknown): value is number | undefined {\n return value === undefined || isFiniteNumber(value);\n}\n","import BigNumber from 'bignumber.js';\nimport { GSwapSDKError } 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 type { GalaChainSigner } from './signers.js';\nimport type { Symbols } 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 { type TokenRef, compositeKeyOf, parseTokenClassKey } from '../utils/ordering.js';\nimport { validateFee, validateNumericAmount } from '../utils/validation.js';\nimport { alignTickDown, alignTickUp, assertTickRange, tickFromPrice } from '../utils/ticks.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};\ntype PositionSymbols = Pick<Symbols, 'resolve' | 'orderPair'> & { invalidate?: () => void };\n\ninterface BackendEnvelope<TData> {\n data: TData;\n}\n\ninterface PositionWire {\n token0CompositeKey?: string;\n token1CompositeKey?: string;\n token0Symbol: string;\n token1Symbol: string;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n liquidity: string;\n amount0: string;\n amount1: string;\n inRange: boolean;\n owner: string;\n currentTick?: number;\n sqrtPrice?: string;\n pool?: string;\n poolRef?: string;\n fees0?: string;\n fees1?: string;\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 ) {\n this.http = new HttpClient(gateway.httpRequestor, gateway.requestTimeoutMs ?? 30_000);\n }\n\n private readonly http: HttpClient;\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.\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<PositionWire[]>('/positions', { user: owner });\n return response.data.map((position) => this.mapPosition(position));\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 pair = await this.symbols.orderPair(args.token0, args.token1);\n const ticks = this.canonicalTicks(args.tickLower, args.tickUpper, pair.flipped);\n const response = await this.getNullable<PositionWire>(\n '/position',\n {\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 signal,\n );\n return response === null ? null : this.mapPosition(response.data);\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: this.requestToken(args.token0),\n token1: this.requestToken(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: this.requestToken(args.token0),\n token1: this.requestToken(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: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount: NumericAmount;\n amountIsToken0: boolean;\n }) {\n validateFee(args.fee);\n const pair = await this.symbols.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 validateNumericAmount(args.amount, 'amount');\n const amount = new BigNumber(args.amount).toFixed();\n const dto: AddLiquidityDTO = {\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.uniqueKey(),\n ...(pair.flipped !== args.amountIsToken0\n ? { depositQuantityToken0: amount }\n : { depositQuantityToken1: amount }),\n };\n return this.submit('AddLiquidity', dto as unknown as Record<string, unknown>, {\n kind: 'add',\n identity: {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n },\n });\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 }) {\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('Price bounds must be finite and positive.', 'VALIDATION_ERROR');\n }\n if (minPrice.isGreaterThan(maxPrice)) {\n throw new GSwapSDKError(\n 'minPrice must be less than or equal to maxPrice.',\n 'VALIDATION_ERROR',\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 });\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: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n amount0?: NumericAmount | undefined;\n amount1?: NumericAmount | undefined;\n }) {\n validateFee(args.fee);\n const pair = await this.symbols.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('Provide at most one of amount0 or amount1.', 'VALIDATION_ERROR');\n }\n if (args.amount0 !== undefined) validateNumericAmount(args.amount0, 'amount0');\n if (args.amount1 !== undefined) validateNumericAmount(args.amount1, 'amount1');\n const withdrawal =\n args.amount0 !== undefined\n ? pair.flipped\n ? { withdrawalQuantityToken1: new BigNumber(args.amount0).toFixed() }\n : { withdrawalQuantityToken0: new BigNumber(args.amount0).toFixed() }\n : args.amount1 !== undefined\n ? pair.flipped\n ? { withdrawalQuantityToken0: new BigNumber(args.amount1).toFixed() }\n : { withdrawalQuantityToken1: new BigNumber(args.amount1).toFixed() }\n : {};\n const dto: RemoveLiquidityDTO = {\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.uniqueKey(),\n ...withdrawal,\n };\n const isFullClose = args.amount0 === undefined && args.amount1 === undefined;\n return this.submit('RemoveLiquidity', dto as unknown as Record<string, unknown>, {\n kind: isFullClose ? 'removeFull' : 'removePartial',\n identity: {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n },\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: {\n token0: TokenRef;\n token1: TokenRef;\n fee: FEE_TIER;\n tickLower: number;\n tickUpper: number;\n }) {\n validateFee(args.fee);\n const pair = await this.symbols.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 const dto: CollectPositionFeesDTO = {\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.uniqueKey(),\n };\n return this.submit('CollectPositionFees', dto as unknown as Record<string, unknown>, {\n kind: 'collect',\n identity: {\n token0: pair.token0.symbol,\n token1: pair.token1.symbol,\n fee: args.fee,\n tickLower: ticks.tickLower,\n tickUpper: ticks.tickUpper,\n },\n });\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 * VALIDATION_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: {\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 isPrivate?: boolean | undefined;\n privateAccess?: string[] | undefined;\n }) {\n const hasPrice = args.startingPrice !== undefined;\n const hasSqrtPrice = args.startingSqrtPrice !== undefined;\n if (hasPrice === hasSqrtPrice) {\n throw new GSwapSDKError(\n 'Provide exactly one of startingPrice or startingSqrtPrice.',\n 'VALIDATION_ERROR',\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('Starting price must be finite and positive.', 'VALIDATION_ERROR');\n }\n const canonicalPrice = flipped ? new BigNumber(1).dividedBy(sourcePrice) : sourcePrice;\n const dto: CreatePoolDTO = {\n token0Key: token0.classKey,\n token1Key: token1.classKey,\n token0Symbol: token0.symbol,\n token1Symbol: token1.symbol,\n fee: args.fee,\n uniqueKey: this.uniqueKey(),\n ...(hasPrice\n ? { startingPrice: canonicalPrice.toFixed() }\n : { startingSqrtPrice: canonicalPrice.toFixed() }),\n ...(args.isPrivate === undefined ? {} : { isPrivate: args.isPrivate }),\n ...(args.privateAccess === undefined ? {} : { privateAccess: args.privateAccess }),\n };\n const transaction = await this.submit('CreatePool', dto, {\n kind: 'createPool',\n token0: token0.symbol,\n token1: token1.symbol,\n fee: args.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 this.signer.signObject(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 if (!(error instanceof GSwapSDKError) || error.details === undefined) return false;\n return error.details['status'] === 404;\n }\n\n private mapPosition(position: PositionWire): Position {\n return {\n token0Symbol: position.token0Symbol,\n token1Symbol: position.token1Symbol,\n ...(position.token0CompositeKey === undefined\n ? {}\n : { token0CompositeKey: position.token0CompositeKey }),\n ...(position.token1CompositeKey === undefined\n ? {}\n : { token1CompositeKey: position.token1CompositeKey }),\n fee: position.fee,\n tickLower: position.tickLower,\n tickUpper: position.tickUpper,\n liquidity: position.liquidity,\n amount0: position.amount0,\n amount1: position.amount1,\n inRange: position.inRange,\n ...(position.currentTick === undefined ? {} : { currentTick: position.currentTick }),\n ...(position.sqrtPrice === undefined ? {} : { sqrtPrice: position.sqrtPrice }),\n pool: position.poolRef ?? position.pool ?? '',\n owner: position.owner,\n ...(position.fees0 === undefined ? {} : { fees0: position.fees0 }),\n ...(position.fees1 === undefined ? {} : { fees1: position.fees1 }),\n };\n }\n\n private requestToken(ref: TokenRef): string {\n return typeof ref === 'string' ? ref : compositeKeyOf(ref);\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(`Unsupported fee tier: ${fee}.`, 'VALIDATION_ERROR');\n }\n return spacing;\n }\n\n private rejectNumber(value: unknown, parameterName: string): void {\n if (typeof value === 'number') {\n throw new GSwapSDKError(\n `Invalid ${parameterName}: use a decimal string or BigNumber, not a JavaScript number`,\n 'VALIDATION_ERROR',\n );\n }\n }\n\n private uniqueKey(): string {\n return `gswap-sdk-${globalThis.crypto.randomUUID()}`;\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 this.symbols.resolve(lookupRef);\n if (\n symbolOverride !== undefined &&\n symbolOverride !== '' &&\n symbolOverride !== resolved.symbol\n ) {\n throw new GSwapSDKError(\n `Supplied symbol ${symbolOverride} disagrees with the registered trading symbol ${resolved.symbol}.`,\n 'VALIDATION_ERROR',\n { token: ref, suppliedSymbol: symbolOverride, registeredSymbol: resolved.symbol },\n );\n }\n const suppliedClassKey = this.tryParseClassKey(ref);\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 (!(error instanceof GSwapSDKError) || error.code !== '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(\n 'Token is not registered in the trading-symbol registry yet; pass token0Symbol/token1Symbol (the token class symbol) to propose one. A symbol cannot be derived from a class key.',\n 'VALIDATION_ERROR',\n { token: ref },\n );\n }\n if (!/^[A-Za-z0-9]+$/u.test(symbolOverride)) {\n throw new GSwapSDKError(\n 'Invalid trading symbol: must be ASCII letters and digits only.',\n 'VALIDATION_ERROR',\n { symbol: symbolOverride },\n );\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","import BigNumber from 'bignumber.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 type { QuoteResult } from '../types/v2_results.js';\nimport type { TokenRef } from '../utils/ordering.js';\nimport { validateNumericAmount } from '../utils/validation.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport type { HttpClient } from './http_client.js';\nimport type { Symbols } from './symbols.js';\n\ninterface QuoteWire {\n contractVersion: 'v2';\n fee: number;\n amountIn: string;\n amountOut: string;\n currentSqrtPrice?: string;\n newSqrtPrice?: string;\n currentPrice?: string;\n newPrice?: string;\n newTick: number;\n tradingFees: string;\n protocolFees: string;\n totalFees: string;\n feeTokenSymbol: string;\n token0Symbol: string;\n token1Symbol: string;\n tokenInIsToken0: boolean;\n}\n\ninterface BackendEnvelope<T> {\n data: T;\n}\n\ntype QuoteSymbols = Pick<Symbols, 'resolve'>;\n\n/** Read-only quote service backed by the v2 offline quote engine. */\nexport class Quoting {\n /**\n * Creates a quote service.\n *\n * @example\n * ```ts\n * const quoting = new Quoting('https://swap-backend.stage.defi.ovh.gala.com', http, symbols);\n * ```\n */\n constructor(\n private readonly dexBackendBaseUrl: string,\n private readonly http: HttpClient,\n private readonly symbols: QuoteSymbols,\n ) {}\n\n /**\n * Quotes the output for a positive exact-input amount.\n *\n * @example\n * ```ts\n * const quote = await quoting.quoteExactInput('GALA', 'GUSDC', '100');\n * console.log(quote.amountOut);\n * ```\n */\n public async quoteExactInput(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n amountIn: NumericAmount,\n fee?: FEE_TIER,\n ): Promise<QuoteResult> {\n validateNumericAmount(amountIn, 'amountIn');\n return this.quote(tokenIn, tokenOut, { amountIn: toDecimalString(amountIn) }, fee);\n }\n\n /**\n * Quotes the input for a positive exact-output amount.\n *\n * @example\n * ```ts\n * const quote = await quoting.quoteExactOutput('GALA', 'GUSDC', '10', 3000);\n * console.log(quote.amountIn);\n * ```\n */\n public async quoteExactOutput(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n amountOut: NumericAmount,\n fee?: FEE_TIER,\n ): Promise<QuoteResult> {\n validateNumericAmount(amountOut, 'amountOut');\n return this.quote(tokenIn, tokenOut, { amountOut: toDecimalString(amountOut) }, fee);\n }\n\n private async quote(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n amount: { amountIn: string } | { amountOut: string },\n fee?: FEE_TIER,\n ): Promise<QuoteResult> {\n validateOptionalFee(fee);\n\n const tokenInSymbol = await resolveSymbol(this.symbols, tokenIn);\n const tokenOutSymbol = await resolveSymbol(this.symbols, tokenOut);\n const params: Record<string, string> = {\n tokenIn: tokenInSymbol,\n tokenOut: tokenOutSymbol,\n ...amount,\n };\n if (fee !== undefined) params['fee'] = String(fee);\n\n try {\n const response = await this.http.sendGetRequest<BackendEnvelope<QuoteWire>>(\n this.dexBackendBaseUrl,\n '/v2/trade',\n '/quote',\n params,\n );\n return mapQuote(response.data);\n } catch (error: unknown) {\n throw mapQuoteError(error, tokenIn, tokenOut, fee);\n }\n }\n}\n\nfunction mapQuote(value: unknown): QuoteResult {\n if (!isQuoteWire(value)) {\n throw new GSwapSDKError('Backend returned an invalid quote.', 'INVALID_CHAIN_RESPONSE', {\n data: value,\n });\n }\n const wire = value;\n const currentPrice =\n wire.currentPrice !== undefined\n ? new BigNumber(wire.currentPrice)\n : orientPrice(wire.currentSqrtPrice!, wire.tokenInIsToken0);\n const newPrice =\n wire.newPrice !== undefined\n ? new BigNumber(wire.newPrice)\n : orientPrice(wire.newSqrtPrice!, wire.tokenInIsToken0);\n const priceImpact = newPrice.minus(currentPrice).dividedBy(currentPrice);\n\n return {\n contractVersion: wire.contractVersion,\n fee: wire.fee,\n amountIn: wire.amountIn,\n amountOut: wire.amountOut,\n ...(wire.currentSqrtPrice === undefined ? {} : { currentSqrtPrice: wire.currentSqrtPrice }),\n ...(wire.newSqrtPrice === undefined ? {} : { newSqrtPrice: wire.newSqrtPrice }),\n feeTier: wire.fee,\n newTick: wire.newTick,\n tradingFees: wire.tradingFees,\n protocolFees: wire.protocolFees,\n totalFees: wire.totalFees,\n feeTokenSymbol: wire.feeTokenSymbol,\n token0Symbol: wire.token0Symbol,\n token1Symbol: wire.token1Symbol,\n tokenInIsToken0: wire.tokenInIsToken0,\n currentPrice,\n newPrice,\n priceImpact,\n };\n}\n\n// The default BigNumber.DECIMAL_PLACES (20) underflows 1/poolPrice to exactly 0 for a\n// pool price above ~1e20 (a real, in-range price for a low-unit-value token quoted\n// against a high-value one) — 60dp matches the precision ticks.ts's DexMath already\n// uses for this same class of division.\nconst HighPrecision = BigNumber.clone({ DECIMAL_PLACES: 60 });\n\nfunction orientPrice(sqrtPrice: string, tokenInIsToken0: boolean): BigNumber {\n const poolPrice = new HighPrecision(sqrtPrice).pow(2);\n return tokenInIsToken0 ? poolPrice : new HighPrecision(1).dividedBy(poolPrice);\n}\n\nfunction isQuoteWire(value: unknown): value is QuoteWire {\n if (typeof value !== 'object' || value === null) return false;\n const wire = value as Record<string, unknown>;\n const requiredStrings = [\n 'amountIn',\n 'amountOut',\n 'tradingFees',\n 'protocolFees',\n 'totalFees',\n 'feeTokenSymbol',\n 'token0Symbol',\n 'token1Symbol',\n ];\n return (\n wire['contractVersion'] === 'v2' &&\n typeof wire['fee'] === 'number' &&\n Number.isFinite(wire['fee']) &&\n requiredStrings.every((key) => typeof wire[key] === 'string') &&\n typeof wire['newTick'] === 'number' &&\n Number.isInteger(wire['newTick']) &&\n typeof wire['tokenInIsToken0'] === 'boolean' &&\n optionalPositiveDecimal(wire['currentSqrtPrice']) &&\n optionalPositiveDecimal(wire['newSqrtPrice']) &&\n optionalPositiveDecimal(wire['currentPrice']) &&\n optionalPositiveDecimal(wire['newPrice']) &&\n (wire['currentSqrtPrice'] !== undefined || wire['currentPrice'] !== undefined) &&\n (wire['newSqrtPrice'] !== undefined || wire['newPrice'] !== undefined)\n );\n}\n\nfunction optionalPositiveDecimal(value: unknown): boolean {\n if (value === undefined) return true;\n if (typeof value !== 'string') return false;\n try {\n // bignumber.js 11+ throws on an unparseable value instead of constructing a NaN\n // instance — this validates an untrusted backend field, so an unparseable value\n // must fail validation cleanly (INVALID_CHAIN_RESPONSE), not throw raw.\n const decimal = new BigNumber(value);\n return decimal.isFinite() && decimal.isGreaterThan(0);\n } catch {\n return false;\n }\n}\n\nfunction mapQuoteError(\n error: unknown,\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER | undefined,\n): GSwapSDKError {\n if (error instanceof GSwapSDKError) {\n const status = readStatus(error.details);\n const message = readMessage(error.details) ?? error.message;\n if (status === 404 || /no pool|no pools|pool does not exist/iu.test(message)) {\n return GSwapSDKError.noPoolAvailableError(tokenIn, tokenOut, fee);\n }\n if (status === 400 && /insufficient liquidity/iu.test(message)) {\n return GSwapSDKError.insufficientLiquidityError(tokenIn, tokenOut, fee);\n }\n return error;\n }\n return new GSwapSDKError('Quote request failed.', 'HTTP_ERROR', {\n cause: error,\n tokenIn,\n tokenOut,\n fee,\n });\n}\n\nfunction readStatus(details: Record<string, unknown> | undefined): number | undefined {\n const status = details?.['status'];\n return typeof status === 'number' ? status : undefined;\n}\n\nfunction readMessage(details: Record<string, unknown> | undefined): string | undefined {\n const direct = details?.['message'];\n if (typeof direct === 'string') return direct;\n const body = details?.['body'];\n if (typeof body !== 'object' || body === null || Array.isArray(body)) return undefined;\n const message = (body as Record<string, unknown>)['message'];\n return typeof message === 'string' ? message : undefined;\n}\n\nfunction validateOptionalFee(fee: FEE_TIER | undefined): void {\n if (fee !== undefined && !ALL_FEE_TIERS.some((tier) => Number(tier) === Number(fee))) {\n throw new GSwapSDKError(`Invalid fee tier: ${fee}`, 'VALIDATION_ERROR', { fee });\n }\n}\n\nfunction toDecimalString(amount: NumericAmount): string {\n return new BigNumber(amount).toFixed();\n}\n\nasync function resolveSymbol(symbols: QuoteSymbols, token: TokenRef): Promise<string> {\n const resolved = await symbols.resolve(token);\n if (resolved.symbol.length > 0) return resolved.symbol;\n throw new GSwapSDKError('Token could not be resolved to a trading symbol.', 'SYMBOL_NOT_FOUND', {\n token,\n });\n}\n","import type { GalaChainTokenClassKey } from '../types/token.js';\nimport type { TradingSymbol } from '../types/v2_results.js';\nimport type { TokenRef } from '../utils/ordering.js';\nimport { compositeKeyOf, orderSymbols, parseTokenClassKey } from '../utils/ordering.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport type { ChainGateway } from './gateway.js';\nimport { HttpClient } from './http_client.js';\n\nconst SYMBOL_CACHE_TTL_MS = 60_000;\n\n/** Symbol registry client for the current GalaChainDex contract. */\nexport class Symbols {\n private cachedSymbols: TradingSymbol[] | undefined;\n private cachedAt = 0;\n private refreshInFlight: Promise<TradingSymbol[]> | undefined;\n\n private readonly http: HttpClient;\n\n /** Create a symbol service backed by the swap backend. */\n constructor(\n private readonly gateway: Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {\n requestTimeoutMs?: number | undefined;\n },\n ) {\n this.http = new HttpClient(gateway.httpRequestor, gateway.requestTimeoutMs);\n }\n\n /** List all registered GalaChainDex trading symbols, cached for 60 seconds. */\n public async list(): Promise<TradingSymbol[]> {\n if (this.cachedSymbols !== undefined && Date.now() - this.cachedAt < SYMBOL_CACHE_TTL_MS) {\n return this.cachedSymbols;\n }\n if (this.refreshInFlight !== undefined) return this.refreshInFlight;\n this.refreshInFlight = this.http\n .sendGetRequest<{ data: unknown }>(this.gateway.dexBackendBaseUrl, '/v2/trade', '/symbols')\n .then((response) => parseSymbols(response.data))\n .then((symbols) => {\n this.cachedSymbols = symbols;\n this.cachedAt = Date.now();\n return symbols;\n })\n .finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n\n /** Invalidate the cached symbol registry after a write changes registration state.\n *\n * @example\n * ```ts\n * gSwap.symbols.invalidate();\n * ```\n */\n public invalidate(): void {\n this.cachedSymbols = undefined;\n this.cachedAt = 0;\n }\n\n /** Force one registry refresh, bypassing the cache.\n *\n * @example\n * ```ts\n * const symbols = await gSwap.symbols.refresh();\n * ```\n */\n public async refresh(): Promise<TradingSymbol[]> {\n this.invalidate();\n // list() would otherwise return an ALREADY in-flight refresh that started before this\n // call (built from pre-invalidation state) — bypassing it too is what makes this\n // actually force a fresh fetch, not just satisfy the cache-freshness check.\n this.refreshInFlight = undefined;\n return this.list();\n }\n\n /** Resolve a symbol or token class key to its registered symbol metadata. */\n public async resolve(ref: TokenRef): Promise<TradingSymbol> {\n let symbols = await this.list();\n const composite =\n typeof ref === 'string'\n ? isCompositeKey(ref)\n ? compositeKeyOf(parseTokenClassKey(ref))\n : undefined\n : compositeKeyOf(ref);\n const resolved = symbols.find(\n (entry) =>\n entry.symbol === ref || (composite !== undefined && compositeKeyOf(entry) === composite),\n );\n if (resolved === undefined) {\n symbols = await this.refresh();\n const refreshed = symbols.find(\n (entry) =>\n entry.symbol === ref || (composite !== undefined && compositeKeyOf(entry) === composite),\n );\n if (refreshed === undefined) throw GSwapSDKError.unknownTokenError(ref);\n return refreshed;\n }\n return resolved;\n }\n\n /** Resolve and put two token references in canonical trading-symbol order. */\n public async orderPair(\n a: TokenRef,\n b: TokenRef,\n ): Promise<{\n token0: TradingSymbol;\n token1: TradingSymbol;\n flipped: boolean;\n }> {\n const [resolvedA, resolvedB] = await Promise.all([this.resolve(a), this.resolve(b)]);\n const [token0Symbol, token1Symbol] = orderSymbols(resolvedA.symbol, resolvedB.symbol);\n return {\n token0: token0Symbol === resolvedA.symbol ? resolvedA : resolvedB,\n token1: token1Symbol === resolvedB.symbol ? resolvedB : resolvedA,\n flipped: token0Symbol !== resolvedA.symbol,\n };\n }\n}\n\nfunction parseSymbols(value: unknown): TradingSymbol[] {\n if (!Array.isArray(value) || !value.every(isTradingSymbol)) {\n throw new GSwapSDKError('Backend returned an invalid symbol list.', 'INVALID_CHAIN_RESPONSE', {\n data: value,\n });\n }\n return value;\n}\n\nfunction isTradingSymbol(value: unknown): value is TradingSymbol {\n if (typeof value !== 'object' || value === null) return false;\n const entry = value as Record<string, unknown>;\n return (\n typeof entry['symbol'] === 'string' &&\n typeof entry['collection'] === 'string' &&\n typeof entry['category'] === 'string' &&\n typeof entry['type'] === 'string' &&\n typeof entry['additionalKey'] === 'string' &&\n typeof entry['decimals'] === 'number' &&\n Number.isInteger(entry['decimals']) &&\n entry['decimals'] >= 0\n );\n}\n\nfunction isCompositeKey(ref: string): boolean {\n return ref.includes('|') || ref.includes('$');\n}\n\n/** Alias exported for callers that use the contract's shorter type name. */\nexport type TokenClassKey = GalaChainTokenClassKey;\n","import BigNumber from 'bignumber.js';\nimport type { NumericAmount } from '../types/amounts.js';\nimport type { FEE_TIER } from '../types/fees.js';\nimport { orderSymbols, readOrderedSymbols, type TokenRef } from '../utils/ordering.js';\nimport { validateFee, validateNumericAmount } from '../utils/validation.js';\nimport type { ChainSubmitOptions } from './gateway.js';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport type { GalaChainSigner } from './signers.js';\nimport { SubmittedTransaction, type ConfirmOptions } from './submitted_transaction.js';\nimport type { AppliedTrade } from '../types/v2_results.js';\nimport type { HttpRequestor } from '../types/http_requestor.js';\nimport type { Symbols } from './symbols.js';\n\n/** The swap backend's apply-results key constraint (`apply-results.dto.ts`). */\nconst UNIQUE_KEY_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/u;\n\nexport type SwapAmount =\n | {\n exactIn: NumericAmount;\n exactOut?: undefined;\n amountOutMinimum?: NumericAmount | undefined;\n amountInMaximum?: undefined;\n }\n | {\n exactIn?: undefined;\n exactOut: NumericAmount;\n amountOutMinimum?: undefined;\n amountInMaximum?: NumericAmount | undefined;\n };\ninterface SwapGateway {\n submit: (\n method: 'RequestTrade',\n signedBody: Record<string, unknown>,\n options?: ChainSubmitOptions,\n ) => Promise<SubmittedTransaction<AppliedTrade>>;\n readonly dexBackendBaseUrl: string;\n readonly httpRequestor: HttpRequestor;\n readonly requestTimeoutMs: number;\n}\ntype SwapSymbols = Pick<Symbols, 'resolve'>;\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: SwapSymbols,\n private readonly signer?: GalaChainSigner,\n private readonly walletAddress?: string,\n ) {}\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 ): Promise<SubmittedTransaction<AppliedTrade>> {\n validateFee(fee);\n\n const dto = await this.buildRequestTradeDto(tokenIn, tokenOut, fee, amount);\n if (this.signer === undefined) throw GSwapSDKError.noSignerError();\n const signedDto = await this.signer.signObject('RequestTrade', dto);\n const submitOptions =\n this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress };\n return this.gateway.submit('RequestTrade', signedDto, submitOptions);\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('gswap-sdk-2f1c…');\n * ```\n */\n public async confirmSwap(uniqueKey: string, options?: ConfirmOptions): Promise<AppliedTrade> {\n if (!UNIQUE_KEY_PATTERN.test(uniqueKey)) {\n throw new GSwapSDKError(\n 'uniqueKey must be 1-128 characters of A-Z, a-z, 0-9, \".\", \"_\", \":\" or \"-\".',\n 'VALIDATION_ERROR',\n { uniqueKey },\n );\n }\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 });\n return transaction.confirm({ initialDelayMs: 0, ...options });\n }\n\n private async buildRequestTradeDto(\n tokenIn: TokenRef,\n tokenOut: TokenRef,\n fee: FEE_TIER,\n amount: SwapAmount,\n ): Promise<Record<string, unknown>> {\n const tokenInSymbol = await resolveSymbol(this.symbols, tokenIn);\n const tokenOutSymbol = await resolveSymbol(this.symbols, tokenOut);\n const ordered = readOrderedSymbols(orderSymbols(tokenInSymbol, tokenOutSymbol));\n const tokenInIsToken0 = tokenInSymbol === ordered.token0;\n\n const dto: Record<string, unknown> = {\n token0: ordered.token0,\n token1: ordered.token1,\n fee,\n uniqueKey: `gswap-sdk-${globalThis.crypto.randomUUID()}`,\n };\n\n if ('exactIn' in amount) {\n const exactIn = amount.exactIn;\n if (exactIn === undefined) {\n throw new GSwapSDKError('exactIn is required for an exact-input swap.', 'VALIDATION_ERROR');\n }\n validateNumericAmount(exactIn, 'exactIn');\n dto[tokenInIsToken0 ? 'sell0Qty' : 'sell1Qty'] = toDecimalString(exactIn);\n if (amount.amountOutMinimum !== undefined) {\n validateNumericAmount(amount.amountOutMinimum, 'amountOutMinimum', true);\n dto['amountOutMinimum'] = toDecimalString(amount.amountOutMinimum);\n }\n } else {\n const exactOut = amount.exactOut;\n if (exactOut === undefined) {\n throw new GSwapSDKError(\n 'exactOut is required for an exact-output swap.',\n 'VALIDATION_ERROR',\n );\n }\n validateNumericAmount(exactOut, 'exactOut');\n dto[tokenInIsToken0 ? 'buy1Qty' : 'buy0Qty'] = toDecimalString(exactOut);\n if (amount.amountInMaximum !== undefined) {\n validateNumericAmount(amount.amountInMaximum, 'amountInMaximum', true);\n dto['amountInMaximum'] = toDecimalString(amount.amountInMaximum);\n }\n }\n return dto;\n }\n}\n\nfunction toDecimalString(amount: NumericAmount): string {\n return new BigNumber(amount).toFixed();\n}\n\nasync function resolveSymbol(symbols: SwapSymbols, token: TokenRef): Promise<string> {\n const resolved = await symbols.resolve(token);\n if (resolved.symbol.length > 0) return resolved.symbol;\n throw new GSwapSDKError('Token could not be resolved to a trading symbol.', 'SYMBOL_NOT_FOUND', {\n token,\n });\n}\n","import { Assets } from './assets.js';\nimport { ChainGateway } from './gateway.js';\nimport { GdexStreamService } from './gdex_stream.js';\nimport { HttpClient } from './http_client.js';\nimport { Pools } from './pools.js';\nimport { Positions } from './positions.js';\nimport { Quoting } from './quoting.js';\nimport type { GalaChainSigner } from './signers.js';\nimport { Symbols } from './symbols.js';\nimport { Swaps } from './swaps.js';\nimport type { HttpRequestor } from '../types/http_requestor.js';\nimport type { GSwapEnv } from '../types/env.js';\nimport { GSWAP_ENVIRONMENTS } from '../types/env.js';\n\n/** Options for constructing a backend-routed SDK client. */\nexport interface GSwapOptions {\n signer?: GalaChainSigner | undefined;\n walletAddress?: string | undefined;\n env?: GSwapEnv | undefined;\n dexBackendBaseUrl?: string | undefined;\n httpRequestor?: HttpRequestor | undefined;\n chainCallTimeoutMs?: number | undefined;\n /** Realtime stream endpoint. Defaults to the environment's, or is derived from `dexBackendBaseUrl`. */\n dexBackendWsUrl?: string | undefined;\n /** WebSocket constructor for the realtime stream; required on Node.js older than 22. */\n webSocketImpl?: unknown;\n}\n\n/** Main entry point for the current GalaChainDex SDK. */\nexport class GSwap {\n public readonly dexBackendBaseUrl: string;\n public readonly chainCallTimeoutMs: number;\n public readonly signer: GalaChainSigner | undefined;\n public readonly walletAddress: string | undefined;\n public readonly gateway: ChainGateway;\n public readonly symbols: Symbols;\n public readonly quoting: Quoting;\n public readonly pools: Pools;\n public readonly positions: Positions;\n public readonly swaps: Swaps;\n public readonly assets: Assets;\n public readonly dexBackendWsUrl: string;\n private readonly webSocketImpl: unknown;\n private streamClient: GdexStreamService | undefined;\n\n /**\n * Create an SDK client for prod or stage.\n *\n * @example\n * ```typescript\n * const gSwap = new GSwap({ env: 'stage' });\n * const symbols = await gSwap.symbols.list();\n * ```\n */\n constructor(options?: GSwapOptions) {\n const environment = GSWAP_ENVIRONMENTS[options?.env ?? 'prod'];\n this.dexBackendBaseUrl = trimTrailingSlash(\n options?.dexBackendBaseUrl ?? environment.dexBackendBaseUrl,\n );\n this.chainCallTimeoutMs = options?.chainCallTimeoutMs ?? 30_000;\n this.signer = options?.signer;\n this.walletAddress = options?.walletAddress;\n\n const httpClient = new HttpClient(options?.httpRequestor, this.chainCallTimeoutMs);\n this.gateway = new ChainGateway({\n dexBackendBaseUrl: this.dexBackendBaseUrl,\n chainCallTimeoutMs: this.chainCallTimeoutMs,\n ...(options?.httpRequestor === undefined ? {} : { httpRequestor: options.httpRequestor }),\n ...(this.walletAddress === undefined ? {} : { walletAddress: this.walletAddress }),\n });\n this.symbols = new Symbols(this.gateway);\n this.quoting = new Quoting(this.dexBackendBaseUrl, httpClient, this.symbols);\n this.pools = new Pools(this.gateway, this.symbols);\n this.positions = new Positions(this.gateway, this.symbols, this.signer, this.walletAddress);\n this.swaps = new Swaps(this.gateway, this.symbols, this.signer, this.walletAddress);\n this.assets = new Assets(this.dexBackendBaseUrl, httpClient);\n this.dexBackendWsUrl =\n options?.dexBackendWsUrl ??\n (options?.dexBackendBaseUrl === undefined\n ? environment.dexBackendWsUrl\n : `${this.dexBackendBaseUrl.replace(/^http/u, 'ws')}/ws`);\n this.webSocketImpl = options?.webSocketImpl;\n }\n\n /**\n * The realtime stream client for this environment (created on first use, not connected until you\n * call `connect()`).\n *\n * @example\n * ```typescript\n * const gSwap = new GSwap({ env: 'stage' });\n * await gSwap.stream.connect();\n * await gSwap.stream.subscribeLiquidity((event) => console.log(event.action, event.amount0));\n * ```\n */\n get stream(): GdexStreamService {\n this.streamClient ??= new GdexStreamService({\n url: this.dexBackendWsUrl,\n ...(this.webSocketImpl === undefined ? {} : { webSocketImpl: this.webSocketImpl }),\n });\n return this.streamClient;\n }\n}\n\nfunction trimTrailingSlash(value: string): string {\n return value.replace(/\\/$/u, '');\n}\n","/**\n * Genuine EIP-712 typed-data signing for the four v2 dex-contract operations proven (2026-09-16,\n * live bisection against stage — see defi-backend's `chain-findings-artifact` memory /\n * https://claude.ai/artifact/3N9MevSjoQdU7gqnVB3dfU) to recover the `client|` identity correctly\n * via `eth_signTypedData_v4`, unlike `personal_sign` (which only ever resolves the bare `eth|`\n * form — see `BrowserWalletSigner`'s own doc comment). Mirrors frontend_v2's\n * `src/Services/eip712Types.ts` + `readWriteUtilsV2.ts`'s `EIP712_FIELD_COMPLETERS` exactly —\n * ported here rather than shared as a package because gswap-sdk has no frontend_v2 dependency\n * and should not gain one for four small functions.\n */\n\nexport type EIP712Types = Record<string, Array<{ name: string; type: string }>>;\n\n/**\n * Derives the EIP-712 `types` for a DTO from its runtime shape.\n *\n * The generated `types` travel with the signed payload and are what BOTH sides hash, so they\n * must enumerate EVERY field the chain-side DTO will carry. GalaChain refuses any signature\n * whose `types` leave a DTO field uncovered (`assertNoUnsignedFields`, the fix for the\n * 2026-08-18 unsigned-field-injection drain); when that happens signature recovery fails\n * outright and the chain reports \"Missing signerPublicKey or signerAddress field in dto\".\n */\nexport function generateEIP712Types(\n typeName: string,\n params: Record<string, unknown>,\n): EIP712Types {\n const types: EIP712Types = {};\n types[typeName] = [];\n\n // Every `name` this is ever called with (the top-level `typeName`, or a nested struct's own\n // name) is unconditionally assigned `types[name] = []` on the line immediately before any\n // recursive call that could reach here; TypeScript still types `types[name]` as\n // possibly-undefined (index-signature access), so the guard below stays for real type safety\n // even though no current call path can actually trigger it.\n function fieldsFor(name: string): Array<{ name: string; type: string }> {\n const fields = types[name];\n /* c8 ignore next */\n if (!fields) throw new Error(`Missing EIP-712 type definition for ${name}`);\n return fields;\n }\n\n function addField(\n name: string,\n fieldValue: unknown,\n parentTypeName: string,\n onlyGetType = false,\n ): string | undefined {\n if (Array.isArray(fieldValue)) {\n const type =\n fieldValue.length > 0 ? addField(name, fieldValue[0], parentTypeName, true) : 'string';\n if (!onlyGetType) fieldsFor(parentTypeName).push({ name, type: (type ?? name) + '[]' });\n } else if (typeof fieldValue === 'object' && fieldValue !== null) {\n if (types[name]) {\n throw new Error('Name collisions not yet supported');\n }\n types[name] = [];\n Object.entries(fieldValue).forEach(([key, value]) => {\n addField(key, value, name);\n });\n if (!onlyGetType) fieldsFor(parentTypeName).push({ name, type: name });\n } else {\n let eipType: string;\n switch (typeof fieldValue) {\n case 'string':\n eipType = 'string';\n break;\n case 'number':\n eipType = 'int256';\n break;\n case 'boolean':\n eipType = 'bool';\n break;\n case 'bigint':\n case 'symbol':\n case 'undefined':\n case 'function':\n case 'object':\n throw new Error(\n `Unsupported type, ${typeof fieldValue}, value: ${Object.prototype.toString.call(fieldValue)}`,\n );\n }\n if (onlyGetType) {\n return eipType;\n }\n fieldsFor(parentTypeName).push({ name, type: eipType });\n }\n return undefined;\n }\n\n Object.entries(params).forEach(([key, value]) => {\n addField(key, value, typeName);\n });\n\n return types;\n}\n\n/** Matches every genuine-EIP-712 probe that has actually recovered `client|` on stage. */\nexport const EIP712_DOMAIN: { name: string; chainId: number } = { name: 'ethereum', chainId: 1 };\n\n/**\n * The four v2 operations proven to recover the signer correctly via genuine EIP-712: `RequestTrade`\n * never had the problem (one numeric field). `AddLiquidity`/`RemoveLiquidity`/\n * `CollectPositionFees` each need their `types` completed with a handful of fields their real\n * server-side DTO always carries — see the `complete*Fields` functions below. `CreatePool` is a\n * genuinely different, unsolved problem (nested `TokenClassKey` structs, not a flat\n * missing-field gap) and is NOT in this set — callers must keep using `personal-sign` for it.\n */\nexport const EIP712_CAPABLE_METHODS: ReadonlySet<string> = new Set([\n 'RequestTrade',\n 'AddLiquidity',\n 'RemoveLiquidity',\n 'CollectPositionFees',\n]);\n\n/**\n * Every `complete*Fields` function below shares the same two live-proven rules:\n * 1. Numeric completeness fields MUST be JS `number`, never numeric strings —\n * `generateEIP712Types` infers a field's Solidity type from `typeof`, and declaring one as\n * EIP-712 `string` instead of `int256` breaks recovery identically to omitting the field\n * entirely (verified live on AddLiquidity: `amount0Min: '0'` fails with the exact same\n * \"Missing signerPublicKey\" error as `amount0Min` being absent; `amount0Min: 0` succeeds).\n * 2. `positionId` has no such constraint — an empty string works, and does not target an\n * existing position (`positionId: ''` created a fresh position on AddLiquidity, not an add\n * to position id `''`; on RemoveLiquidity/CollectPositionFees the real position is still\n * resolved from `token0`/`token1`/`fee`/`tickLower`/`tickUpper`, not from this field).\n */\nfunction numericOr0(dto: Record<string, unknown>, field: string): number {\n return typeof dto[field] === 'number' ? dto[field] : 0;\n}\n\n/**\n * `AddLiquidity`'s real server-side DTO always carries `amount0Desired`/`amount0Min`/\n * `amount1Desired`/`amount1Min`/`positionId` once reconstructed, regardless of which deposit\n * convention the caller used (`Positions.addLiquidityByTicks` only ever sends\n * `depositQuantityToken0`/`depositQuantityToken1`). Proven empirically by bisection: none of the\n * five alone fixes recovery, all five together does (live 201, tx `407d9b24...`, block\n * `2429022`).\n */\nfunction completeAddLiquidityFields(dto: Record<string, unknown>): Record<string, unknown> {\n return {\n ...dto,\n amount0Desired: numericOr0(dto, 'amount0Desired'),\n amount0Min: numericOr0(dto, 'amount0Min'),\n amount1Desired: numericOr0(dto, 'amount1Desired'),\n amount1Min: numericOr0(dto, 'amount1Min'),\n positionId: dto['positionId'] ?? '',\n };\n}\n\n/**\n * `RemoveLiquidity`'s real server-side DTO always carries `amount`/`amount0Min`/`amount1Min`/\n * `positionId` — `Positions.removeLiquidity` only ever sends a `withdrawalQuantityTokenX` (or\n * neither, for a full close). Proven empirically: every subset of these four fails, all four\n * together succeeds (live, random-signer probe — recovery confirmed by the response moving from\n * \"Missing signerPublicKey\" to a genuine position-not-found 404).\n */\nfunction completeRemoveLiquidityFields(dto: Record<string, unknown>): Record<string, unknown> {\n return {\n ...dto,\n amount: numericOr0(dto, 'amount'),\n amount0Min: numericOr0(dto, 'amount0Min'),\n amount1Min: numericOr0(dto, 'amount1Min'),\n positionId: dto['positionId'] ?? '',\n };\n}\n\n/**\n * `CollectPositionFees`'s real server-side DTO always carries `amount0Requested`/\n * `amount1Requested`/`positionId` — `Positions.collectPositionFees` sends only the five identity\n * fields. Proven empirically the same way as `completeRemoveLiquidityFields`.\n */\nfunction completeCollectPositionFeesFields(dto: Record<string, unknown>): Record<string, unknown> {\n return {\n ...dto,\n amount0Requested: numericOr0(dto, 'amount0Requested'),\n amount1Requested: numericOr0(dto, 'amount1Requested'),\n positionId: dto['positionId'] ?? '',\n };\n}\n\nexport const EIP712_FIELD_COMPLETERS: Readonly<\n Record<string, (dto: Record<string, unknown>) => Record<string, unknown>>\n> = {\n AddLiquidity: completeAddLiquidityFields,\n RemoveLiquidity: completeRemoveLiquidityFields,\n CollectPositionFees: completeCollectPositionFeesFields,\n};\n\n/**\n * Completes a DTO's fields for EIP-712 signing (a no-op for methods with no known gap, e.g.\n * `RequestTrade`) and derives its `types`. Exported separately from the signing call itself so tests\n * can assert on the exact payload without needing a live provider.\n */\nexport function buildEIP712Payload(\n methodName: string,\n dto: Record<string, unknown>,\n): { completedDto: Record<string, unknown>; types: EIP712Types } {\n const completer = EIP712_FIELD_COMPLETERS[methodName];\n const completedDto = completer ? completer(dto) : dto;\n const types = generateEIP712Types(methodName, completedDto);\n return { completedDto, types };\n}\n","import { serialize, signatures } from '@gala-chain/api';\nimport { GSwapSDKError } from './gswap_sdk_error.js';\nimport {\n buildEIP712Payload,\n EIP712_CAPABLE_METHODS,\n EIP712_DOMAIN,\n type EIP712Types,\n} from '../utils/eip712.js';\n\n// Personal-sign prefix, computed the way THE CHAIN verifies it.\n//\n// GalaChain (SDK 3.x) recovers a personal-signed DTO from\n// keccak256(<prefix field> + <canonical JSON of the DTO WITHOUT the prefix field>)\n// and a browser wallet's `personal_sign` (EIP-191) hashes\n// \"\\u0019Ethereum Signed Message:\\n\" + <byte length of message> + <message>.\n// They agree exactly when the wallet signs the bare canonical DTO and `prefix` is the EIP-191\n// header for that message's UTF-8 BYTE length. Any other message still yields a valid-looking\n// signature — it just recovers to an address nobody holds. This SDK used to embed `prefix` in\n// the signed message (the SDK 1.10 client recipe): observed on stage 2026-09-23, such a\n// MetaMask-signed CreatePool executed on chain under a phantom creator, and defi-backend's\n// bouncer now rejects that shape outright.\n//\n// `@gala-chain/connect`'s prefix helper must NOT be used for wallet `personal_sign`: its\n// fixpoint counts the prefix itself and targets the SDK's raw-payload signer. The same header\n// is also what Gala Wallet's `gala_signChainDto` (personal-sign scheme) prepends before hashing,\n// so one value serves both paths.\n//\n// Built via String.fromCharCode rather than a literal escape ON PURPOSE: the EIP-191 control\n// byte is invisible either way once it's a real character in the string, but a literal escape\n// in source is itself a raw control byte sitting in the file the moment any tool decodes it\n// (an editor save, a diff, a copy-paste) — this keeps the source text itself ordinary and\n// constructs the byte at runtime instead.\nconst ETHEREUM_SIGNED_MESSAGE = String.fromCharCode(0x19) + 'Ethereum Signed Message:\\n';\n\n/** The EIP-191 header for `dto`'s canonical JSON (UTF-8 byte length; any `prefix` on it is ignored). */\nfunction personalSignPrefixFor(dto: Record<string, unknown>): string {\n const withoutPrefix: Record<string, unknown> = { ...dto };\n delete withoutPrefix['prefix'];\n const message = serialize(withoutPrefix);\n return ETHEREUM_SIGNED_MESSAGE + String(new TextEncoder().encode(message).length);\n}\n\n/** The signing schemes supported by the Gala Wallet signer. */\nexport type GalaWalletScheme = 'native' | 'personal-sign';\n\n/** The request surface used by an EIP-1193 browser wallet. */\nexport interface BrowserWalletProvider {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n}\n\ninterface GalaWalletProvider {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n}\n\ninterface WindowWithGala {\n gala?: GalaWalletProvider;\n}\n\ninterface GlobalWithWindow {\n window?: WindowWithGala;\n}\n\ntype SignedDto<T extends Record<string, unknown>> = T & { signature: string };\n\n/**\n * A signer for complete GalaChain write bodies.\n *\n * Implementations return the DTO fields together with the signature that belongs in the\n * gateway request body. Signer identity is recovered from that signature; implementations do\n * not add signer hints, typed-data metadata, or a domain.\n */\nexport interface GalaChainSigner {\n /**\n * Signs a DTO for a named GalaChain contract method.\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n */\n signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;\n}\n\nfunction getWalletProvider(): GalaWalletProvider {\n const globalObject = globalThis as GlobalWithWindow;\n const wallet = globalObject.window?.gala;\n if (!wallet) {\n throw new GSwapSDKError(\n 'Gala wallet is not available. Please ensure the Gala wallet is connected.',\n 'GALA_WALLET_NOT_AVAILABLE',\n );\n }\n return wallet;\n}\n\nfunction getNativeSignature(value: unknown): string {\n if (typeof value !== 'string') {\n throw new GSwapSDKError('Wallet returned an invalid signature.', 'INVALID_SIGNATURE');\n }\n if (!/^[0-9a-fA-F]{130}$/u.test(value)) {\n throw new GSwapSDKError('Wallet returned an invalid native signature.', 'INVALID_SIGNATURE');\n }\n return value;\n}\n\nfunction getPersonalSignature(value: unknown): string {\n if (typeof value !== 'string' || !/^(?:0x)?[0-9a-fA-F]{130}$/u.test(value)) {\n throw new GSwapSDKError(\n 'Wallet returned an invalid personal-sign signature.',\n 'INVALID_SIGNATURE',\n );\n }\n return value;\n}\n\nfunction normalizeEthereumAccount(address: string, allowGalaPrefix: boolean): string {\n const normalized = allowGalaPrefix && address.startsWith('eth|') ? address.slice(4) : address;\n if (!/^0x[0-9a-fA-F]{40}$/u.test(normalized)) {\n throw new GSwapSDKError(\n 'Wallet address must be the selected Ethereum account in 0x-prefixed form.',\n 'VALIDATION_ERROR',\n { type: 'INVALID_WALLET_ADDRESS', value: address },\n );\n }\n return `0x${normalized.slice(2).toLowerCase()}`;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n if (typeof error === 'object' && error !== null && 'message' in error) {\n const message = error.message;\n return typeof message === 'string' ? message : '';\n }\n return '';\n}\n\n// Deliberately does NOT match a generic \"invalid params\" (JSON-RPC -32602) — that code fires\n// for many validation failures unrelated to scheme support (e.g. a malformed DTO), and a false\n// match here would permanently latch effectiveScheme to 'personal-sign' for every future call\n// on this signer, even though native signing was never actually unsupported.\nfunction isUnsupportedNativeSchemeError(error: unknown): boolean {\n return /unsupported|unknown scheme/i.test(getErrorMessage(error));\n}\n\nfunction personalSign<T extends Record<string, unknown>>(\n provider: GalaWalletProvider | BrowserWalletProvider,\n dto: T,\n walletAddress: string,\n methodName?: string,\n): Promise<T & { prefix: string; signature: string }> {\n const prefix = personalSignPrefixFor(dto);\n const payload = { ...dto, prefix };\n // A browser wallet's `personal_sign` applies the EIP-191 header ITSELF, so it must sign the\n // bare DTO; Gala Wallet's `gala_signChainDto` (personal-sign scheme) instead extracts the\n // `prefix` field from what it is handed and prepends it before hashing, so it is handed the\n // prefixed payload. Both submit `{ ...dto, prefix, signature }`.\n const params =\n methodName !== undefined\n ? [serialize(payload), walletAddress, methodName]\n : [serialize(dto), walletAddress];\n\n return provider\n .request({ method: methodName !== undefined ? 'gala_signChainDto' : 'personal_sign', params })\n .then((value) => ({ ...payload, signature: getPersonalSignature(value) }));\n}\n\n/**\n * Signs a DTO via genuine EIP-712 (`eth_signTypedData_v4`) — correctly resolves the `client|`\n * identity, unlike `personal_sign`, for the operations in `EIP712_CAPABLE_METHODS`.\n *\n * Constructs the raw JSON-RPC payload by hand (`{domain, types: {...types, EIP712Domain},\n * primaryType, message}`) rather than depending on ethers.js, matching exactly what\n * `ethers.TypedDataEncoder.getPayload`/`Wallet.signTypedData` produce internally — verified\n * byte-for-byte equivalent (same recovered address from the same signature against both\n * constructions) before this shipped, since gswap-sdk deliberately has no ethers dependency.\n */\nfunction signEIP712<T extends Record<string, unknown>>(\n provider: BrowserWalletProvider,\n methodName: string,\n dto: T,\n walletAddress: string,\n): Promise<T & { types: EIP712Types; domain: typeof EIP712_DOMAIN; signature: string }> {\n const { completedDto, types } = buildEIP712Payload(methodName, dto);\n const prefix = personalSignPrefixFor(completedDto);\n const message = { ...completedDto, prefix };\n const eip712Domain = [\n { name: 'name', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n ];\n const payload = {\n domain: EIP712_DOMAIN,\n types: { ...types, EIP712Domain: eip712Domain },\n primaryType: methodName,\n message,\n };\n\n return provider\n .request({\n method: 'eth_signTypedData_v4',\n params: [walletAddress, JSON.stringify(payload)],\n })\n .then((value) => ({\n ...(message as T & { prefix: string }),\n types,\n domain: EIP712_DOMAIN,\n signature: getPersonalSignature(value),\n }));\n}\n\n/**\n * A GalaChain native signer backed by a secp256k1 private key.\n *\n * Native signing produces the bare GalaChain signature format, without a personal-sign prefix\n * or EIP-712 metadata. The private-key identity is recovered by the chain.\n */\nexport class PrivateKeySigner implements GalaChainSigner {\n private readonly keyBuffer: Buffer;\n\n /**\n * Creates a native signer from a hex or base64 secp256k1 private key.\n *\n * @example\n * ```typescript\n * const signer = new PrivateKeySigner('1'.padStart(64, '0'));\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n */\n constructor(privateKey: string) {\n this.keyBuffer = signatures.normalizePrivateKey(privateKey);\n }\n\n /**\n * Signs the DTO with GalaChain native signing.\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('RequestTrade', {\n * token0: 'GALA',\n * token1: 'GUSDC',\n * fee: 3000,\n * });\n * ```\n */\n public signObject<T extends Record<string, unknown>>(\n _methodName: string,\n dto: T,\n ): Promise<SignedDto<T>> {\n const signature = signatures.getSignature(dto, this.keyBuffer);\n return Promise.resolve({ ...dto, signature });\n }\n}\n\n/**\n * A Gala Wallet signer using native GalaChain signing, with an opt-in personal-sign mode and\n * automatic fallback for older wallets.\n *\n * The selected Ethereum account is passed to Gala Wallet. Personal-sign resolves the bare\n * `eth|` identity; the legacy EIP-712 `eth_signTypedData` path is not used. The fallback calls\n * `gala_signChainDto([serialize({ ...dto, prefix }), walletAddress, methodName])`.\n */\nexport class GalaWalletSigner implements GalaChainSigner {\n /** The wallet address supplied to Gala Wallet for each signing request. */\n public readonly walletAddress: string;\n\n /** The scheme currently used, including any automatic native-to-personal fallback. */\n public effectiveScheme: GalaWalletScheme;\n\n /**\n * Creates a Gala Wallet signer.\n *\n * @example\n * ```typescript\n * const signer = new GalaWalletSigner('0x0123456789012345678901234567890123456789');\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n *\n * @param walletAddress - The selected Ethereum account (`0x` plus 40 hex digits); Gala Wallet's\n * `eth|0x...` form is also accepted and normalized.\n * @param options - Select native signing or personal-sign explicitly.\n */\n constructor(walletAddress: string, options: { scheme?: GalaWalletScheme | undefined } = {}) {\n this.walletAddress = normalizeEthereumAccount(walletAddress, true);\n this.effectiveScheme = options.scheme ?? 'native';\n }\n\n /**\n * Signs a DTO through `gala_signChainDto`.\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('AddLiquidity', {\n * token0: 'GALA',\n * token1: 'GUSDC',\n * tickLower: -60,\n * tickUpper: 60,\n * });\n * ```\n */\n public async signObject<T extends Record<string, unknown>>(\n methodName: string,\n dto: T,\n ): Promise<SignedDto<T>> {\n const wallet = getWalletProvider();\n\n if (this.effectiveScheme === 'personal-sign') {\n return personalSign(wallet, dto, this.walletAddress, methodName);\n }\n\n try {\n const signature = await wallet.request({\n method: 'gala_signChainDto',\n params: [serialize(dto), this.walletAddress, methodName, 'native'],\n });\n return { ...dto, signature: getNativeSignature(signature) };\n } catch (error: unknown) {\n if (!isUnsupportedNativeSchemeError(error)) {\n throw error;\n }\n this.effectiveScheme = 'personal-sign';\n return personalSign(wallet, dto, this.walletAddress, methodName);\n }\n }\n}\n\n/**\n * A personal-sign signer for MetaMask and other EIP-1193 browser wallets.\n *\n * The chain recovers this signature using the EIP-191 wrap applied by the wallet to\n * `personal_sign`. This is the browser-wallet path used by the v2 frontend and resolves the\n * bare `eth|` identity.\n */\nexport class BrowserWalletSigner implements GalaChainSigner {\n /**\n * Creates a browser-wallet signer.\n *\n * Defaults to `personal_sign` — unchanged from every existing integration, since it only ever\n * resolves the bare `eth|` identity and changing that silently would be a real behavior\n * break for anyone already depending on it. Pass `{ scheme: 'eip712' }` to correctly resolve\n * a registered `client|` alias instead, for `RequestTrade`/`AddLiquidity`/`RemoveLiquidity`/\n * `CollectPositionFees` (`EIP712_CAPABLE_METHODS`) — `CreatePool` and any other method still\n * falls back to `personal_sign` even in `'eip712'` mode, since its EIP-712 signing is a\n * separate, unsolved chain-side problem.\n *\n * @example\n * ```typescript\n * const signer = new BrowserWalletSigner(window.ethereum, '0x0123456789012345678901234567890123456789');\n * const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });\n * ```\n * @example\n * ```typescript\n * // Correctly resolves a registered client| alias instead of the bare eth| address.\n * const signer = new BrowserWalletSigner(window.ethereum, walletAddress, { scheme: 'eip712' });\n * ```\n */\n constructor(\n private readonly provider: BrowserWalletProvider,\n walletAddress: string,\n options: { scheme?: 'personal-sign' | 'eip712' } = {},\n ) {\n this.walletAddress = normalizeEthereumAccount(walletAddress, false);\n this.scheme = options.scheme ?? 'personal-sign';\n }\n\n public readonly walletAddress: string;\n private readonly scheme: 'personal-sign' | 'eip712';\n\n /**\n * Signs the DTO with `eth_signTypedData_v4` (when constructed with `{ scheme: 'eip712' }` and\n * `methodName` is in `EIP712_CAPABLE_METHODS`) or the EIP-1193 `personal_sign` method\n * (otherwise — the default).\n *\n * @example\n * ```typescript\n * const signed = await signer.signObject('RequestTrade', {\n * token0: 'GALA',\n * token1: 'GUSDC',\n * fee: 3000,\n * });\n * ```\n */\n public signObject<T extends Record<string, unknown>>(\n methodName: string,\n dto: T,\n ): Promise<SignedDto<T>> {\n if (this.scheme === 'eip712' && EIP712_CAPABLE_METHODS.has(methodName)) {\n return signEIP712(this.provider, methodName, dto, this.walletAddress);\n }\n return personalSign(this.provider, dto, this.walletAddress);\n }\n}\n"],"mappings":"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"}