@gala-chain/gswap-sdk 1.1.1 → 1.2.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -5
- package/dist/browser/index.js +4 -3
- package/dist/browser/index.js.map +1 -1
- package/dist/index.cjs +3282 -610
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2021 -471
- package/dist/index.d.ts +2021 -471
- package/dist/index.mjs +3213 -608
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -6
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
+
//#region src/types/confirm_options.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Controls timeout, polling and cancellation of confirmation.
|
|
5
|
+
*
|
|
6
|
+
* - `timeoutMs` (default 60 000): overall deadline, counted from the `confirm()` call and
|
|
7
|
+
* including `initialDelayMs`. At least one read is always made.
|
|
8
|
+
* - `pollIntervalMs` (default 2 000, minimum 500): base interval, doubled with jitter up to 8 s.
|
|
9
|
+
* - `initialDelayMs`: wait before the first read. Defaults to 3 000 for a queued RequestTrade
|
|
10
|
+
* (the AutoApplier needs a few seconds) and 0 for liquidity writes (already executed).
|
|
11
|
+
* - `signal`: aborts the wait or an in-flight read. Confirmation then throws an error with code
|
|
12
|
+
* `CONFIRMATION_ABORTED`; nothing is learned about the outcome, so confirm the same
|
|
13
|
+
* `uniqueKey` again later.
|
|
14
|
+
*/
|
|
15
|
+
export interface ConfirmOptions {
|
|
16
|
+
timeoutMs?: number | undefined;
|
|
17
|
+
pollIntervalMs?: number | undefined;
|
|
18
|
+
initialDelayMs?: number | undefined;
|
|
19
|
+
signal?: AbortSignal | undefined;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/types/http_requestor.d.ts
|
|
23
|
+
type FetchReturnValue = Awaited<ReturnType<typeof fetch>>;
|
|
24
|
+
interface HTTPResponse {
|
|
25
|
+
ok: FetchReturnValue['ok'];
|
|
26
|
+
status: FetchReturnValue['status'];
|
|
27
|
+
json: FetchReturnValue['json'];
|
|
28
|
+
text: FetchReturnValue['text'];
|
|
29
|
+
headers?: {
|
|
30
|
+
get(name: string): string | null;
|
|
31
|
+
} | Record<string, string | undefined>;
|
|
32
|
+
}
|
|
33
|
+
type HttpRequestor = (uri: string, options?: Parameters<typeof fetch>[1]) => Promise<HTTPResponse>;
|
|
34
|
+
//#endregion
|
|
2
35
|
//#region src/types/v2_results.d.ts
|
|
3
36
|
/** Pool metadata returned by GalaChainDex. */
|
|
4
37
|
export interface PoolInfo {
|
|
@@ -15,19 +48,26 @@ export interface PoolInfo {
|
|
|
15
48
|
isPrivate?: boolean;
|
|
16
49
|
flippedFromRequest?: boolean;
|
|
17
50
|
}
|
|
18
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Pool summary returned by the backend pool-list route. Only the identity (`token0`, `token1`,
|
|
53
|
+
* `poolRef`) and `fee` are guaranteed; a row that lacks any other field is still a usable row, as
|
|
54
|
+
* the apps that list pools treat it.
|
|
55
|
+
*/
|
|
19
56
|
export interface PoolListInfo {
|
|
20
|
-
contractVersion
|
|
57
|
+
contractVersion?: 'v2' | undefined;
|
|
21
58
|
token0: string;
|
|
22
59
|
token1: string;
|
|
23
60
|
token0CompositeKey?: string | undefined;
|
|
24
61
|
token1CompositeKey?: string | undefined;
|
|
62
|
+
/** Registry image URL of token0 resolved by the backend; empty when the token is unregistered. */
|
|
63
|
+
token0Image?: string | undefined;
|
|
64
|
+
token1Image?: string | undefined;
|
|
25
65
|
fee: number;
|
|
26
|
-
poolName
|
|
66
|
+
poolName?: string | undefined;
|
|
27
67
|
poolRef: string;
|
|
28
|
-
tickSpacing
|
|
29
|
-
protocolFees
|
|
30
|
-
tradingFees
|
|
68
|
+
tickSpacing?: number | undefined;
|
|
69
|
+
protocolFees?: number | undefined;
|
|
70
|
+
tradingFees?: number | undefined;
|
|
31
71
|
creator?: string | undefined;
|
|
32
72
|
price?: string | undefined;
|
|
33
73
|
sqrtPrice?: string | undefined;
|
|
@@ -103,6 +143,9 @@ export interface Position {
|
|
|
103
143
|
token1Symbol: string;
|
|
104
144
|
token0CompositeKey?: string;
|
|
105
145
|
token1CompositeKey?: string;
|
|
146
|
+
/** Registry image URL of token0 resolved by the backend; empty when the token is unregistered. */
|
|
147
|
+
token0Image?: string;
|
|
148
|
+
token1Image?: string;
|
|
106
149
|
fee: number;
|
|
107
150
|
tickLower: number;
|
|
108
151
|
tickUpper: number;
|
|
@@ -209,25 +252,189 @@ export interface ChainSubmissionResult {
|
|
|
209
252
|
uniqueKey?: string;
|
|
210
253
|
}
|
|
211
254
|
//#endregion
|
|
212
|
-
//#region src/types/
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
255
|
+
//#region src/types/wire.d.ts
|
|
256
|
+
/**
|
|
257
|
+
* How the SDK writes a read request on the wire. The defaults suit a server-side caller; an app
|
|
258
|
+
* that already issues the same requests from its own HTTP stack (frontend_v2, the Gala Wallet)
|
|
259
|
+
* sets these so the SDK's requests are indistinguishable from the ones it replaces.
|
|
260
|
+
*
|
|
261
|
+
* One object, carried by {@link ChainGateway}, so every service built on a gateway (symbols,
|
|
262
|
+
* pools, positions, quoting) shares it without per-service plumbing.
|
|
263
|
+
*/
|
|
264
|
+
export interface WireOptions {
|
|
265
|
+
/**
|
|
266
|
+
* Query-string encoding of GET parameters.
|
|
267
|
+
*
|
|
268
|
+
* - `'standard'` (default): `URLSearchParams` (`application/x-www-form-urlencoded`), where `$`
|
|
269
|
+
* and `|` become `%24` and `%7C`.
|
|
270
|
+
* - `'readable'`: keeps `$ | : ,` and the RFC 3986 sub-delimiters `! ' ( ) *` unescaped, so a
|
|
271
|
+
* composite key such as `GALA$Unit$none$none` or `client|abc` reads as written. Everything
|
|
272
|
+
* that would change a query's meaning (`& = # % +`, space, non-ASCII, controls) is still
|
|
273
|
+
* percent-encoded (a space is `+`), so the server decodes exactly the value that was passed.
|
|
274
|
+
* This is the text frontend_v2's `formatUrl` produces for every value it can represent.
|
|
275
|
+
*/
|
|
276
|
+
queryEncoding?: 'standard' | 'readable' | undefined;
|
|
277
|
+
/**
|
|
278
|
+
* The `User-Agent` request header. Defaults to `GalaChain-SDK/<version>`; `false` omits it
|
|
279
|
+
* (browsers forbid setting it, and an app whose own requests carry none can match them).
|
|
280
|
+
* `Content-Type` is only ever sent with a request body, never on a GET.
|
|
281
|
+
*/
|
|
282
|
+
userAgent?: string | false | undefined;
|
|
283
|
+
/**
|
|
284
|
+
* Extra request headers for every read, sent after (and so able to replace) the defaults above;
|
|
285
|
+
* for example axios' `Accept: application/json, text/plain, *\/*`, so a request is the same as
|
|
286
|
+
* the one an app's own HTTP stack used to send.
|
|
287
|
+
*/
|
|
288
|
+
headers?: Record<string, string> | undefined;
|
|
222
289
|
}
|
|
223
|
-
|
|
290
|
+
//#endregion
|
|
291
|
+
//#region src/types/token.d.ts
|
|
292
|
+
export interface GalaChainTokenClassKey {
|
|
293
|
+
collection: string;
|
|
294
|
+
category: string;
|
|
295
|
+
type: string;
|
|
296
|
+
additionalKey: string;
|
|
297
|
+
}
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/classes/gswap_sdk_error.d.ts
|
|
300
|
+
/** Error raised by the SDK for validation, gateway, chain, or transaction failures. */
|
|
301
|
+
export declare class GSwapSDKError extends Error {
|
|
302
|
+
readonly code: string;
|
|
303
|
+
readonly details?: Record<string, unknown> | undefined;
|
|
304
|
+
readonly chainMessage: string | undefined;
|
|
305
|
+
readonly retryAfterMs: number | undefined;
|
|
306
|
+
/** The HTTP status of the response that caused this error, when there was one. */
|
|
307
|
+
readonly status: number | undefined;
|
|
308
|
+
/**
|
|
309
|
+
* The response body parsed as JSON, when the failing response had one; `undefined` for a body
|
|
310
|
+
* that was not JSON (see {@link bodyText}). Never part of {@link message}.
|
|
311
|
+
*/
|
|
312
|
+
readonly body: unknown;
|
|
313
|
+
/**
|
|
314
|
+
* The raw text of a failing response whose body was NOT JSON (a proxy's HTML 502, a WAF page,
|
|
315
|
+
* an empty body). It is kept here for diagnostics and is never copied into {@link message} or
|
|
316
|
+
* {@link userMessage}, so it cannot reach a user interface by accident.
|
|
317
|
+
*/
|
|
318
|
+
readonly bodyText: string | undefined;
|
|
319
|
+
constructor(message: string, code: string, details?: Record<string, unknown> | undefined, chainMessage?: string, retryAfterMs?: number);
|
|
320
|
+
/**
|
|
321
|
+
* A message that is safe to show a user as is: the server's own message when it sent one
|
|
322
|
+
* (a gateway or chain rejection), a neutral line naming the status for an HTTP failure with no
|
|
323
|
+
* readable answer, and otherwise {@link message}. Apps that word these differently (a
|
|
324
|
+
* "network busy" line for a 502, say) branch on {@link code} and {@link status} instead.
|
|
325
|
+
*/
|
|
326
|
+
get userMessage(): string;
|
|
327
|
+
/**
|
|
328
|
+
* True when the failure means "that market, pool or position does not exist" rather than
|
|
329
|
+
* "something went wrong": an HTTP 404, a pair with no pool at any fee tier
|
|
330
|
+
* (`NO_POOL_AVAILABLE`), or a token the DEX contract has no trading symbol for
|
|
331
|
+
* (`UNKNOWN_TOKEN`). A pool that exists but is too thin (`INSUFFICIENT_LIQUIDITY`) is NOT
|
|
332
|
+
* not-found.
|
|
333
|
+
*/
|
|
334
|
+
get notFound(): boolean;
|
|
335
|
+
/** Create the standard missing-signer error. */
|
|
336
|
+
static noSignerError(): GSwapSDKError;
|
|
337
|
+
/** Create the error used when confirming a position write without a configured wallet address. */
|
|
338
|
+
static noWalletAddressError(): GSwapSDKError;
|
|
339
|
+
/**
|
|
340
|
+
* Create the error used when no pool can quote the requested pair. `source` is the backend
|
|
341
|
+
* answer that said so; its status, body and message are kept (the message as `chainMessage`,
|
|
342
|
+
* so {@link userMessage} is the server's own wording).
|
|
343
|
+
*/
|
|
344
|
+
static noPoolAvailableError(tokenIn: GalaChainTokenClassKey | string, tokenOut: GalaChainTokenClassKey | string, fee?: number, source?: GSwapSDKError): GSwapSDKError;
|
|
345
|
+
/** Create the error used when a pool lacks liquidity for a quote. `source` as for {@link noPoolAvailableError}. */
|
|
346
|
+
static insufficientLiquidityError(tokenIn: GalaChainTokenClassKey | string, tokenOut: GalaChainTokenClassKey | string, fee?: number, source?: GSwapSDKError): GSwapSDKError;
|
|
347
|
+
/**
|
|
348
|
+
* The message the server put in a JSON answer (`message`, or `error.Message`), when this error
|
|
349
|
+
* came from an HTTP response that had one.
|
|
350
|
+
*/
|
|
351
|
+
get serverMessage(): string | undefined;
|
|
352
|
+
/** Convert a chain-gateway bounce into a typed SDK error. */
|
|
353
|
+
static fromGatewayBounce(code: string, message: string, status: number, retryAfterMs?: number): GSwapSDKError;
|
|
354
|
+
/** Convert a GalaChain `Status: 0` response into a typed SDK error. */
|
|
355
|
+
static fromChainError(errorKey: string, message: string, details?: Record<string, unknown>): GSwapSDKError;
|
|
356
|
+
/** Create the error used when a token is not registered by the current DEX contract. */
|
|
357
|
+
static unknownTokenError(token: GalaChainTokenClassKey | string): GSwapSDKError;
|
|
358
|
+
/** Create the error used when apply-results confirmation does not arrive in time. */
|
|
359
|
+
static confirmationTimeoutError(uniqueKey: string, cause?: unknown): GSwapSDKError;
|
|
360
|
+
/** Convert an unexpected HTTP response into an SDK error. */
|
|
361
|
+
static fromErrorResponse(url: string, response: HTTPResponse): Promise<GSwapSDKError>;
|
|
362
|
+
}
|
|
363
|
+
/** Narrow an object property without trusting a cast at a network boundary. */
|
|
364
|
+
export declare function getObjectProperty(value: unknown, property: string): Record<string, unknown> | undefined;
|
|
365
|
+
/** Read a string property from an unknown object. */
|
|
366
|
+
export declare function getStringProperty(value: unknown, property: string): string | undefined;
|
|
367
|
+
/** Parse a response body, preserving non-JSON text for error reporting. */
|
|
368
|
+
export declare function parseJson(text: string): unknown;
|
|
369
|
+
//#endregion
|
|
370
|
+
//#region src/classes/apply_results.d.ts
|
|
371
|
+
/**
|
|
372
|
+
* The outcome of a queued RequestTrade that could not be delivered as an {@link AppliedTrade}.
|
|
373
|
+
* `code` says why:
|
|
374
|
+
*
|
|
375
|
+
* - `CONFIRMATION_TIMEOUT`: no terminal result before the deadline. The trade may still apply;
|
|
376
|
+
* confirm the same `uniqueKey` again later and never resubmit.
|
|
377
|
+
* - `CONFIRMATION_ABORTED`: the caller's `signal` aborted. Nothing is known about the outcome.
|
|
378
|
+
* - `CONFIRMATION_FAILED`: the apply-results read itself failed (malformed key or body, a
|
|
379
|
+
* non-retryable HTTP status). The outcome is unknown.
|
|
380
|
+
* - anything else: the chain REJECTED the trade; `code` is the chain `ErrorKey` (or
|
|
381
|
+
* `CHAIN_ERROR`) and `chainMessage` is its message, which is also `message`.
|
|
382
|
+
*
|
|
383
|
+
* `details` always carries `uniqueKey` and, where known, `requestTransactionId`,
|
|
384
|
+
* `applyTransactionId`, `blockNumber`, `status`, `body`, `url` and the last transport `cause`.
|
|
385
|
+
*/
|
|
386
|
+
export declare class AppliedTradeError extends GSwapSDKError {
|
|
387
|
+
constructor(message: string, code: string, details?: Record<string, unknown>, chainMessage?: string);
|
|
388
|
+
}
|
|
389
|
+
/** The transport and backend a confirmation reads from. */
|
|
390
|
+
export interface ApplyResultsClient {
|
|
391
|
+
/** Swap backend origin, e.g. `https://dex-backend-prod1.defi.gala.com` (no trailing path). */
|
|
392
|
+
dexBackendBaseUrl: string;
|
|
393
|
+
/** Defaults to the global `fetch`. */
|
|
394
|
+
httpRequestor?: HttpRequestor | undefined;
|
|
395
|
+
/** Per-read timeout in milliseconds (default 30 000). */
|
|
396
|
+
requestTimeoutMs?: number | undefined;
|
|
397
|
+
/** Request headers of the poll (`userAgent`, `headers`); see {@link WireOptions}. */
|
|
398
|
+
wire?: WireOptions | undefined;
|
|
399
|
+
}
|
|
400
|
+
/** What identifies the queued trade to confirm. */
|
|
401
|
+
export interface AppliedTradeInput {
|
|
402
|
+
uniqueKey: string;
|
|
403
|
+
/** The transaction id of the queued request, carried through to the result; `null` if unknown. */
|
|
404
|
+
requestTransactionId: string | null;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Polls `GET /v1/chain/apply-results/{uniqueKey}?channel=asset&contract=dex-contract` until the
|
|
408
|
+
* queued RequestTrade reaches a terminal state.
|
|
409
|
+
*
|
|
410
|
+
* Pacing: wait `initialDelayMs` (default 3 s), then read; on 404, 429, 500, 502, 503, 504 or a
|
|
411
|
+
* transport error wait with jittered exponential backoff (`pollIntervalMs` doubling to 8 s,
|
|
412
|
+
* `Retry-After` honored as seconds or an HTTP date) until `timeoutMs`. Any other status is
|
|
413
|
+
* terminal. At least one read is always made.
|
|
414
|
+
*
|
|
415
|
+
* @returns The applied trade.
|
|
416
|
+
* @throws AppliedTradeError - see its documentation for every `code`.
|
|
417
|
+
* @example
|
|
418
|
+
* ```ts
|
|
419
|
+
* const applied = await confirmAppliedTrade(
|
|
420
|
+
* { dexBackendBaseUrl: 'https://dex-backend-prod1.defi.gala.com' },
|
|
421
|
+
* { uniqueKey, requestTransactionId: null },
|
|
422
|
+
* { initialDelayMs: 0, timeoutMs: 60_000, signal: controller.signal },
|
|
423
|
+
* );
|
|
424
|
+
* ```
|
|
425
|
+
*/
|
|
426
|
+
export declare function confirmAppliedTrade(client: ApplyResultsClient, input: AppliedTradeInput, options?: ConfirmOptions): Promise<AppliedTrade>;
|
|
224
427
|
//#endregion
|
|
225
428
|
//#region src/classes/http_client.d.ts
|
|
226
429
|
declare class HttpClient {
|
|
227
430
|
private readonly httpRequestor;
|
|
228
431
|
private readonly timeoutMs;
|
|
229
|
-
|
|
230
|
-
|
|
432
|
+
private readonly wire;
|
|
433
|
+
/**
|
|
434
|
+
* Create an HTTP client around fetch or an injected requestor. `wire` selects the query
|
|
435
|
+
* encoding and the `User-Agent` (see {@link WireOptions}).
|
|
436
|
+
*/
|
|
437
|
+
constructor(httpRequestor?: HttpRequestor, timeoutMs?: number, wire?: WireOptions);
|
|
231
438
|
private sendRequest;
|
|
232
439
|
/** Send a JSON POST request and decode its response. */
|
|
233
440
|
sendPostRequest<TReturnType>(baseUrl: string, basePath: string, endpoint: string, body: unknown): Promise<TReturnType>;
|
|
@@ -262,96 +469,552 @@ export declare class Assets {
|
|
|
262
469
|
getUserAssets(ownerAddress: string, page?: number, limit?: number): Promise<UserAssetsResult>;
|
|
263
470
|
}
|
|
264
471
|
//#endregion
|
|
265
|
-
//#region src/classes/
|
|
266
|
-
/**
|
|
267
|
-
export type
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
472
|
+
//#region src/classes/signers.d.ts
|
|
473
|
+
/** The signing schemes supported by the Gala Wallet signer. */
|
|
474
|
+
export type GalaWalletScheme = 'native' | 'personal-sign';
|
|
475
|
+
/** The request surface used by an EIP-1193 browser wallet. */
|
|
476
|
+
export interface BrowserWalletProvider {
|
|
477
|
+
request(args: {
|
|
478
|
+
method: string;
|
|
479
|
+
params?: unknown[];
|
|
480
|
+
}): Promise<unknown>;
|
|
481
|
+
}
|
|
482
|
+
type SignedDto<T extends Record<string, unknown>> = T & {
|
|
483
|
+
signature: string;
|
|
273
484
|
};
|
|
274
|
-
/**
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
private readonly requestor;
|
|
285
|
-
private readonly requestTimeoutMs;
|
|
286
|
-
private readonly positionConfirmation;
|
|
287
|
-
/** Construct a submitted transaction from a successful gateway response.
|
|
485
|
+
/**
|
|
486
|
+
* A signer for complete GalaChain write bodies.
|
|
487
|
+
*
|
|
488
|
+
* Implementations return the DTO fields together with the signature that belongs in the
|
|
489
|
+
* gateway request body. Signer identity is recovered from that signature; implementations do
|
|
490
|
+
* not add signer hints, typed-data metadata, or a domain.
|
|
491
|
+
*/
|
|
492
|
+
export interface GalaChainSigner {
|
|
493
|
+
/**
|
|
494
|
+
* Signs a DTO for a named GalaChain contract method.
|
|
288
495
|
*
|
|
289
496
|
* @example
|
|
290
|
-
* ```
|
|
291
|
-
* const
|
|
292
|
-
* method: 'RequestTrade', mode: 'queued', uniqueKey: 'swap-1',
|
|
293
|
-
* transactionId: 'request-tx', result: undefined,
|
|
294
|
-
* dexBackendBaseUrl: 'https://dex.example', httpRequestor,
|
|
295
|
-
* });
|
|
497
|
+
* ```typescript
|
|
498
|
+
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
296
499
|
* ```
|
|
297
500
|
*/
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
501
|
+
signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* The `0x`-prefixed Ethereum address a Gala account is signed by, or `undefined` when the account
|
|
505
|
+
* names no key (a `client|` alias or a bare GalaChain id is not derivable from a key). Accepts
|
|
506
|
+
* `0x` plus 40 hex digits and `eth|` plus 40 hex digits, with or without `0x`; the caller's casing
|
|
507
|
+
* is kept. For {@link LazyPrivateKeySignerOptions.expectedAddress}, which should only be set for
|
|
508
|
+
* an account whose key can be checked.
|
|
509
|
+
*
|
|
510
|
+
* @example
|
|
511
|
+
* ```ts
|
|
512
|
+
* createLazyPrivateKeySigner(getKey, { expectedAddress: ethereumAddressOfAccount(account) });
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
export declare function ethereumAddressOfAccount(account: string): string | undefined;
|
|
516
|
+
/**
|
|
517
|
+
* A GalaChain native signer backed by a secp256k1 private key.
|
|
518
|
+
*
|
|
519
|
+
* Native signing produces the bare GalaChain signature format, without a personal-sign prefix
|
|
520
|
+
* or EIP-712 metadata. The private-key identity is recovered by the chain.
|
|
521
|
+
*/
|
|
522
|
+
export declare class PrivateKeySigner implements GalaChainSigner {
|
|
523
|
+
private readonly privateKey;
|
|
524
|
+
/**
|
|
525
|
+
* Creates a native signer from a hex or base64 secp256k1 private key.
|
|
314
526
|
*
|
|
315
527
|
* @example
|
|
316
|
-
* ```
|
|
317
|
-
* const
|
|
528
|
+
* ```typescript
|
|
529
|
+
* const signer = new PrivateKeySigner('1'.padStart(64, '0'));
|
|
530
|
+
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
318
531
|
* ```
|
|
319
532
|
*/
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
/** Confirm a liquidity write against the position's observable effect.
|
|
533
|
+
constructor(privateKey: string);
|
|
534
|
+
/**
|
|
535
|
+
* Signs the DTO with GalaChain native signing.
|
|
324
536
|
*
|
|
325
|
-
* @returns The position after the write, or `null` for a confirmed full close.
|
|
326
537
|
* @example
|
|
327
|
-
* ```
|
|
328
|
-
* const
|
|
538
|
+
* ```typescript
|
|
539
|
+
* const signed = await signer.signObject('RequestTrade', {
|
|
540
|
+
* token0: 'GALA',
|
|
541
|
+
* token1: 'GUSDC',
|
|
542
|
+
* fee: 3000,
|
|
543
|
+
* });
|
|
329
544
|
* ```
|
|
330
545
|
*/
|
|
331
|
-
|
|
546
|
+
signObject<T extends Record<string, unknown>>(_methodName: string, dto: T): Promise<SignedDto<T>>;
|
|
547
|
+
}
|
|
548
|
+
/** Supplies a private key at sign time: a hex/base64 string, possibly fetched asynchronously. */
|
|
549
|
+
export type PrivateKeyProvider = () => Promise<string> | string;
|
|
550
|
+
/** Options for {@link createLazyPrivateKeySigner}. */
|
|
551
|
+
export interface LazyPrivateKeySignerOptions {
|
|
552
|
+
/**
|
|
553
|
+
* When set, every signature first checks that the fetched key belongs to this account (`0x...`
|
|
554
|
+
* or the Gala `eth|0x...` / `eth|<40 hex>` form, case-insensitive) and refuses to sign otherwise
|
|
555
|
+
* (`SIGNER_ADDRESS_MISMATCH`). Use it when the key lives in a slot another surface can switch
|
|
556
|
+
* between the moment a request was approved and the moment it is signed.
|
|
557
|
+
*/
|
|
558
|
+
expectedAddress?: string | undefined;
|
|
332
559
|
}
|
|
333
560
|
/**
|
|
334
|
-
*
|
|
561
|
+
* Creates the native-signing equivalent of {@link PrivateKeySigner} for apps that must not hold a
|
|
562
|
+
* key in a long-lived object (an extension that reads its session key at sign time).
|
|
335
563
|
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
564
|
+
* `getPrivateKey` is called once per `signObject` call, never cached, never shared between calls
|
|
565
|
+
* (concurrent signatures each fetch their own key), and the normalized key bytes are zeroed
|
|
566
|
+
* before `signObject` settles, also on failure. A rejection or exception from `getPrivateKey` is
|
|
567
|
+
* passed through unchanged, so the app's own "wallet is locked" error reaches its caller; a key
|
|
568
|
+
* that is not a valid secp256k1 key string is a `VALIDATION_ERROR` (`INVALID_PRIVATE_KEY`).
|
|
569
|
+
* Signatures are byte-identical to `new PrivateKeySigner(key).signObject(...)`.
|
|
570
|
+
*
|
|
571
|
+
* A JavaScript string cannot be wiped; the provider owns the lifetime of the string it returns.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```typescript
|
|
575
|
+
* const signer = createLazyPrivateKeySigner(
|
|
576
|
+
* () => SecurityHelper.getSessionSecret(SecurityHelper.SESSION_PRIVATE_KEY_KEY),
|
|
577
|
+
* { expectedAddress: account.address },
|
|
578
|
+
* );
|
|
579
|
+
* const gswap = new GSwap({ signer });
|
|
580
|
+
* ```
|
|
341
581
|
*/
|
|
342
|
-
export
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
582
|
+
export declare function createLazyPrivateKeySigner(getPrivateKey: PrivateKeyProvider, options?: LazyPrivateKeySignerOptions): GalaChainSigner;
|
|
583
|
+
/**
|
|
584
|
+
* A Gala Wallet signer using native GalaChain signing, with an opt-in personal-sign mode.
|
|
585
|
+
*
|
|
586
|
+
* The selected Ethereum account is passed to Gala Wallet. There is NO automatic fallback: a
|
|
587
|
+
* wallet that rejects `native` surfaces its error to the caller, because the only alternative,
|
|
588
|
+
* `personal-sign`, silently recovers a phantom signer on every released Gala Wallet.
|
|
589
|
+
*
|
|
590
|
+
* `scheme: 'personal-sign'` calls
|
|
591
|
+
* `gala_signChainDto([serialize({ ...dto, prefix }), walletAddress, methodName])` and REQUIRES
|
|
592
|
+
* a wallet build that contains wallet_extension commit 3ad7ae6 (strips the embedded `prefix`
|
|
593
|
+
* field and hashes `prefix` + the prefix-less canonical body, the chain's scheme). Wallets
|
|
594
|
+
* released before that fix hash the string with the `prefix` field still inside it and the
|
|
595
|
+
* signature recovers to an address nobody holds, so only opt in once the fixed wallet is
|
|
596
|
+
* released. See SIGNING-PARITY.md.
|
|
597
|
+
*/
|
|
598
|
+
export declare class GalaWalletSigner implements GalaChainSigner {
|
|
599
|
+
/** The wallet address supplied to Gala Wallet for each signing request. */
|
|
600
|
+
readonly walletAddress: string;
|
|
601
|
+
/** The signing scheme used for every request; it never changes after construction. */
|
|
602
|
+
readonly scheme: GalaWalletScheme;
|
|
603
|
+
/**
|
|
604
|
+
* Creates a Gala Wallet signer.
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* ```typescript
|
|
608
|
+
* const signer = new GalaWalletSigner('0x0123456789012345678901234567890123456789');
|
|
609
|
+
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
610
|
+
* ```
|
|
611
|
+
*
|
|
612
|
+
* @param walletAddress - The account passed to Gala Wallet as the signer address. An Ethereum
|
|
613
|
+
* account is `0x` plus 40 hex digits (Gala Wallet's `eth|...` form is normalized to it and held
|
|
614
|
+
* to the same check); a GalaChain id is `client|` plus 24 hex digits, or the bare 24 hex digits
|
|
615
|
+
* frontend_v2 keeps for a direct `client|` login, and is passed through unchanged.
|
|
616
|
+
* @param options - Select native signing (default) or personal-sign explicitly.
|
|
617
|
+
* `'personal-sign'` requires a Gala Wallet build with wallet_extension commit 3ad7ae6.
|
|
618
|
+
* `selectAddress` is the identity (`client|...` / `eth|...`) Gala Wallet is switched to with
|
|
619
|
+
* `window.gala.setAddress` before every signature, when the wallet offers it.
|
|
620
|
+
*/
|
|
621
|
+
constructor(walletAddress: string, options?: {
|
|
622
|
+
scheme?: GalaWalletScheme | undefined;
|
|
623
|
+
selectAddress?: string | undefined;
|
|
624
|
+
});
|
|
625
|
+
/** The identity Gala Wallet is switched to before each signature, if one was given. */
|
|
626
|
+
readonly selectAddress: string | undefined;
|
|
627
|
+
/**
|
|
628
|
+
* Signs a DTO through `gala_signChainDto`.
|
|
629
|
+
*
|
|
630
|
+
* @example
|
|
631
|
+
* ```typescript
|
|
632
|
+
* const signed = await signer.signObject('AddLiquidity', {
|
|
633
|
+
* token0: 'GALA',
|
|
634
|
+
* token1: 'GUSDC',
|
|
635
|
+
* tickLower: -60,
|
|
636
|
+
* tickUpper: 60,
|
|
637
|
+
* });
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* A personal-sign signer for MetaMask and other EIP-1193 browser wallets.
|
|
644
|
+
*
|
|
645
|
+
* The chain recovers this signature using the EIP-191 wrap applied by the wallet to
|
|
646
|
+
* `personal_sign`. This is the browser-wallet path used by the v2 frontend and resolves the
|
|
647
|
+
* bare `eth|` identity.
|
|
648
|
+
*/
|
|
649
|
+
export declare class BrowserWalletSigner implements GalaChainSigner {
|
|
650
|
+
private readonly provider;
|
|
651
|
+
/**
|
|
652
|
+
* Creates a browser-wallet signer.
|
|
653
|
+
*
|
|
654
|
+
* Defaults to `personal_sign` — unchanged from every existing integration, since it only ever
|
|
655
|
+
* resolves the bare `eth|` identity and changing that silently would be a real behavior
|
|
656
|
+
* break for anyone already depending on it. Pass `{ scheme: 'eip712' }` to correctly resolve
|
|
657
|
+
* a registered `client|` alias instead, for `RequestTrade`/`AddLiquidity`/`RemoveLiquidity`/
|
|
658
|
+
* `CollectPositionFees` (`EIP712_CAPABLE_METHODS`) — `CreatePool` and any other method still
|
|
659
|
+
* falls back to `personal_sign` even in `'eip712'` mode, since its EIP-712 signing is a
|
|
660
|
+
* separate, unsolved chain-side problem.
|
|
661
|
+
*
|
|
662
|
+
* @example
|
|
663
|
+
* ```typescript
|
|
664
|
+
* const signer = new BrowserWalletSigner(window.ethereum, '0x0123456789012345678901234567890123456789');
|
|
665
|
+
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
666
|
+
* ```
|
|
667
|
+
* @example
|
|
668
|
+
* ```typescript
|
|
669
|
+
* // Correctly resolves a registered client| alias instead of the bare eth| address.
|
|
670
|
+
* const signer = new BrowserWalletSigner(window.ethereum, walletAddress, { scheme: 'eip712' });
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
constructor(provider: BrowserWalletProvider, walletAddress: string, options?: {
|
|
674
|
+
scheme?: 'personal-sign' | 'eip712';
|
|
675
|
+
});
|
|
676
|
+
readonly walletAddress: string;
|
|
677
|
+
private readonly scheme;
|
|
678
|
+
/**
|
|
679
|
+
* Signs the DTO with `eth_signTypedData_v4` (when constructed with `{ scheme: 'eip712' }` and
|
|
680
|
+
* `methodName` is in `EIP712_CAPABLE_METHODS`) or the EIP-1193 `personal_sign` method
|
|
681
|
+
* (otherwise — the default).
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* ```typescript
|
|
685
|
+
* const signed = await signer.signObject('RequestTrade', {
|
|
686
|
+
* token0: 'GALA',
|
|
687
|
+
* token1: 'GUSDC',
|
|
688
|
+
* fee: 3000,
|
|
689
|
+
* });
|
|
690
|
+
* ```
|
|
691
|
+
*/
|
|
692
|
+
signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;
|
|
693
|
+
}
|
|
694
|
+
//#endregion
|
|
695
|
+
//#region src/classes/dex_fees.d.ts
|
|
696
|
+
/** DEX methods the backend accepts a fee quote for (its allow-list enumerates the same six). */
|
|
697
|
+
export declare const DEX_FEE_METHODS: readonly ['Swap', 'RequestTrade', 'AddLiquidity', 'RemoveLiquidity', 'CollectPositionFees', 'CreatePool'];
|
|
698
|
+
export type DexFeeMethod = (typeof DEX_FEE_METHODS)[number];
|
|
699
|
+
/** Which pool contract the DTO being quoted targets: legacy (V3) or current (GalaChainDex). */
|
|
700
|
+
export type DexFeeContract = 'dexv3-contract' | 'dex-contract';
|
|
701
|
+
/** The chain method name the signed DryRun wrapper is signed under. */
|
|
702
|
+
export declare const DRY_RUN_METHOD = "DryRun";
|
|
703
|
+
/** `uniqueKey` prefix of the DryRun WRAPPER (distinct from the inner DTO's key). */
|
|
704
|
+
export declare const DRY_RUN_UNIQUE_KEY_PREFIX = "galaconnect-operation-";
|
|
705
|
+
/** True when `method` is a DEX method a fee can be quoted for. */
|
|
706
|
+
export declare function isDexFeeMethod(method: unknown): method is DexFeeMethod;
|
|
707
|
+
/** Current-contract typed DEX messages use trading symbols instead of TokenClassKey objects. */
|
|
708
|
+
export declare function isCurrentContractDexMessage(message: Record<string, unknown> | null | undefined, method: unknown): boolean;
|
|
709
|
+
/**
|
|
710
|
+
* The backend's response. It ALWAYS carries a usable `fees[0].feeInGala`: the backend decides what
|
|
711
|
+
* to serve when the chain cannot price the operation, so the client never invents a fee.
|
|
712
|
+
*
|
|
713
|
+
* `source` is informational: `'dry-run'` is simulated on chain and authoritative (possibly a
|
|
714
|
+
* legitimate `'0'`), `'default'` means the chain could not price it and the platform default was
|
|
715
|
+
* served.
|
|
716
|
+
*/
|
|
717
|
+
export interface DexFeeQuote {
|
|
718
|
+
fees: Array<{
|
|
719
|
+
feeInGala: string;
|
|
720
|
+
}>;
|
|
721
|
+
source: 'dry-run' | 'default';
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Reduces an EIP-712 approval `message` to the DTO the chain actually receives: drops the signing
|
|
725
|
+
* envelope (`signature`, `prefix`, `types`, `domain`) and transport metadata (`trace`).
|
|
726
|
+
*/
|
|
727
|
+
export declare function toChainDto(message: Record<string, unknown>): Record<string, unknown>;
|
|
728
|
+
/**
|
|
729
|
+
* Signs the DryRun WRAPPER the gateway accepts for every contract:
|
|
730
|
+
* `{ callerPublicKey, method, dto: <inner DTO object>, uniqueKey, signature }`. The inner DTO
|
|
731
|
+
* travels unsigned and as an object; no `signerPublicKey` is sent because the signature already
|
|
732
|
+
* recovers it (the gateway rejects it as REDUNDANT_SIGNER_PUBLIC_KEY). The wrapper carries its own
|
|
733
|
+
* `uniqueKey`, distinct from the DTO's.
|
|
734
|
+
*/
|
|
735
|
+
export declare function buildDryRunWrapper(signer: GalaChainSigner, callerPublicKey: string, method: string, dto: Record<string, unknown>, uniqueKeyPrefix?: string): Promise<Record<string, unknown>>;
|
|
736
|
+
/** The transport and backend a fee quote reads from. */
|
|
737
|
+
export interface DexFeesClient {
|
|
738
|
+
/** Swap backend origin, e.g. `https://dex-backend-prod1.defi.gala.com`. */
|
|
739
|
+
dexBackendBaseUrl: string;
|
|
740
|
+
/** Defaults to the global `fetch`. */
|
|
741
|
+
httpRequestor?: HttpRequestor | undefined;
|
|
742
|
+
/** Per-request timeout in milliseconds (default 30 000). */
|
|
743
|
+
requestTimeoutMs?: number | undefined;
|
|
744
|
+
/**
|
|
745
|
+
* Request headers of the fee POST (`userAgent`, `headers`); see {@link WireOptions}. The SDK's
|
|
746
|
+
* `Accept: application/json` is a default that `wire.headers` may replace.
|
|
747
|
+
*/
|
|
748
|
+
wire?: WireOptions | undefined;
|
|
749
|
+
}
|
|
750
|
+
/** Options for a single quote. */
|
|
751
|
+
export interface DexFeeQuoteOptions {
|
|
752
|
+
/** GalaChain channel. Default `asset`. */
|
|
753
|
+
channel?: string | undefined;
|
|
754
|
+
/**
|
|
755
|
+
* Contract the DTO targets. Default `dexv3-contract` (what every legacy caller quotes against);
|
|
756
|
+
* a current-contract operation must pass `dex-contract` explicitly.
|
|
757
|
+
*/
|
|
758
|
+
contract?: DexFeeContract | undefined;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Network-fee quote for GalaChain DEX methods, derived from a server-side DryRun.
|
|
762
|
+
*
|
|
763
|
+
* The client only SIGNS the DryRun wrapper (with whatever {@link GalaChainSigner} it is given) and
|
|
764
|
+
* the backend forwards it to the gateway, where the simulated writes carry the fee; the backend
|
|
765
|
+
* never holds a key. Intended for wallets: the DTO quoted is the typed message a dApp handed over.
|
|
766
|
+
*
|
|
767
|
+
* @example
|
|
768
|
+
* ```ts
|
|
769
|
+
* const fees = new DexFees({ dexBackendBaseUrl }, new PrivateKeySigner(sessionKey));
|
|
770
|
+
* const quote = await fees.quote(publicKey, 'RequestTrade', toChainDto(message), {
|
|
771
|
+
* contract: 'dex-contract',
|
|
772
|
+
* });
|
|
773
|
+
* const feeInGala = quote?.fees[0]?.feeInGala;
|
|
774
|
+
* ```
|
|
775
|
+
*/
|
|
776
|
+
export declare class DexFees {
|
|
777
|
+
private readonly signer;
|
|
778
|
+
private readonly requestor;
|
|
779
|
+
private readonly baseUrl;
|
|
780
|
+
private readonly requestTimeoutMs;
|
|
781
|
+
private readonly wire;
|
|
782
|
+
constructor(client: DexFeesClient, signer: GalaChainSigner | undefined);
|
|
783
|
+
/**
|
|
784
|
+
* Quotes the network fee for `method` applied to `message`. The message is reduced with
|
|
785
|
+
* {@link toChainDto} first, so an EIP-712 approval message can be passed as is.
|
|
786
|
+
*
|
|
787
|
+
* Resolves `null` when the BACKEND could not be reached or answered unusably (offline, 4xx/5xx,
|
|
788
|
+
* malformed body): a transport outcome, not a fee. Deciding what to charge when the chain is
|
|
789
|
+
* silent is the backend's job (it serves `source: 'default'`), so the client never substitutes
|
|
790
|
+
* a fee of its own, with ONE exception that mirrors the wallet: a `dex-contract` quote answered
|
|
791
|
+
* 403 or 404 means the contract has no fee route yet and resolves `{ source: 'default', '0' }`.
|
|
792
|
+
* Never throws on transport, so a fee lookup cannot block or break a signing screen.
|
|
793
|
+
*
|
|
794
|
+
* @throws GSwapSDKError NO_SIGNER when constructed without a signer; any error the signer
|
|
795
|
+
* throws (for example a locked wallet) propagates unchanged.
|
|
796
|
+
*/
|
|
797
|
+
quote(callerPublicKey: string, method: DexFeeMethod, message: Record<string, unknown>, options?: DexFeeQuoteOptions): Promise<DexFeeQuote | null>;
|
|
798
|
+
}
|
|
799
|
+
//#endregion
|
|
800
|
+
//#region src/classes/shadow_submit.d.ts
|
|
801
|
+
/** The raw answer to a shadow (dark) write: every HTTP status resolves. */
|
|
802
|
+
export interface ShadowSubmitResult {
|
|
803
|
+
httpStatus: number;
|
|
804
|
+
/** Parsed JSON body, or the raw text when the body was not JSON. */
|
|
805
|
+
body: unknown;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Machine-readable codes defi-backend returns in a shadow failure body (`{ code, message }`, with
|
|
809
|
+
* no `statusCode`; the HTTP status carries the number).
|
|
810
|
+
*
|
|
811
|
+
* - `SHADOW_UNAVAILABLE` (503): marking failed or infra not configured; retryable. Never fall back
|
|
812
|
+
* silently to a public swap.
|
|
813
|
+
* - `SHADOW_DISABLED` (400): the feature is off for this environment.
|
|
814
|
+
* - `SHADOW_UNSUPPORTED_TYPE` (400): shadow requested on a non-swap method.
|
|
815
|
+
* - `SHADOW_RELAY_REJECTED`: terminal business rejection (slippage, balance, ...), not retryable;
|
|
816
|
+
* `message` is the gateway's verbatim string.
|
|
817
|
+
*/
|
|
818
|
+
export type ShadowSubmitCode = 'SHADOW_UNAVAILABLE' | 'SHADOW_DISABLED' | 'SHADOW_UNSUPPORTED_TYPE' | 'SHADOW_RELAY_REJECTED';
|
|
819
|
+
/** The normalized outcome of a shadow write. */
|
|
820
|
+
export type ShadowSubmitOutcome = {
|
|
821
|
+
ok: true;
|
|
822
|
+
/** The request transaction id (`''` when the gateway gave none). */
|
|
823
|
+
bundleId: string;
|
|
824
|
+
/** Present for a queued RequestTrade: confirm with `confirmAppliedTrade`. */
|
|
825
|
+
queued?: {
|
|
826
|
+
uniqueKey: string;
|
|
827
|
+
requestTransactionId: string | null;
|
|
828
|
+
};
|
|
829
|
+
} | {
|
|
830
|
+
ok: false;
|
|
831
|
+
kind: 'unavailable';
|
|
832
|
+
retryable: true;
|
|
833
|
+
} | {
|
|
834
|
+
ok: false;
|
|
835
|
+
kind: 'disabled';
|
|
836
|
+
retryable: false;
|
|
837
|
+
} | {
|
|
838
|
+
ok: false;
|
|
839
|
+
kind: 'rejected';
|
|
840
|
+
retryable: false;
|
|
841
|
+
message: string;
|
|
842
|
+
} | {
|
|
843
|
+
ok: false;
|
|
844
|
+
kind: 'unknown';
|
|
845
|
+
retryable: false;
|
|
846
|
+
};
|
|
847
|
+
type ShadowFailureKind = Exclude<ShadowSubmitOutcome, {
|
|
848
|
+
ok: true;
|
|
849
|
+
}>['kind'];
|
|
850
|
+
/** Maps an HTTP status to a failure kind: 503 retryable, 400 disabled, anything else unknown. */
|
|
851
|
+
export declare function classifyShadowSubmitStatus(status: number): ShadowFailureKind;
|
|
852
|
+
/**
|
|
853
|
+
* Prefers the body `code` (stable across status remaps) and falls back to the HTTP status.
|
|
854
|
+
* `SHADOW_UNAVAILABLE` is the only retryable case; `SHADOW_RELAY_REJECTED` is a terminal gateway
|
|
855
|
+
* rejection; the two other 400 codes and any unknown 400 map to "disabled".
|
|
856
|
+
*/
|
|
857
|
+
export declare function classifyShadowSubmitError(status: number, code?: string): ShadowFailureKind;
|
|
858
|
+
/**
|
|
859
|
+
* Normalizes a shadow write's raw answer.
|
|
860
|
+
*
|
|
861
|
+
* A 2xx envelope with `error === false` is a success when it is a queued RequestTrade that
|
|
862
|
+
* acknowledges the EXACT signed `uniqueKey`, or a synchronous (`mode: 'sync'`) liquidity write.
|
|
863
|
+
* Everything else is classified as a failure from the status and the body's `code`.
|
|
864
|
+
*
|
|
865
|
+
* @throws GSwapSDKError INVALID_GATEWAY_RESPONSE when a RequestTrade success does not queue the
|
|
866
|
+
* signed `uniqueKey` (a synchronous or mismatched answer must never be accepted as a swap).
|
|
867
|
+
*/
|
|
868
|
+
export declare function readShadowSubmitOutcome(method: string, signedBody: Record<string, unknown>, result: ShadowSubmitResult): ShadowSubmitOutcome;
|
|
869
|
+
//#endregion
|
|
870
|
+
//#region src/utils/submit_state.d.ts
|
|
871
|
+
/**
|
|
872
|
+
* What a write's gateway answer says about the write, as one vocabulary for every app.
|
|
873
|
+
*
|
|
874
|
+
* The gateway answers `{ status, message, error, data }`. `data.mode` is `'sync'` for a liquidity
|
|
875
|
+
* write (its executed chain result is in `data.result`) and `'queued'` for a RequestTrade
|
|
876
|
+
* acknowledgement (accepted, NOT executed: the outcome is read from apply-results with
|
|
877
|
+
* `confirm()`). `error: true` is the gateway refusing the write.
|
|
878
|
+
*
|
|
879
|
+
* A {@link SubmittedTransaction} only exists for an answer the SDK accepted, so its
|
|
880
|
+
* {@link SubmitStatus} is `'executed'` or `'queued'`; a refused answer is a thrown
|
|
881
|
+
* {@link GSwapSDKError}. The predicates below classify a RAW envelope instead, for an app that
|
|
882
|
+
* holds one (`SubmittedTransaction.envelope`, `GSwapSDKError.body`, a stored answer) and for the
|
|
883
|
+
* answers that never became a transaction. They reproduce frontend_v2's `isV2SubmitSuccess` /
|
|
884
|
+
* `isV2SubmitQueued` / `isV2SubmitRejected` exactly, so the app can delete its own copies.
|
|
885
|
+
*/
|
|
886
|
+
/** The state of an accepted write: executed on chain (`mode: 'sync'`) or queued (`mode: 'queued'`). */
|
|
887
|
+
export type SubmitStatus = 'executed' | 'queued';
|
|
888
|
+
/**
|
|
889
|
+
* How a raw gateway envelope classifies:
|
|
890
|
+
*
|
|
891
|
+
* - `'executed'`: `error === false` and `data.mode === 'sync'` (the executed result came back).
|
|
892
|
+
* - `'queued'`: `error === false`, `data.mode === 'queued'` and `data.uniqueKey` is a string.
|
|
893
|
+
* - `'rejected'`: no envelope at all, or `error === true`: a DEFINITE failure.
|
|
894
|
+
* - `'unconfirmed'`: anything else (`error: false` with another or no `mode`, a queued answer
|
|
895
|
+
* with no `uniqueKey`, an envelope with no boolean `error`): accepted, outcome not known. It is
|
|
896
|
+
* NOT a rejection and must not be shown as one.
|
|
897
|
+
*
|
|
898
|
+
* The four are mutually exclusive and exhaustive.
|
|
899
|
+
*/
|
|
900
|
+
export type SubmitClassification = SubmitStatus | 'rejected' | 'unconfirmed';
|
|
901
|
+
/** True when the envelope is a definite failure: absent, or `error === true`. */
|
|
902
|
+
export declare function isSubmitRejected(envelope: unknown): boolean;
|
|
903
|
+
/**
|
|
904
|
+
* True when the envelope carries an executed result: `error === false` and `data.mode === 'sync'`.
|
|
905
|
+
* A queued RequestTrade acknowledgement is deliberately NOT executed: its outcome is not known
|
|
906
|
+
* until apply-results resolves.
|
|
907
|
+
*/
|
|
908
|
+
export declare function isSubmitExecuted(envelope: unknown): boolean;
|
|
909
|
+
/** True when the envelope acknowledges a `uniqueKey` as queued (`data.mode === 'queued'`). */
|
|
910
|
+
export declare function isSubmitQueued(envelope: unknown): boolean;
|
|
911
|
+
/** Classifies a raw gateway envelope; see {@link SubmitClassification}. */
|
|
912
|
+
export declare function classifySubmitEnvelope(envelope: unknown): SubmitClassification;
|
|
913
|
+
//#endregion
|
|
914
|
+
//#region src/classes/submitted_transaction.d.ts
|
|
915
|
+
/** Result of one position-confirmation poll. */
|
|
916
|
+
export type PositionConfirmationResult = {
|
|
917
|
+
confirmed: true;
|
|
918
|
+
position: Position | null;
|
|
919
|
+
} | {
|
|
920
|
+
confirmed: false;
|
|
921
|
+
position?: Position | null;
|
|
922
|
+
};
|
|
923
|
+
/** A submitted v2 transaction whose confirmation mode is explicit in the gateway response. */
|
|
924
|
+
export declare class SubmittedTransaction<TConfirmation = AppliedTrade | Position | null> {
|
|
925
|
+
readonly method: string;
|
|
926
|
+
readonly uniqueKey: string;
|
|
927
|
+
readonly transactionId: string | null;
|
|
928
|
+
readonly blockNumber: number | null;
|
|
929
|
+
/** The gateway's `data.mode`: `'sync'` (executed, `result` is the chain result) or `'queued'`. */
|
|
930
|
+
readonly mode: 'sync' | 'queued';
|
|
931
|
+
/**
|
|
932
|
+
* What the gateway's answer established: `'executed'` for `mode: 'sync'`, `'queued'` for
|
|
933
|
+
* `mode: 'queued'` (accepted, NOT executed: `await confirm()` for the outcome). A refused answer
|
|
934
|
+
* never becomes a transaction, so there is no `'rejected'` here; see {@link classifySubmitEnvelope}
|
|
935
|
+
* for classifying a raw envelope.
|
|
936
|
+
*/
|
|
937
|
+
readonly status: SubmitStatus;
|
|
938
|
+
/** The synchronous gateway result, or `undefined` when `mode === 'queued'`. */
|
|
939
|
+
readonly result: unknown;
|
|
940
|
+
/**
|
|
941
|
+
* The gateway's whole JSON answer as it came (`{ status, message, error, data }`), for an app
|
|
942
|
+
* that hands the backend's own envelope to its callers; `undefined` for a transaction built from
|
|
943
|
+
* a uniqueKey alone.
|
|
944
|
+
*/
|
|
945
|
+
readonly envelope: unknown;
|
|
946
|
+
private readonly backendBaseUrl;
|
|
947
|
+
private readonly requestor;
|
|
948
|
+
private readonly requestTimeoutMs;
|
|
949
|
+
private readonly wire;
|
|
950
|
+
private readonly positionConfirmation;
|
|
951
|
+
/** Construct a submitted transaction from a successful gateway response.
|
|
952
|
+
*
|
|
953
|
+
* @example
|
|
954
|
+
* ```ts
|
|
955
|
+
* const transaction = new SubmittedTransaction({
|
|
956
|
+
* method: 'RequestTrade', mode: 'queued', uniqueKey: 'swap-1',
|
|
957
|
+
* transactionId: 'request-tx', result: undefined,
|
|
958
|
+
* dexBackendBaseUrl: 'https://dex.example', httpRequestor,
|
|
959
|
+
* });
|
|
960
|
+
* ```
|
|
961
|
+
*/
|
|
962
|
+
constructor(options: {
|
|
963
|
+
method: string;
|
|
964
|
+
uniqueKey: string;
|
|
965
|
+
transactionId: string | null;
|
|
966
|
+
mode: 'sync' | 'queued';
|
|
967
|
+
result: unknown;
|
|
968
|
+
dexBackendBaseUrl: string;
|
|
969
|
+
httpRequestor: HttpRequestor;
|
|
970
|
+
blockNumber?: number | null | undefined;
|
|
971
|
+
envelope?: unknown;
|
|
972
|
+
requestTimeoutMs?: number | undefined;
|
|
973
|
+
/** Wire options of the apply-results polls `confirm()` makes. */
|
|
974
|
+
wire?: WireOptions | undefined;
|
|
975
|
+
positionConfirmation?: ((signal: AbortSignal) => Promise<PositionConfirmationResult>) | undefined;
|
|
976
|
+
});
|
|
977
|
+
/** Confirm a queued RequestTrade or prove the affected position for a liquidity write.
|
|
978
|
+
*
|
|
979
|
+
* For RequestTrade, calling this method is required to learn the outcome: the queued
|
|
980
|
+
* acknowledgement proves acceptance, not execution.
|
|
981
|
+
*
|
|
982
|
+
* @example
|
|
983
|
+
* ```ts
|
|
984
|
+
* const applied = await submitted.confirm({ initialDelayMs: 3_000 });
|
|
985
|
+
* ```
|
|
986
|
+
*/
|
|
987
|
+
confirm(options?: ConfirmOptions): Promise<TConfirmation>;
|
|
988
|
+
private confirmApplied;
|
|
989
|
+
/** Confirm a liquidity write against the position's observable effect.
|
|
990
|
+
*
|
|
991
|
+
* @returns The position after the write, or `null` for a confirmed full close.
|
|
992
|
+
* @example
|
|
993
|
+
* ```ts
|
|
994
|
+
* const position = await submitted.confirm({ timeoutMs: 60_000 });
|
|
995
|
+
* ```
|
|
996
|
+
*/
|
|
997
|
+
private confirmPosition;
|
|
998
|
+
}
|
|
999
|
+
//#endregion
|
|
1000
|
+
//#region src/classes/gateway.d.ts
|
|
1001
|
+
/** Options for a chain-gateway client. */
|
|
1002
|
+
export interface ChainGatewayOptions {
|
|
1003
|
+
dexBackendBaseUrl: string;
|
|
352
1004
|
httpRequestor?: HttpRequestor | undefined;
|
|
353
1005
|
walletAddress?: string | undefined;
|
|
1006
|
+
/**
|
|
1007
|
+
* Timeout of every gateway request in milliseconds (default 30 000); also the per-read timeout
|
|
1008
|
+
* of the services built on this gateway and of `confirm()`. `Infinity` arms no timer, for an
|
|
1009
|
+
* app whose HTTP stack owns request lifetimes.
|
|
1010
|
+
*/
|
|
354
1011
|
chainCallTimeoutMs?: number | undefined;
|
|
1012
|
+
/**
|
|
1013
|
+
* Wire format of every request of this gateway and of the services built on it: the headers
|
|
1014
|
+
* (`userAgent`, `headers`) of reads AND of the POSTs that submit writes, and the query encoding
|
|
1015
|
+
* of reads. `X-Wallet-Address` and `X-Shadow` always win over a same-named `wire.headers` entry.
|
|
1016
|
+
*/
|
|
1017
|
+
wire?: WireOptions | undefined;
|
|
355
1018
|
}
|
|
356
1019
|
/** Optional attribution and operation-specific confirmation hooks for a write. */
|
|
357
1020
|
export interface ChainSubmitOptions {
|
|
@@ -365,11 +1028,35 @@ export declare class ChainGateway {
|
|
|
365
1028
|
private readonly chainCallTimeoutMs;
|
|
366
1029
|
readonly requestTimeoutMs: number;
|
|
367
1030
|
readonly dexBackendBaseUrl: string;
|
|
1031
|
+
/** Wire format shared by the read services built on this gateway. */
|
|
1032
|
+
readonly wire: WireOptions;
|
|
368
1033
|
/** Create a chain gateway client. */
|
|
369
1034
|
constructor(options: ChainGatewayOptions);
|
|
370
1035
|
/** Submit a signed v2 DTO through the chain gateway. */
|
|
371
1036
|
submit(method: 'RequestTrade', signedBody: Record<string, unknown>, options?: ChainSubmitOptions): Promise<SubmittedTransaction<AppliedTrade>>;
|
|
372
1037
|
submit(method: string, signedBody: Record<string, unknown>, options?: ChainSubmitOptions): Promise<SubmittedTransaction<Position | null>>;
|
|
1038
|
+
/**
|
|
1039
|
+
* Submit a signed v2 DTO as a SHADOW (dark) write: the same route and body as {@link submit},
|
|
1040
|
+
* plus `X-Wallet-Address` and `X-Shadow: true`, so defi-backend marks the transaction private
|
|
1041
|
+
* before it reaches the contract. The wallet address is required (the backend resolves the
|
|
1042
|
+
* owner from it).
|
|
1043
|
+
*
|
|
1044
|
+
* Unlike `submit`, EVERY HTTP status resolves: the result is the raw `{ httpStatus, body }`,
|
|
1045
|
+
* because shadow failures are classified from the status together with the body's `code`
|
|
1046
|
+
* (`SHADOW_UNAVAILABLE`, `SHADOW_DISABLED`, `SHADOW_UNSUPPORTED_TYPE`, `SHADOW_RELAY_REJECTED`);
|
|
1047
|
+
* see `readShadowSubmitOutcome`. Only a transport failure rejects, and a timeout rejects
|
|
1048
|
+
* with `SUBMISSION_OUTCOME_UNKNOWN`.
|
|
1049
|
+
*
|
|
1050
|
+
* @example
|
|
1051
|
+
* ```ts
|
|
1052
|
+
* const result = await gateway.submitShadow('RequestTrade', signedDto, { walletAddress });
|
|
1053
|
+
* const outcome = readShadowSubmitOutcome('RequestTrade', signedDto, result);
|
|
1054
|
+
* ```
|
|
1055
|
+
*/
|
|
1056
|
+
submitShadow(method: string, signedBody: Record<string, unknown>, options?: ChainSubmitOptions): Promise<ShadowSubmitResult>;
|
|
1057
|
+
private writeUrl;
|
|
1058
|
+
/** POSTs a signed body; a timeout means the outcome is unknown, never "not submitted". */
|
|
1059
|
+
private post;
|
|
373
1060
|
/** Expose the requestor for sibling read services that share this gateway transport. */
|
|
374
1061
|
get httpRequestor(): HttpRequestor;
|
|
375
1062
|
}
|
|
@@ -390,6 +1077,20 @@ export interface GdexStreamConfig {
|
|
|
390
1077
|
* global `WebSocket` (pass the one from the `ws` package).
|
|
391
1078
|
*/
|
|
392
1079
|
webSocketImpl?: unknown;
|
|
1080
|
+
/**
|
|
1081
|
+
* Presents `x-api-key` on the WebSocket upgrade request, which defi-backend uses to serve the
|
|
1082
|
+
* PRIVILEGED view (shadow swaps with the wallet unredacted). Without it, or with a wrong key, the
|
|
1083
|
+
* connection is simply public: the server never says whether a privileged mode exists.
|
|
1084
|
+
*
|
|
1085
|
+
* It must travel as an HTTP header, because the server reads no other credential, and a browser
|
|
1086
|
+
* `WebSocket` cannot set headers. So this option needs a constructor that accepts them as its
|
|
1087
|
+
* third argument (`{ headers }`): the `ws` package on Node.js, or React Native's built-in
|
|
1088
|
+
* `WebSocket`. It therefore REQUIRES `webSocketImpl` (the platform default is never assumed to
|
|
1089
|
+
* honor headers, and a key that is silently dropped would look like a working privileged
|
|
1090
|
+
* connection); the constructor throws otherwise. Use it from server-side code only: a key
|
|
1091
|
+
* shipped inside a browser or app bundle is not a secret. Browser clients stay public.
|
|
1092
|
+
*/
|
|
1093
|
+
apiKey?: string | undefined;
|
|
393
1094
|
}
|
|
394
1095
|
/** The channels of the realtime stream. */
|
|
395
1096
|
export type GdexChannel = 'pool' | 'balance' | 'poolCreated' | 'swap' | 'liquidity' | 'blocks';
|
|
@@ -482,6 +1183,7 @@ export declare class GdexStreamError extends Error {
|
|
|
482
1183
|
export declare class GdexStreamService {
|
|
483
1184
|
private readonly url;
|
|
484
1185
|
private readonly requestTimeoutMs;
|
|
1186
|
+
private readonly apiKey;
|
|
485
1187
|
private readonly webSocketConstructor;
|
|
486
1188
|
private readonly backoff;
|
|
487
1189
|
private socket;
|
|
@@ -502,6 +1204,7 @@ export declare class GdexStreamService {
|
|
|
502
1204
|
isConnected(): boolean;
|
|
503
1205
|
/** Raw JSON-RPC escape hatch. */
|
|
504
1206
|
request<T = unknown>(method: string, params?: Record<string, unknown>): Promise<T>;
|
|
1207
|
+
private send;
|
|
505
1208
|
serverInfo(): Promise<Record<string, unknown>>;
|
|
506
1209
|
ping(): Promise<{
|
|
507
1210
|
pong: boolean;
|
|
@@ -595,13 +1298,31 @@ export declare const TICK_SPACING_BY_FEE: Readonly<Record<FEE_TIER, number>>;
|
|
|
595
1298
|
/** All fee tiers supported by the current GalaChainDex contract. */
|
|
596
1299
|
export declare const ALL_FEE_TIERS: readonly FEE_TIER[];
|
|
597
1300
|
//#endregion
|
|
598
|
-
//#region src/
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
1301
|
+
//#region src/utils/lenient.d.ts
|
|
1302
|
+
/** One row of a list answer that the SDK skipped because it was not usable. */
|
|
1303
|
+
interface InvalidEntry {
|
|
1304
|
+
/** Which read the row came from. */
|
|
1305
|
+
source: 'pools' | 'symbols' | 'positions';
|
|
1306
|
+
/** Position of the row in the answer's array. */
|
|
1307
|
+
index: number;
|
|
1308
|
+
/** The row exactly as the backend sent it. */
|
|
1309
|
+
entry: unknown;
|
|
1310
|
+
/** Why it was skipped, in words. */
|
|
1311
|
+
reason: string;
|
|
604
1312
|
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Called once per skipped row, in order, before the read resolves. It is a diagnostics hook: what it
|
|
1315
|
+
* does, or throws, never changes the result of the read.
|
|
1316
|
+
*/
|
|
1317
|
+
type InvalidEntryHandler = (invalid: InvalidEntry) => void;
|
|
1318
|
+
/** The outcome of reading one row. */
|
|
1319
|
+
type EntryParse<T> = {
|
|
1320
|
+
ok: true;
|
|
1321
|
+
value: T;
|
|
1322
|
+
} | {
|
|
1323
|
+
ok: false;
|
|
1324
|
+
reason: string;
|
|
1325
|
+
};
|
|
605
1326
|
//#endregion
|
|
606
1327
|
//#region src/utils/ordering.d.ts
|
|
607
1328
|
/** A symbol or a GalaChain token class key accepted by v2 operations. */
|
|
@@ -642,15 +1363,26 @@ export declare function parseTokenClassKey(tokenClassKey: TokenRef): GalaChainTo
|
|
|
642
1363
|
/** Symbol registry client for the current GalaChainDex contract. */
|
|
643
1364
|
export declare class Symbols {
|
|
644
1365
|
private readonly gateway;
|
|
1366
|
+
private readonly options;
|
|
645
1367
|
private cachedSymbols;
|
|
646
1368
|
private cachedAt;
|
|
647
1369
|
private refreshInFlight;
|
|
648
1370
|
private readonly http;
|
|
649
|
-
/**
|
|
1371
|
+
/**
|
|
1372
|
+
* Create a symbol service backed by the swap backend. `onInvalidEntry` is told about every
|
|
1373
|
+
* registry row that was skipped as unusable (see {@link InvalidEntryHandler}).
|
|
1374
|
+
*/
|
|
650
1375
|
constructor(gateway: Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {
|
|
651
1376
|
requestTimeoutMs?: number | undefined;
|
|
1377
|
+
wire?: WireOptions | undefined;
|
|
1378
|
+
}, options?: {
|
|
1379
|
+
onInvalidEntry?: InvalidEntryHandler | undefined;
|
|
652
1380
|
});
|
|
653
|
-
/**
|
|
1381
|
+
/**
|
|
1382
|
+
* List all registered GalaChainDex trading symbols, cached for 60 seconds. A registry row that
|
|
1383
|
+
* is not a usable symbol is skipped (and reported to `onInvalidEntry`) instead of failing the
|
|
1384
|
+
* whole list.
|
|
1385
|
+
*/
|
|
654
1386
|
list(): Promise<TradingSymbol[]>;
|
|
655
1387
|
/** Invalidate the cached symbol registry after a write changes registration state.
|
|
656
1388
|
*
|
|
@@ -670,7 +1402,32 @@ export declare class Symbols {
|
|
|
670
1402
|
refresh(): Promise<TradingSymbol[]>;
|
|
671
1403
|
/** Resolve a symbol or token class key to its registered symbol metadata. */
|
|
672
1404
|
resolve(ref: TokenRef): Promise<TradingSymbol>;
|
|
673
|
-
/**
|
|
1405
|
+
/**
|
|
1406
|
+
* The trading symbol to put in a token's first CreatePool.
|
|
1407
|
+
*
|
|
1408
|
+
* 1. The symbol ALREADY registered for exactly this class key, if any: proposing another one
|
|
1409
|
+
* fails the gateway's registry-conflict check.
|
|
1410
|
+
* 2. Otherwise `displaySymbol` (the token's curated symbol), when it is proposable
|
|
1411
|
+
* ({@link isProposableTradingSymbol}).
|
|
1412
|
+
* 3. Otherwise a `VALIDATION_ERROR`: a symbol is never derived from the key (BNB's collection is
|
|
1413
|
+
* `GBNB`, a launchpad token's is the reserved word `Token`).
|
|
1414
|
+
*
|
|
1415
|
+
* `registryFailure: 'ignore'` treats an unreachable registry as an empty one and falls through
|
|
1416
|
+
* to step 2 (the gateway still rejects a conflicting symbol); the default `'throw'` propagates
|
|
1417
|
+
* the failure.
|
|
1418
|
+
*
|
|
1419
|
+
* @example
|
|
1420
|
+
* ```ts
|
|
1421
|
+
* const symbol = await gSwap.symbols.proposeSymbol(
|
|
1422
|
+
* { collection: 'GALA_TEST1', category: 'Unit', type: 'none', additionalKey: 'none' },
|
|
1423
|
+
* 'GALATEST',
|
|
1424
|
+
* );
|
|
1425
|
+
* ```
|
|
1426
|
+
*/
|
|
1427
|
+
proposeSymbol(classKey: GalaChainTokenClassKey, displaySymbol: string, options?: {
|
|
1428
|
+
registryFailure?: 'throw' | 'ignore' | undefined;
|
|
1429
|
+
}): Promise<string>;
|
|
1430
|
+
/** Resolve and put two token references in canonical trading-symbol order. */
|
|
674
1431
|
orderPair(a: TokenRef, b: TokenRef): Promise<{
|
|
675
1432
|
token0: TradingSymbol;
|
|
676
1433
|
token1: TradingSymbol;
|
|
@@ -679,38 +1436,109 @@ export declare class Symbols {
|
|
|
679
1436
|
}
|
|
680
1437
|
/** Alias exported for callers that use the contract's shorter type name. */
|
|
681
1438
|
export type TokenClassKey = GalaChainTokenClassKey;
|
|
1439
|
+
/**
|
|
1440
|
+
* What the services need from a token resolver: how a token reference becomes a trading symbol,
|
|
1441
|
+
* and whether requests carry the caller's references untouched. {@link Symbols} is the registry
|
|
1442
|
+
* resolver (one `GET /v2/trade/symbols`, cached); {@link CanonicalSymbols} is the offline one.
|
|
1443
|
+
*/
|
|
1444
|
+
export interface TokenResolver {
|
|
1445
|
+
resolve(ref: TokenRef): Promise<TradingSymbol>;
|
|
1446
|
+
/**
|
|
1447
|
+
* True when reads send the caller's token references verbatim (a symbol, or a composite key as
|
|
1448
|
+
* the caller wrote it) and let the backend resolve and orient the pair — no registry request
|
|
1449
|
+
* and no client-side ordering or tick flip.
|
|
1450
|
+
*/
|
|
1451
|
+
readonly passthrough?: boolean | undefined;
|
|
1452
|
+
}
|
|
1453
|
+
/** A token reference as the caller wrote it: a string verbatim, a class key as its `$` composite. */
|
|
1454
|
+
export declare function rawTokenOf(ref: TokenRef): string;
|
|
1455
|
+
/** The trading symbol of a reference, or `SYMBOL_NOT_FOUND` when the resolver has none. */
|
|
1456
|
+
export declare function tradingSymbolOf(resolver: TokenResolver, ref: TokenRef): Promise<string>;
|
|
1457
|
+
/** What a read request names a token by: the reference itself in pass-through mode, else its symbol. */
|
|
1458
|
+
export declare function queryTokenOf(resolver: TokenResolver, ref: TokenRef): Promise<string>;
|
|
1459
|
+
/**
|
|
1460
|
+
* The offline resolver for apps that already hold the backend's canonical trading symbols (from
|
|
1461
|
+
* `/quote`, `/add-liq-estimate`, a position row) and must not make a registry request of their own.
|
|
1462
|
+
*
|
|
1463
|
+
* - `resolve` accepts a bare trading symbol and returns it as is; a class key (object, `$` or `|`
|
|
1464
|
+
* form) is not a symbol and is refused as `UNKNOWN_TOKEN`. `createPool` relies on that refusal to
|
|
1465
|
+
* fall back to the symbols its caller supplies.
|
|
1466
|
+
* - `orderPair` orders two symbols by plain string comparison, as the contract does.
|
|
1467
|
+
* - Reads are pass-through (see {@link TokenResolver.passthrough}): the caller's references go on
|
|
1468
|
+
* the wire verbatim, composite keys included, and the backend orients the pair.
|
|
1469
|
+
*
|
|
1470
|
+
* @example
|
|
1471
|
+
* ```ts
|
|
1472
|
+
* const swaps = new Swaps(gateway, new CanonicalSymbols(), signer, walletAddress);
|
|
1473
|
+
* await swaps.swap('GALA', 'GUSDC', 3000, { exactIn: '10' });
|
|
1474
|
+
* ```
|
|
1475
|
+
*/
|
|
1476
|
+
export declare class CanonicalSymbols implements TokenResolver {
|
|
1477
|
+
readonly passthrough = true;
|
|
1478
|
+
/** Resolve a bare trading symbol to itself. */
|
|
1479
|
+
resolve(ref: TokenRef): Promise<TradingSymbol>;
|
|
1480
|
+
/** Put two symbols in canonical (string) order. */
|
|
1481
|
+
orderPair(a: TokenRef, b: TokenRef): Promise<{
|
|
1482
|
+
token0: TradingSymbol;
|
|
1483
|
+
token1: TradingSymbol;
|
|
1484
|
+
flipped: boolean;
|
|
1485
|
+
}>;
|
|
1486
|
+
/** There is no registry state to drop. */
|
|
1487
|
+
invalidate(): void;
|
|
1488
|
+
}
|
|
682
1489
|
//#endregion
|
|
683
1490
|
//#region src/classes/pools.d.ts
|
|
684
1491
|
type PoolGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {
|
|
685
1492
|
requestTimeoutMs?: number | undefined;
|
|
1493
|
+
wire?: WireOptions | undefined;
|
|
686
1494
|
};
|
|
687
|
-
|
|
1495
|
+
/** The sort keys of `GET /v2/trade/pools`. */
|
|
1496
|
+
export type PoolSortBy = 'tvl' | 'volume1d' | 'volume30d';
|
|
1497
|
+
/** Options of {@link Pools.getPools}. Omit all of `search`, `sortBy`, `sortOrder`, `page`, `limit` for the full, unsorted list. */
|
|
1498
|
+
export interface PoolListOptions {
|
|
1499
|
+
signal?: AbortSignal | undefined;
|
|
1500
|
+
/** Case-insensitive match on the pair's symbols; `A/B` or `A B` matches either order. At most 64 characters. */
|
|
1501
|
+
search?: string | undefined;
|
|
1502
|
+
sortBy?: PoolSortBy | undefined;
|
|
1503
|
+
sortOrder?: 'asc' | 'desc' | undefined;
|
|
1504
|
+
/** 1-based page number; only meaningful together with `limit`. */
|
|
1505
|
+
page?: number | undefined;
|
|
1506
|
+
/** Rows per page, 1-1000; omitted returns every row. */
|
|
1507
|
+
limit?: number | undefined;
|
|
1508
|
+
/** Overrides the service-level handler for this call. */
|
|
1509
|
+
onInvalidEntry?: InvalidEntryHandler | undefined;
|
|
1510
|
+
}
|
|
688
1511
|
/** Read-only pool and current-price access for the current GalaChainDex contract. */
|
|
689
1512
|
export declare class Pools {
|
|
690
1513
|
private readonly gateway;
|
|
691
1514
|
private readonly symbols;
|
|
1515
|
+
private readonly options;
|
|
692
1516
|
/**
|
|
693
|
-
* Creates a pool service.
|
|
1517
|
+
* Creates a pool service. `options.onInvalidEntry` is told about every pool row that was
|
|
1518
|
+
* skipped as unusable (see {@link InvalidEntryHandler}).
|
|
694
1519
|
*
|
|
695
1520
|
* @example
|
|
696
1521
|
* ```ts
|
|
697
1522
|
* const pools = new Pools(gateway, symbols);
|
|
698
1523
|
* ```
|
|
699
1524
|
*/
|
|
700
|
-
constructor(gateway: PoolGateway, symbols:
|
|
1525
|
+
constructor(gateway: PoolGateway, symbols: TokenResolver, options?: {
|
|
1526
|
+
onInvalidEntry?: InvalidEntryHandler | undefined;
|
|
1527
|
+
});
|
|
701
1528
|
private readonly http;
|
|
702
1529
|
/**
|
|
703
|
-
* Fetches
|
|
1530
|
+
* Fetches current-contract pools from the swap backend, optionally searched, sorted and paged
|
|
1531
|
+
* by the backend. A row that is not a usable pool is skipped and reported to `onInvalidEntry`
|
|
1532
|
+
* instead of failing the whole list; an answer that is not a list at all is
|
|
1533
|
+
* `INVALID_CHAIN_RESPONSE`.
|
|
704
1534
|
*
|
|
705
1535
|
* @example
|
|
706
1536
|
* ```ts
|
|
707
|
-
* const
|
|
708
|
-
* console.log(
|
|
1537
|
+
* const top = await service.getPools({ sortBy: 'tvl', sortOrder: 'desc', page: 1, limit: 8 });
|
|
1538
|
+
* console.log(top.length);
|
|
709
1539
|
* ```
|
|
710
1540
|
*/
|
|
711
|
-
getPools(options?:
|
|
712
|
-
signal?: AbortSignal | undefined;
|
|
713
|
-
}): Promise<PoolListInfo[]>;
|
|
1541
|
+
getPools(options?: PoolListOptions): Promise<PoolListInfo[]>;
|
|
714
1542
|
/**
|
|
715
1543
|
* Fetches one pool from the backend, preserving whether the request order was flipped.
|
|
716
1544
|
*
|
|
@@ -745,237 +1573,342 @@ export declare class Pools {
|
|
|
745
1573
|
private getBackend;
|
|
746
1574
|
}
|
|
747
1575
|
//#endregion
|
|
748
|
-
//#region src/
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
/** The request surface used by an EIP-1193 browser wallet. */
|
|
752
|
-
export interface BrowserWalletProvider {
|
|
753
|
-
request(args: {
|
|
754
|
-
method: string;
|
|
755
|
-
params?: unknown[];
|
|
756
|
-
}): Promise<unknown>;
|
|
1576
|
+
//#region src/types/branding.d.ts
|
|
1577
|
+
interface Branding<BrandT> {
|
|
1578
|
+
_type: BrandT;
|
|
757
1579
|
}
|
|
758
|
-
type
|
|
759
|
-
|
|
1580
|
+
type Brand<T, BrandT> = T & Branding<BrandT>;
|
|
1581
|
+
//#endregion
|
|
1582
|
+
//#region src/types/amounts.d.ts
|
|
1583
|
+
export type NumericAmount = string | BigNumber;
|
|
1584
|
+
export type SqrtPrice = Brand<BigNumber, 'SqrtPrice'>;
|
|
1585
|
+
export type SqrtPriceIn = Brand<NumericAmount, 'SqrtPriceIn'> | SqrtPrice;
|
|
1586
|
+
export type Price = Brand<BigNumber, 'Price'>;
|
|
1587
|
+
export type PriceIn = Brand<NumericAmount, 'PriceIn'> | Price;
|
|
1588
|
+
/**
|
|
1589
|
+
* What a swap trades: exactly one of `exactIn` (sell this much of the input token) or `exactOut`
|
|
1590
|
+
* (receive this much of the output token), with that side's slippage bound and an optional
|
|
1591
|
+
* sqrt-price limit.
|
|
1592
|
+
*/
|
|
1593
|
+
export type SwapAmount = {
|
|
1594
|
+
exactIn: NumericAmount;
|
|
1595
|
+
exactOut?: undefined;
|
|
1596
|
+
amountOutMinimum?: NumericAmount | undefined;
|
|
1597
|
+
amountInMaximum?: undefined;
|
|
1598
|
+
/** Sqrt-price limit passed through to the chain as `priceLimit`; omitted when undefined. */
|
|
1599
|
+
priceLimit?: NumericAmount | undefined;
|
|
1600
|
+
} | {
|
|
1601
|
+
exactIn?: undefined;
|
|
1602
|
+
exactOut: NumericAmount;
|
|
1603
|
+
amountOutMinimum?: undefined;
|
|
1604
|
+
amountInMaximum?: NumericAmount | undefined;
|
|
1605
|
+
/** Sqrt-price limit passed through to the chain as `priceLimit`; omitted when undefined. */
|
|
1606
|
+
priceLimit?: NumericAmount | undefined;
|
|
1607
|
+
};
|
|
1608
|
+
//#endregion
|
|
1609
|
+
//#region src/types/v2_dtos.d.ts
|
|
1610
|
+
/** Common identity fields for v2 pool writes. */
|
|
1611
|
+
export type V2PoolWriteBase = Record<'token0' | 'token1' | 'uniqueKey', string> & {
|
|
1612
|
+
fee: FEE_TIER;
|
|
1613
|
+
};
|
|
1614
|
+
/** A v2 RequestTrade with exactly one selected trade-side quantity. */
|
|
1615
|
+
export type RequestTradeDTO = V2PoolWriteBase & ({
|
|
1616
|
+
sell0Qty: string;
|
|
1617
|
+
sell1Qty?: never;
|
|
1618
|
+
buy0Qty?: never;
|
|
1619
|
+
buy1Qty?: never;
|
|
1620
|
+
} | {
|
|
1621
|
+
sell0Qty?: never;
|
|
1622
|
+
sell1Qty: string;
|
|
1623
|
+
buy0Qty?: never;
|
|
1624
|
+
buy1Qty?: never;
|
|
1625
|
+
} | {
|
|
1626
|
+
sell0Qty?: never;
|
|
1627
|
+
sell1Qty?: never;
|
|
1628
|
+
buy0Qty: string;
|
|
1629
|
+
buy1Qty?: never;
|
|
1630
|
+
} | {
|
|
1631
|
+
sell0Qty?: never;
|
|
1632
|
+
sell1Qty?: never;
|
|
1633
|
+
buy0Qty?: never;
|
|
1634
|
+
buy1Qty: string;
|
|
1635
|
+
}) & {
|
|
1636
|
+
amountOutMinimum?: string | undefined;
|
|
1637
|
+
amountInMaximum?: string | undefined;
|
|
1638
|
+
priceLimit?: string | undefined;
|
|
1639
|
+
};
|
|
1640
|
+
/** A v2 liquidity deposit with exactly one selected deposit quantity. */
|
|
1641
|
+
export type AddLiquidityDTO = V2PoolWriteBase & {
|
|
1642
|
+
tickLower: number;
|
|
1643
|
+
tickUpper: number;
|
|
1644
|
+
} & ({
|
|
1645
|
+
depositQuantityToken0: string;
|
|
1646
|
+
depositQuantityToken1?: never;
|
|
1647
|
+
} | {
|
|
1648
|
+
depositQuantityToken0?: never;
|
|
1649
|
+
depositQuantityToken1: string;
|
|
1650
|
+
});
|
|
1651
|
+
/** A v2 liquidity withdrawal; omitting both quantities closes the position. */
|
|
1652
|
+
export type RemoveLiquidityDTO = V2PoolWriteBase & {
|
|
1653
|
+
tickLower: number;
|
|
1654
|
+
tickUpper: number;
|
|
1655
|
+
} & ({
|
|
1656
|
+
withdrawalQuantityToken0: string;
|
|
1657
|
+
withdrawalQuantityToken1?: never;
|
|
1658
|
+
} | {
|
|
1659
|
+
withdrawalQuantityToken0?: never;
|
|
1660
|
+
withdrawalQuantityToken1: string;
|
|
1661
|
+
} | {
|
|
1662
|
+
withdrawalQuantityToken0?: never;
|
|
1663
|
+
withdrawalQuantityToken1?: never;
|
|
1664
|
+
});
|
|
1665
|
+
/** A v2 request to sweep all fees from one position. */
|
|
1666
|
+
export type CollectPositionFeesDTO = V2PoolWriteBase & {
|
|
1667
|
+
tickLower: number;
|
|
1668
|
+
tickUpper: number;
|
|
760
1669
|
};
|
|
1670
|
+
/** A v2 pool creation request with exactly one initial-price representation. */
|
|
1671
|
+
export type CreatePoolDTO = {
|
|
1672
|
+
token0Key: GalaChainTokenClassKey;
|
|
1673
|
+
token1Key: GalaChainTokenClassKey;
|
|
1674
|
+
token0Symbol: string;
|
|
1675
|
+
token1Symbol: string;
|
|
1676
|
+
fee: FEE_TIER;
|
|
1677
|
+
name?: string | undefined;
|
|
1678
|
+
isPrivate?: boolean | undefined;
|
|
1679
|
+
privateAccess?: string[] | undefined;
|
|
1680
|
+
uniqueKey: string;
|
|
1681
|
+
} & ({
|
|
1682
|
+
startingPrice: string;
|
|
1683
|
+
startingSqrtPrice?: never;
|
|
1684
|
+
} | {
|
|
1685
|
+
startingPrice?: never;
|
|
1686
|
+
startingSqrtPrice: string;
|
|
1687
|
+
});
|
|
1688
|
+
/** Optional page cursor accepted by chain read methods. */
|
|
1689
|
+
export interface PageDTO {
|
|
1690
|
+
limit?: number | undefined;
|
|
1691
|
+
bookmark?: string | undefined;
|
|
1692
|
+
}
|
|
1693
|
+
/** Fetch all registered trading symbols. */
|
|
1694
|
+
export type FetchTokenTradingSymbolsDTO = PageDTO;
|
|
1695
|
+
/** Fetch a composite pool snapshot. */
|
|
1696
|
+
export interface FetchCompositePoolDataDTO {
|
|
1697
|
+
token0: string;
|
|
1698
|
+
token1: string;
|
|
1699
|
+
fee: FEE_TIER;
|
|
1700
|
+
}
|
|
1701
|
+
/** Fetch one current trading price, or all prices when no pair is supplied. */
|
|
1702
|
+
export type FetchCurrentTradingPricesDTO = Partial<FetchCompositePoolDataDTO> & PageDTO;
|
|
1703
|
+
/** Fetch pools, optionally narrowed to one pair and paged. */
|
|
1704
|
+
export type FetchPoolsDTO = Partial<FetchCompositePoolDataDTO> & PageDTO;
|
|
1705
|
+
/** Fetch all liquidity positions, optionally narrowed to a pool reference. */
|
|
1706
|
+
export interface FetchLiquidityPositionsDTO extends PageDTO {
|
|
1707
|
+
pool?: string | undefined;
|
|
1708
|
+
}
|
|
1709
|
+
//#endregion
|
|
1710
|
+
//#region src/utils/unique_key.d.ts
|
|
761
1711
|
/**
|
|
762
|
-
*
|
|
1712
|
+
* The `uniqueKey` prefix frontend_v2 and wallet_extension have always sent
|
|
1713
|
+
* (`galaswap-operation-<uuid>`). defi-backend does not depend on it: the chain-write verifier
|
|
1714
|
+
* only requires a non-empty key of at most 256 characters, and apply-results accepts
|
|
1715
|
+
* `[A-Za-z0-9._:-]{1,128}`; the only code that mints a prefixed key itself is the server-side v1
|
|
1716
|
+
* trade builder, which nothing reads back by prefix.
|
|
1717
|
+
*/
|
|
1718
|
+
export declare const DEFAULT_UNIQUE_KEY_PREFIX = "galaswap-operation-";
|
|
1719
|
+
/** Options shared by the services that mint `uniqueKey`s for writes. */
|
|
1720
|
+
export interface UniqueKeyOptions {
|
|
1721
|
+
/**
|
|
1722
|
+
* Prefix of every minted `uniqueKey` (`<prefix><uuid>`). Defaults to
|
|
1723
|
+
* `DEFAULT_UNIQUE_KEY_PREFIX` (`galaswap-operation-`).
|
|
1724
|
+
*/
|
|
1725
|
+
uniqueKeyPrefix?: string | undefined;
|
|
1726
|
+
}
|
|
1727
|
+
/**
|
|
1728
|
+
* Validates a caller-supplied `uniqueKey` prefix. The whole key (`<prefix><uuid>`) must stay a
|
|
1729
|
+
* valid apply-results key, otherwise `confirm()` could never read the outcome of the write.
|
|
763
1730
|
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
766
|
-
* not add signer hints, typed-data metadata, or a domain.
|
|
1731
|
+
* @throws GSwapSDKError VALIDATION_ERROR when the prefix has characters outside `A-Za-z0-9._:-` or
|
|
1732
|
+
* is longer than 92 characters.
|
|
767
1733
|
*/
|
|
768
|
-
export
|
|
1734
|
+
export declare function resolveUniqueKeyPrefix(prefix: string | undefined): string;
|
|
1735
|
+
/**
|
|
1736
|
+
* Validates a caller-supplied write `uniqueKey`: 1 to 128 characters of `A-Za-z0-9._:-`, the
|
|
1737
|
+
* shape the apply-results route accepts, so the write's outcome can always be read back with
|
|
1738
|
+
* `confirm()`. A key is one attempt's identity: reuse it only to retry that same attempt.
|
|
1739
|
+
*
|
|
1740
|
+
* @throws GSwapSDKError VALIDATION_ERROR otherwise.
|
|
1741
|
+
*/
|
|
1742
|
+
export declare function assertUniqueKey(uniqueKey: string): void;
|
|
1743
|
+
/** A fresh per-attempt key: `<prefix><random UUID>`. */
|
|
1744
|
+
export declare function createUniqueKey(prefix: string): string;
|
|
1745
|
+
//#endregion
|
|
1746
|
+
//#region src/classes/positions.d.ts
|
|
1747
|
+
type PositionGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {
|
|
1748
|
+
submit: (method: string, signedBody: Record<string, unknown>, options?: ChainSubmitOptions) => Promise<SubmittedTransaction<Position | null>>;
|
|
1749
|
+
requestTimeoutMs?: number | undefined;
|
|
1750
|
+
wire?: WireOptions | undefined;
|
|
1751
|
+
};
|
|
1752
|
+
type PositionSymbols = TokenResolver & Pick<Symbols, 'orderPair'> & {
|
|
1753
|
+
invalidate?: () => void;
|
|
1754
|
+
};
|
|
1755
|
+
/** Options of {@link Positions}: the `uniqueKey` prefix and a handler for skipped list rows. */
|
|
1756
|
+
export interface PositionsOptions extends UniqueKeyOptions {
|
|
1757
|
+
/** Told about every position row of a list that was skipped as unusable. */
|
|
1758
|
+
onInvalidEntry?: InvalidEntryHandler | undefined;
|
|
1759
|
+
}
|
|
1760
|
+
/** A write's optional attempt identity. */
|
|
1761
|
+
interface UniqueKeyArg {
|
|
769
1762
|
/**
|
|
770
|
-
*
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
* ```typescript
|
|
774
|
-
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
775
|
-
* ```
|
|
1763
|
+
* The attempt's `uniqueKey` (1-128 characters of `A-Za-z0-9._:-`). Default: a fresh
|
|
1764
|
+
* `<uniqueKeyPrefix><uuid>`. Supply one to know the key before signing, or to retry the SAME
|
|
1765
|
+
* attempt after a lost response; never reuse it for another write.
|
|
776
1766
|
*/
|
|
777
|
-
|
|
1767
|
+
uniqueKey?: string | undefined;
|
|
1768
|
+
}
|
|
1769
|
+
/** Arguments of {@link Positions.addLiquidityByTicks} and {@link Positions.buildAddLiquidity}. */
|
|
1770
|
+
export interface AddLiquidityArgs extends UniqueKeyArg {
|
|
1771
|
+
token0: TokenRef;
|
|
1772
|
+
token1: TokenRef;
|
|
1773
|
+
fee: FEE_TIER;
|
|
1774
|
+
tickLower: number;
|
|
1775
|
+
tickUpper: number;
|
|
1776
|
+
amount: NumericAmount;
|
|
1777
|
+
/** Whether `amount` is of `token0` as the caller passed it (not of the canonical token0). */
|
|
1778
|
+
amountIsToken0: boolean;
|
|
1779
|
+
}
|
|
1780
|
+
/** Arguments of {@link Positions.removeLiquidity} and {@link Positions.buildRemoveLiquidity}. */
|
|
1781
|
+
export interface RemoveLiquidityArgs extends UniqueKeyArg {
|
|
1782
|
+
token0: TokenRef;
|
|
1783
|
+
token1: TokenRef;
|
|
1784
|
+
fee: FEE_TIER;
|
|
1785
|
+
tickLower: number;
|
|
1786
|
+
tickUpper: number;
|
|
1787
|
+
/** Withdraw this much of the caller's `token0`; give at most one of `amount0` / `amount1`. */
|
|
1788
|
+
amount0?: NumericAmount | undefined;
|
|
1789
|
+
amount1?: NumericAmount | undefined;
|
|
1790
|
+
}
|
|
1791
|
+
/** Arguments of {@link Positions.collectPositionFees} and {@link Positions.buildCollectPositionFees}. */
|
|
1792
|
+
export interface CollectPositionFeesArgs extends UniqueKeyArg {
|
|
1793
|
+
token0: TokenRef;
|
|
1794
|
+
token1: TokenRef;
|
|
1795
|
+
fee: FEE_TIER;
|
|
1796
|
+
tickLower: number;
|
|
1797
|
+
tickUpper: number;
|
|
1798
|
+
}
|
|
1799
|
+
/** Arguments of {@link Positions.createPool} and {@link Positions.buildCreatePool}. */
|
|
1800
|
+
export interface CreatePoolArgs extends UniqueKeyArg {
|
|
1801
|
+
token0: TokenRef;
|
|
1802
|
+
token1: TokenRef;
|
|
1803
|
+
token0Symbol?: string | undefined;
|
|
1804
|
+
token1Symbol?: string | undefined;
|
|
1805
|
+
fee: FEE_TIER;
|
|
1806
|
+
startingPrice?: NumericAmount | undefined;
|
|
1807
|
+
startingSqrtPrice?: NumericAmount | undefined;
|
|
1808
|
+
/** Optional pool display name, sent as the DTO's `name`; omitted when undefined or empty. */
|
|
1809
|
+
name?: string | undefined;
|
|
1810
|
+
isPrivate?: boolean | undefined;
|
|
1811
|
+
privateAccess?: string[] | undefined;
|
|
778
1812
|
}
|
|
779
1813
|
/**
|
|
780
|
-
*
|
|
1814
|
+
* The outcome of {@link Positions.readPosition}. Only `not_found` is chain-confirmed absence (the
|
|
1815
|
+
* backend answers HTTP 404 only when the chain itself found no such position); `unknown` is "no
|
|
1816
|
+
* evidence either way" — a transport failure, a gateway timeout, any other error status or an
|
|
1817
|
+
* answer that is not a position — and must never be read as a removal.
|
|
1818
|
+
*/
|
|
1819
|
+
export type PositionRead = {
|
|
1820
|
+
kind: 'found';
|
|
1821
|
+
data: Position;
|
|
1822
|
+
} | {
|
|
1823
|
+
kind: 'not_found';
|
|
1824
|
+
} | {
|
|
1825
|
+
kind: 'unknown';
|
|
1826
|
+
error: GSwapSDKError;
|
|
1827
|
+
};
|
|
1828
|
+
/**
|
|
1829
|
+
* Manages current-contract concentrated-liquidity positions.
|
|
781
1830
|
*
|
|
782
|
-
*
|
|
783
|
-
*
|
|
1831
|
+
* @example
|
|
1832
|
+
* ```typescript
|
|
1833
|
+
* const positions = gSwap.positions;
|
|
1834
|
+
* const mine = await positions.getUserPositions('client|012345678901234567890123');
|
|
1835
|
+
* console.log(mine.length);
|
|
1836
|
+
* ```
|
|
784
1837
|
*/
|
|
785
|
-
export declare class
|
|
786
|
-
private readonly
|
|
1838
|
+
export declare class Positions {
|
|
1839
|
+
private readonly gateway;
|
|
1840
|
+
private readonly symbols;
|
|
1841
|
+
private readonly signer?;
|
|
1842
|
+
private readonly walletAddress?;
|
|
1843
|
+
constructor(gateway: PositionGateway, symbols: PositionSymbols, signer?: GalaChainSigner | undefined, walletAddress?: string | undefined, options?: PositionsOptions);
|
|
1844
|
+
private readonly http;
|
|
1845
|
+
private readonly uniqueKeyPrefix;
|
|
1846
|
+
private readonly onInvalidEntry;
|
|
787
1847
|
/**
|
|
788
|
-
*
|
|
1848
|
+
* Gets all current-contract positions owned by an address.
|
|
789
1849
|
*
|
|
1850
|
+
* @param owner - GalaChain owner identity.
|
|
1851
|
+
* @returns Enriched positions from the v2 trade backend, token images included. A row that is
|
|
1852
|
+
* not a usable position is skipped and reported to `onInvalidEntry`.
|
|
790
1853
|
* @example
|
|
791
1854
|
* ```typescript
|
|
792
|
-
* const
|
|
793
|
-
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
1855
|
+
* const positions = await gSwap.positions.getUserPositions('client|012345678901234567890123');
|
|
794
1856
|
* ```
|
|
795
1857
|
*/
|
|
796
|
-
|
|
1858
|
+
getUserPositions(owner: string): Promise<Position[]>;
|
|
797
1859
|
/**
|
|
798
|
-
*
|
|
1860
|
+
* Gets one position, normalizing a caller-supplied reversed pair to canonical symbol order.
|
|
1861
|
+
* Reversed pairs also invert the price axis, so `[lower, upper]` becomes `[-upper, -lower]`.
|
|
799
1862
|
*
|
|
1863
|
+
* @param args - Pair, owner, fee, and position tick range.
|
|
1864
|
+
* @returns The position, or `null` when the backend returns 404.
|
|
800
1865
|
* @example
|
|
801
1866
|
* ```typescript
|
|
802
|
-
* const
|
|
803
|
-
* token0: 'GALA',
|
|
804
|
-
*
|
|
805
|
-
* fee: 3000,
|
|
1867
|
+
* const position = await gSwap.positions.getPosition({
|
|
1868
|
+
* token0: 'GALA', token1: 'GUSDC', owner: 'client|012345678901234567890123',
|
|
1869
|
+
* fee: 3000, tickLower: -19200, tickUpper: 12000,
|
|
806
1870
|
* });
|
|
807
1871
|
* ```
|
|
808
1872
|
*/
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
* `gala_signChainDto([serialize({ ...dto, prefix }), walletAddress, methodName])`.
|
|
818
|
-
*/
|
|
819
|
-
export declare class GalaWalletSigner implements GalaChainSigner {
|
|
820
|
-
/** The wallet address supplied to Gala Wallet for each signing request. */
|
|
821
|
-
readonly walletAddress: string;
|
|
822
|
-
/** The scheme currently used, including any automatic native-to-personal fallback. */
|
|
823
|
-
effectiveScheme: GalaWalletScheme;
|
|
824
|
-
/**
|
|
825
|
-
* Creates a Gala Wallet signer.
|
|
826
|
-
*
|
|
827
|
-
* @example
|
|
828
|
-
* ```typescript
|
|
829
|
-
* const signer = new GalaWalletSigner('0x0123456789012345678901234567890123456789');
|
|
830
|
-
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
831
|
-
* ```
|
|
832
|
-
*
|
|
833
|
-
* @param walletAddress - The selected Ethereum account (`0x` plus 40 hex digits); Gala Wallet's
|
|
834
|
-
* `eth|0x...` form is also accepted and normalized.
|
|
835
|
-
* @param options - Select native signing or personal-sign explicitly.
|
|
836
|
-
*/
|
|
837
|
-
constructor(walletAddress: string, options?: {
|
|
838
|
-
scheme?: GalaWalletScheme | undefined;
|
|
839
|
-
});
|
|
840
|
-
/**
|
|
841
|
-
* Signs a DTO through `gala_signChainDto`.
|
|
842
|
-
*
|
|
843
|
-
* @example
|
|
844
|
-
* ```typescript
|
|
845
|
-
* const signed = await signer.signObject('AddLiquidity', {
|
|
846
|
-
* token0: 'GALA',
|
|
847
|
-
* token1: 'GUSDC',
|
|
848
|
-
* tickLower: -60,
|
|
849
|
-
* tickUpper: 60,
|
|
850
|
-
* });
|
|
851
|
-
* ```
|
|
852
|
-
*/
|
|
853
|
-
signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;
|
|
854
|
-
}
|
|
855
|
-
/**
|
|
856
|
-
* A personal-sign signer for MetaMask and other EIP-1193 browser wallets.
|
|
857
|
-
*
|
|
858
|
-
* The chain recovers this signature using the EIP-191 wrap applied by the wallet to
|
|
859
|
-
* `personal_sign`. This is the browser-wallet path used by the v2 frontend and resolves the
|
|
860
|
-
* bare `eth|` identity.
|
|
861
|
-
*/
|
|
862
|
-
export declare class BrowserWalletSigner implements GalaChainSigner {
|
|
863
|
-
private readonly provider;
|
|
864
|
-
/**
|
|
865
|
-
* Creates a browser-wallet signer.
|
|
866
|
-
*
|
|
867
|
-
* Defaults to `personal_sign` — unchanged from every existing integration, since it only ever
|
|
868
|
-
* resolves the bare `eth|` identity and changing that silently would be a real behavior
|
|
869
|
-
* break for anyone already depending on it. Pass `{ scheme: 'eip712' }` to correctly resolve
|
|
870
|
-
* a registered `client|` alias instead, for `RequestTrade`/`AddLiquidity`/`RemoveLiquidity`/
|
|
871
|
-
* `CollectPositionFees` (`EIP712_CAPABLE_METHODS`) — `CreatePool` and any other method still
|
|
872
|
-
* falls back to `personal_sign` even in `'eip712'` mode, since its EIP-712 signing is a
|
|
873
|
-
* separate, unsolved chain-side problem.
|
|
874
|
-
*
|
|
875
|
-
* @example
|
|
876
|
-
* ```typescript
|
|
877
|
-
* const signer = new BrowserWalletSigner(window.ethereum, '0x0123456789012345678901234567890123456789');
|
|
878
|
-
* const signed = await signer.signObject('RequestTrade', { token0: 'GALA', token1: 'GUSDC' });
|
|
879
|
-
* ```
|
|
880
|
-
* @example
|
|
881
|
-
* ```typescript
|
|
882
|
-
* // Correctly resolves a registered client| alias instead of the bare eth| address.
|
|
883
|
-
* const signer = new BrowserWalletSigner(window.ethereum, walletAddress, { scheme: 'eip712' });
|
|
884
|
-
* ```
|
|
885
|
-
*/
|
|
886
|
-
constructor(provider: BrowserWalletProvider, walletAddress: string, options?: {
|
|
887
|
-
scheme?: 'personal-sign' | 'eip712';
|
|
888
|
-
});
|
|
889
|
-
readonly walletAddress: string;
|
|
890
|
-
private readonly scheme;
|
|
891
|
-
/**
|
|
892
|
-
* Signs the DTO with `eth_signTypedData_v4` (when constructed with `{ scheme: 'eip712' }` and
|
|
893
|
-
* `methodName` is in `EIP712_CAPABLE_METHODS`) or the EIP-1193 `personal_sign` method
|
|
894
|
-
* (otherwise — the default).
|
|
895
|
-
*
|
|
896
|
-
* @example
|
|
897
|
-
* ```typescript
|
|
898
|
-
* const signed = await signer.signObject('RequestTrade', {
|
|
899
|
-
* token0: 'GALA',
|
|
900
|
-
* token1: 'GUSDC',
|
|
901
|
-
* fee: 3000,
|
|
902
|
-
* });
|
|
903
|
-
* ```
|
|
904
|
-
*/
|
|
905
|
-
signObject<T extends Record<string, unknown>>(methodName: string, dto: T): Promise<SignedDto<T>>;
|
|
906
|
-
}
|
|
907
|
-
//#endregion
|
|
908
|
-
//#region src/types/branding.d.ts
|
|
909
|
-
interface Branding<BrandT> {
|
|
910
|
-
_type: BrandT;
|
|
911
|
-
}
|
|
912
|
-
type Brand<T, BrandT> = T & Branding<BrandT>;
|
|
913
|
-
//#endregion
|
|
914
|
-
//#region src/types/amounts.d.ts
|
|
915
|
-
export type NumericAmount = string | BigNumber;
|
|
916
|
-
export type SqrtPrice = Brand<BigNumber, 'SqrtPrice'>;
|
|
917
|
-
export type SqrtPriceIn = Brand<NumericAmount, 'SqrtPriceIn'> | SqrtPrice;
|
|
918
|
-
export type Price = Brand<BigNumber, 'Price'>;
|
|
919
|
-
export type PriceIn = Brand<NumericAmount, 'PriceIn'> | Price;
|
|
920
|
-
//#endregion
|
|
921
|
-
//#region src/classes/positions.d.ts
|
|
922
|
-
type PositionGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {
|
|
923
|
-
submit: (method: string, signedBody: Record<string, unknown>, options?: ChainSubmitOptions) => Promise<SubmittedTransaction<Position | null>>;
|
|
924
|
-
requestTimeoutMs?: number | undefined;
|
|
925
|
-
};
|
|
926
|
-
type PositionSymbols = Pick<Symbols, 'resolve' | 'orderPair'> & {
|
|
927
|
-
invalidate?: () => void;
|
|
928
|
-
};
|
|
929
|
-
/**
|
|
930
|
-
* Manages current-contract concentrated-liquidity positions.
|
|
931
|
-
*
|
|
932
|
-
* @example
|
|
933
|
-
* ```typescript
|
|
934
|
-
* const positions = gSwap.positions;
|
|
935
|
-
* const mine = await positions.getUserPositions('client|012345678901234567890123');
|
|
936
|
-
* console.log(mine.length);
|
|
937
|
-
* ```
|
|
938
|
-
*/
|
|
939
|
-
export declare class Positions {
|
|
940
|
-
private readonly gateway;
|
|
941
|
-
private readonly symbols;
|
|
942
|
-
private readonly signer?;
|
|
943
|
-
private readonly walletAddress?;
|
|
944
|
-
constructor(gateway: PositionGateway, symbols: PositionSymbols, signer?: GalaChainSigner | undefined, walletAddress?: string | undefined);
|
|
945
|
-
private readonly http;
|
|
1873
|
+
getPosition(args: {
|
|
1874
|
+
token0: TokenRef;
|
|
1875
|
+
token1: TokenRef;
|
|
1876
|
+
fee: FEE_TIER;
|
|
1877
|
+
owner: string;
|
|
1878
|
+
tickLower: number;
|
|
1879
|
+
tickUpper: number;
|
|
1880
|
+
}, signal?: AbortSignal): Promise<Position | null>;
|
|
946
1881
|
/**
|
|
947
|
-
*
|
|
1882
|
+
* Reads one position and classifies the outcome instead of throwing: `found` with the position
|
|
1883
|
+
* (fees included), `not_found` (the backend's HTTP 404, which it sends only when the chain
|
|
1884
|
+
* itself has no such position) or `unknown` (any other failure, carried as `error`). Use it
|
|
1885
|
+
* to confirm a write: `unknown` is "no evidence either way", never a confirmed absence.
|
|
948
1886
|
*
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
-
* @example
|
|
952
|
-
* ```typescript
|
|
953
|
-
* const positions = await gSwap.positions.getUserPositions('client|012345678901234567890123');
|
|
954
|
-
* ```
|
|
955
|
-
*/
|
|
956
|
-
getUserPositions(owner: string): Promise<Position[]>;
|
|
957
|
-
/**
|
|
958
|
-
* Gets one position, normalizing a caller-supplied reversed pair to canonical symbol order.
|
|
959
|
-
* Reversed pairs also invert the price axis, so `[lower, upper]` becomes `[-upper, -lower]`.
|
|
1887
|
+
* Only the caller's own abort rethrows. With a pass-through resolver ({@link CanonicalSymbols})
|
|
1888
|
+
* the pair and ticks go to the backend exactly as given and the backend orients them.
|
|
960
1889
|
*
|
|
961
|
-
* @param args - Pair, owner, fee, and position tick range.
|
|
962
|
-
* @returns The position, or `null` when the backend returns 404.
|
|
963
1890
|
* @example
|
|
964
1891
|
* ```typescript
|
|
965
|
-
* const
|
|
1892
|
+
* const read = await gSwap.positions.readPosition({
|
|
966
1893
|
* token0: 'GALA', token1: 'GUSDC', owner: 'client|012345678901234567890123',
|
|
967
1894
|
* fee: 3000, tickLower: -19200, tickUpper: 12000,
|
|
968
1895
|
* });
|
|
1896
|
+
* if (read.kind === 'found') console.log(read.data.fees0);
|
|
969
1897
|
* ```
|
|
970
1898
|
*/
|
|
971
|
-
|
|
1899
|
+
readPosition(args: {
|
|
972
1900
|
token0: TokenRef;
|
|
973
1901
|
token1: TokenRef;
|
|
974
1902
|
fee: FEE_TIER;
|
|
975
1903
|
owner: string;
|
|
976
1904
|
tickLower: number;
|
|
977
1905
|
tickUpper: number;
|
|
978
|
-
}, signal?: AbortSignal): Promise<
|
|
1906
|
+
}, signal?: AbortSignal): Promise<PositionRead>;
|
|
1907
|
+
/**
|
|
1908
|
+
* The `/position` query: canonical symbols and canonical ticks after a client-side flip, or,
|
|
1909
|
+
* for a pass-through resolver, the caller's references and ticks untouched.
|
|
1910
|
+
*/
|
|
1911
|
+
private positionParams;
|
|
979
1912
|
/**
|
|
980
1913
|
* Estimates the other token amount and resulting liquidity for a deposit.
|
|
981
1914
|
*
|
|
@@ -1033,15 +1966,28 @@ export declare class Positions {
|
|
|
1033
1966
|
* await tx.confirm();
|
|
1034
1967
|
* ```
|
|
1035
1968
|
*/
|
|
1036
|
-
addLiquidityByTicks(args:
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1969
|
+
addLiquidityByTicks(args: AddLiquidityArgs): Promise<SubmittedTransaction<Position | null>>;
|
|
1970
|
+
/**
|
|
1971
|
+
* Builds the AddLiquidity DTO that {@link addLiquidityByTicks} would sign, without signing or
|
|
1972
|
+
* sending it: to show in an approval popup, or to sign elsewhere. Submit exactly this DTO with
|
|
1973
|
+
* {@link submitAddLiquidity}. The pure counterpart, with canonical inputs and no resolution,
|
|
1974
|
+
* is `buildAddLiquidityDto`.
|
|
1975
|
+
*
|
|
1976
|
+
* @example
|
|
1977
|
+
* ```typescript
|
|
1978
|
+
* const dto = await gSwap.positions.buildAddLiquidity({
|
|
1979
|
+
* token0: 'GALA', token1: 'GUSDC', fee: 3000,
|
|
1980
|
+
* tickLower: -19200, tickUpper: 12000, amount: '100', amountIsToken0: true,
|
|
1981
|
+
* });
|
|
1982
|
+
* ```
|
|
1983
|
+
*/
|
|
1984
|
+
buildAddLiquidity(args: AddLiquidityArgs): Promise<AddLiquidityDTO>;
|
|
1985
|
+
/**
|
|
1986
|
+
* Signs and submits a DTO built by {@link buildAddLiquidity} or `buildAddLiquidityDto`; it must
|
|
1987
|
+
* be exactly what the builder produces. The returned transaction confirms by proving the
|
|
1988
|
+
* position's liquidity grew.
|
|
1989
|
+
*/
|
|
1990
|
+
submitAddLiquidity(dto: AddLiquidityDTO): Promise<SubmittedTransaction<Position | null>>;
|
|
1045
1991
|
/**
|
|
1046
1992
|
* Adds liquidity from prices, flooring the lower tick and ceiling the upper tick to fee spacing.
|
|
1047
1993
|
* The resulting range is therefore no narrower than the requested price interval.
|
|
@@ -1064,6 +2010,8 @@ export declare class Positions {
|
|
|
1064
2010
|
maxPrice: PriceIn;
|
|
1065
2011
|
amount: NumericAmount;
|
|
1066
2012
|
amountIsToken0: boolean;
|
|
2013
|
+
/** The attempt's `uniqueKey`; default a fresh one (see {@link AddLiquidityArgs.uniqueKey}). */
|
|
2014
|
+
uniqueKey?: string | undefined;
|
|
1067
2015
|
}): Promise<SubmittedTransaction<Position | null>>;
|
|
1068
2016
|
/**
|
|
1069
2017
|
* Removes liquidity by withdrawing at most one canonical token quantity.
|
|
@@ -1079,15 +2027,19 @@ export declare class Positions {
|
|
|
1079
2027
|
* });
|
|
1080
2028
|
* ```
|
|
1081
2029
|
*/
|
|
1082
|
-
removeLiquidity(args:
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
2030
|
+
removeLiquidity(args: RemoveLiquidityArgs): Promise<SubmittedTransaction<Position | null>>;
|
|
2031
|
+
/**
|
|
2032
|
+
* Builds the RemoveLiquidity DTO that {@link removeLiquidity} would sign, without signing or
|
|
2033
|
+
* sending it. Submit exactly this DTO with {@link submitRemoveLiquidity}. The pure counterpart
|
|
2034
|
+
* is `buildRemoveLiquidityDto`.
|
|
2035
|
+
*/
|
|
2036
|
+
buildRemoveLiquidity(args: RemoveLiquidityArgs): Promise<RemoveLiquidityDTO>;
|
|
2037
|
+
/**
|
|
2038
|
+
* Signs and submits a DTO built by {@link buildRemoveLiquidity} or `buildRemoveLiquidityDto`;
|
|
2039
|
+
* it must be exactly what the builder produces. A DTO with no withdrawal quantity closes the
|
|
2040
|
+
* position, and the returned transaction then confirms by proving the position is gone.
|
|
2041
|
+
*/
|
|
2042
|
+
submitRemoveLiquidity(dto: RemoveLiquidityDTO): Promise<SubmittedTransaction<Position | null>>;
|
|
1091
2043
|
/**
|
|
1092
2044
|
* Collects all accrued fees for a position; the contract does not support partial collection.
|
|
1093
2045
|
*
|
|
@@ -1101,13 +2053,18 @@ export declare class Positions {
|
|
|
1101
2053
|
* });
|
|
1102
2054
|
* ```
|
|
1103
2055
|
*/
|
|
1104
|
-
collectPositionFees(args:
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
2056
|
+
collectPositionFees(args: CollectPositionFeesArgs): Promise<SubmittedTransaction<Position | null>>;
|
|
2057
|
+
/**
|
|
2058
|
+
* Builds the CollectPositionFees DTO that {@link collectPositionFees} would sign, without
|
|
2059
|
+
* signing or sending it. Submit exactly this DTO with {@link submitCollectPositionFees}. The
|
|
2060
|
+
* pure counterpart is `buildCollectPositionFeesDto`.
|
|
2061
|
+
*/
|
|
2062
|
+
buildCollectPositionFees(args: CollectPositionFeesArgs): Promise<CollectPositionFeesDTO>;
|
|
2063
|
+
/**
|
|
2064
|
+
* Signs and submits a DTO built by {@link buildCollectPositionFees} or
|
|
2065
|
+
* `buildCollectPositionFeesDto`; it must be exactly what the builder produces.
|
|
2066
|
+
*/
|
|
2067
|
+
submitCollectPositionFees(dto: CollectPositionFeesDTO): Promise<SubmittedTransaction<Position | null>>;
|
|
1111
2068
|
/**
|
|
1112
2069
|
* Creates a pool, resolving registered trading symbols.
|
|
1113
2070
|
* Reversed symbol order inverts the supplied starting price or square-root price.
|
|
@@ -1129,17 +2086,20 @@ export declare class Positions {
|
|
|
1129
2086
|
* });
|
|
1130
2087
|
* ```
|
|
1131
2088
|
*/
|
|
1132
|
-
createPool(args:
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
2089
|
+
createPool(args: CreatePoolArgs): Promise<SubmittedTransaction<Position | null>>;
|
|
2090
|
+
/**
|
|
2091
|
+
* Builds the CreatePool DTO that {@link createPool} would sign, without signing or sending it:
|
|
2092
|
+
* symbols resolved or proposed, the pair put in canonical order and the price inverted when it
|
|
2093
|
+
* was reversed. Submit exactly this DTO with {@link submitCreatePool}. The pure counterpart,
|
|
2094
|
+
* with canonical inputs, is `buildCreatePoolDto`.
|
|
2095
|
+
*/
|
|
2096
|
+
buildCreatePool(args: CreatePoolArgs): Promise<CreatePoolDTO>;
|
|
2097
|
+
/**
|
|
2098
|
+
* Signs and submits a DTO built by {@link buildCreatePool} or `buildCreatePoolDto`; it must be
|
|
2099
|
+
* exactly what the builder produces. The returned transaction confirms by the pool existing, and
|
|
2100
|
+
* the cached symbol registry is dropped, since the pool may have registered new symbols.
|
|
2101
|
+
*/
|
|
2102
|
+
submitCreatePool(dto: CreatePoolDTO): Promise<SubmittedTransaction<Position | null>>;
|
|
1143
2103
|
private submit;
|
|
1144
2104
|
/**
|
|
1145
2105
|
* Builds a confirmation closure that proves the write's own effect, not just that a
|
|
@@ -1157,32 +2117,35 @@ export declare class Positions {
|
|
|
1157
2117
|
private get;
|
|
1158
2118
|
private getNullable;
|
|
1159
2119
|
private isNotFound;
|
|
1160
|
-
private mapPosition;
|
|
1161
|
-
private requestToken;
|
|
1162
2120
|
private canonicalTicks;
|
|
1163
2121
|
private tickSpacing;
|
|
1164
2122
|
private rejectNumber;
|
|
1165
|
-
|
|
2123
|
+
/** The caller's `uniqueKey` (validated), else a fresh one. */
|
|
2124
|
+
private uniqueKeyFor;
|
|
1166
2125
|
private resolveCreateToken;
|
|
1167
2126
|
private tryParseClassKey;
|
|
1168
2127
|
}
|
|
1169
2128
|
//#endregion
|
|
1170
2129
|
//#region src/classes/quoting.d.ts
|
|
1171
|
-
|
|
2130
|
+
/** The transport a quote service reads through: the same shape `Pools` and `Symbols` take. */
|
|
2131
|
+
type QuoteGateway = Pick<ChainGateway, 'httpRequestor' | 'dexBackendBaseUrl'> & {
|
|
2132
|
+
requestTimeoutMs?: number | undefined;
|
|
2133
|
+
wire?: WireOptions | undefined;
|
|
2134
|
+
};
|
|
1172
2135
|
/** Read-only quote service backed by the v2 offline quote engine. */
|
|
1173
2136
|
export declare class Quoting {
|
|
1174
|
-
private readonly
|
|
1175
|
-
private readonly http;
|
|
2137
|
+
private readonly gateway;
|
|
1176
2138
|
private readonly symbols;
|
|
1177
2139
|
/**
|
|
1178
2140
|
* Creates a quote service.
|
|
1179
2141
|
*
|
|
1180
2142
|
* @example
|
|
1181
2143
|
* ```ts
|
|
1182
|
-
* const quoting = new Quoting(
|
|
2144
|
+
* const quoting = new Quoting(gateway, symbols); // a ChainGateway, or any { dexBackendBaseUrl, httpRequestor }
|
|
1183
2145
|
* ```
|
|
1184
2146
|
*/
|
|
1185
|
-
constructor(
|
|
2147
|
+
constructor(gateway: QuoteGateway, symbols: TokenResolver);
|
|
2148
|
+
private readonly http;
|
|
1186
2149
|
/**
|
|
1187
2150
|
* Quotes the output for a positive exact-input amount.
|
|
1188
2151
|
*
|
|
@@ -1207,24 +2170,52 @@ export declare class Quoting {
|
|
|
1207
2170
|
}
|
|
1208
2171
|
//#endregion
|
|
1209
2172
|
//#region src/classes/swaps.d.ts
|
|
1210
|
-
export type SwapAmount = {
|
|
1211
|
-
exactIn: NumericAmount;
|
|
1212
|
-
exactOut?: undefined;
|
|
1213
|
-
amountOutMinimum?: NumericAmount | undefined;
|
|
1214
|
-
amountInMaximum?: undefined;
|
|
1215
|
-
} | {
|
|
1216
|
-
exactIn?: undefined;
|
|
1217
|
-
exactOut: NumericAmount;
|
|
1218
|
-
amountOutMinimum?: undefined;
|
|
1219
|
-
amountInMaximum?: NumericAmount | undefined;
|
|
1220
|
-
};
|
|
1221
2173
|
interface SwapGateway {
|
|
1222
2174
|
submit: (method: 'RequestTrade', signedBody: Record<string, unknown>, options?: ChainSubmitOptions) => Promise<SubmittedTransaction<AppliedTrade>>;
|
|
2175
|
+
submitShadow: (method: 'RequestTrade', signedBody: Record<string, unknown>, options?: ChainSubmitOptions) => Promise<ShadowSubmitResult>;
|
|
1223
2176
|
readonly dexBackendBaseUrl: string;
|
|
1224
2177
|
readonly httpRequestor: HttpRequestor;
|
|
1225
2178
|
readonly requestTimeoutMs: number;
|
|
2179
|
+
readonly wire?: WireOptions | undefined;
|
|
2180
|
+
}
|
|
2181
|
+
/** The canonical pool a swap trades in, as a quote names it. */
|
|
2182
|
+
export interface SwapPool {
|
|
2183
|
+
token0: string;
|
|
2184
|
+
token1: string;
|
|
2185
|
+
}
|
|
2186
|
+
/** Options of a swap. */
|
|
2187
|
+
export interface SwapOptions {
|
|
2188
|
+
/**
|
|
2189
|
+
* The attempt's `uniqueKey` (1-128 characters of `A-Za-z0-9._:-`). Default: a fresh
|
|
2190
|
+
* `<uniqueKeyPrefix><uuid>`. Supply one to know the key before signing (to remember it, to
|
|
2191
|
+
* show it), or to retry the SAME attempt after a lost response; never reuse it for another trade.
|
|
2192
|
+
*/
|
|
2193
|
+
uniqueKey?: string | undefined;
|
|
2194
|
+
/**
|
|
2195
|
+
* Pin the pool: take `token0` / `token1` verbatim from the quote the user saw, instead of
|
|
2196
|
+
* ordering `tokenIn` / `tokenOut` by string comparison. `tokenIn` and `tokenOut` must be exactly
|
|
2197
|
+
* these two symbols, and `token0` must sort before `token1`. See {@link swapRouteFromQuote}.
|
|
2198
|
+
*/
|
|
2199
|
+
pool?: SwapPool | undefined;
|
|
2200
|
+
}
|
|
2201
|
+
/** Everything {@link Swaps.swap} needs to trade in the pool a quote priced. */
|
|
2202
|
+
export interface SwapRoute {
|
|
2203
|
+
tokenIn: string;
|
|
2204
|
+
tokenOut: string;
|
|
2205
|
+
fee: FEE_TIER;
|
|
2206
|
+
pool: SwapPool;
|
|
1226
2207
|
}
|
|
1227
|
-
|
|
2208
|
+
/**
|
|
2209
|
+
* The route of a quote: its fee tier and pool, with `tokenIn` / `tokenOut` taken from
|
|
2210
|
+
* `tokenInIsToken0`, nothing re-derived. Use it to swap in exactly the pool a quote priced:
|
|
2211
|
+
*
|
|
2212
|
+
* @example
|
|
2213
|
+
* ```ts
|
|
2214
|
+
* const route = swapRouteFromQuote(quote);
|
|
2215
|
+
* await swaps.swap(route.tokenIn, route.tokenOut, route.fee, { exactIn: '100' }, { pool: route.pool });
|
|
2216
|
+
* ```
|
|
2217
|
+
*/
|
|
2218
|
+
export declare function swapRouteFromQuote(quote: Pick<QuoteResult, 'token0Symbol' | 'token1Symbol' | 'tokenInIsToken0' | 'fee'>): SwapRoute;
|
|
1228
2219
|
/** Executes queued current-contract RequestTrade operations through the Chain Gateway. */
|
|
1229
2220
|
export declare class Swaps {
|
|
1230
2221
|
private readonly gateway;
|
|
@@ -1239,7 +2230,8 @@ export declare class Swaps {
|
|
|
1239
2230
|
* const swaps = new Swaps(gateway, symbols, signer, 'client|alice');
|
|
1240
2231
|
* ```
|
|
1241
2232
|
*/
|
|
1242
|
-
constructor(gateway: SwapGateway, symbols:
|
|
2233
|
+
constructor(gateway: SwapGateway, symbols: TokenResolver, signer?: GalaChainSigner | undefined, walletAddress?: string | undefined, options?: UniqueKeyOptions);
|
|
2234
|
+
private readonly uniqueKeyPrefix;
|
|
1243
2235
|
/**
|
|
1244
2236
|
* Signs and submits an exact-input or exact-output RequestTrade DTO. The returned transaction
|
|
1245
2237
|
* is QUEUED; call `await tx.confirm()` to obtain the executed trade or chain rejection.
|
|
@@ -1252,7 +2244,54 @@ export declare class Swaps {
|
|
|
1252
2244
|
* });
|
|
1253
2245
|
* ```
|
|
1254
2246
|
*/
|
|
1255
|
-
swap(tokenIn: TokenRef, tokenOut: TokenRef, fee: FEE_TIER, amount: SwapAmount): Promise<SubmittedTransaction<AppliedTrade>>;
|
|
2247
|
+
swap(tokenIn: TokenRef, tokenOut: TokenRef, fee: FEE_TIER, amount: SwapAmount, options?: SwapOptions): Promise<SubmittedTransaction<AppliedTrade>>;
|
|
2248
|
+
/**
|
|
2249
|
+
* Signs and submits a SHADOW (dark) swap: the same RequestTrade as {@link swap}, relayed with
|
|
2250
|
+
* `X-Shadow: true` so defi-backend marks it private before it reaches the contract. Requires a
|
|
2251
|
+
* `walletAddress`. Resolves the normalized outcome instead of throwing on a gateway refusal:
|
|
2252
|
+
* `ok: false` carries `unavailable` (retryable), `disabled`, `rejected` (with the gateway's
|
|
2253
|
+
* message) or `unknown`. A success carries `queued`, to be confirmed with
|
|
2254
|
+
* `confirmSwap(queued.uniqueKey)`; never fall back to a public swap on failure.
|
|
2255
|
+
*
|
|
2256
|
+
* @example
|
|
2257
|
+
* ```ts
|
|
2258
|
+
* const outcome = await swaps.swapShadow('GALA', 'GUSDC', 3000, { exactIn: '100' });
|
|
2259
|
+
* if (outcome.ok && outcome.queued) await swaps.confirmSwap(outcome.queued.uniqueKey);
|
|
2260
|
+
* ```
|
|
2261
|
+
*/
|
|
2262
|
+
swapShadow(tokenIn: TokenRef, tokenOut: TokenRef, fee: FEE_TIER, amount: SwapAmount, options?: SwapOptions): Promise<ShadowSubmitOutcome>;
|
|
2263
|
+
/**
|
|
2264
|
+
* Builds the RequestTrade DTO that {@link swap} would sign, without signing or sending it: to
|
|
2265
|
+
* show in an approval popup, to remember its `uniqueKey`, or to sign elsewhere. Submit exactly
|
|
2266
|
+
* this DTO with {@link submitSwap}. The pure counterpart, with canonical inputs and no
|
|
2267
|
+
* resolution, is `buildRequestTradeDto`.
|
|
2268
|
+
*
|
|
2269
|
+
* @example
|
|
2270
|
+
* ```ts
|
|
2271
|
+
* const dto = await swaps.buildSwap('GALA', 'GUSDC', 3000, { exactIn: '100' });
|
|
2272
|
+
* showApproval(dto);
|
|
2273
|
+
* const submitted = await swaps.submitSwap(dto);
|
|
2274
|
+
* ```
|
|
2275
|
+
*/
|
|
2276
|
+
buildSwap(tokenIn: TokenRef, tokenOut: TokenRef, fee: FEE_TIER, amount: SwapAmount, options?: SwapOptions): Promise<RequestTradeDTO>;
|
|
2277
|
+
/**
|
|
2278
|
+
* Signs and submits a DTO built by {@link buildSwap} or `buildRequestTradeDto`. The DTO must be
|
|
2279
|
+
* exactly what the builder produces (no signature, canonical decimals, builder key order), so
|
|
2280
|
+
* what an app showed is what gets signed.
|
|
2281
|
+
*
|
|
2282
|
+
* @example
|
|
2283
|
+
* ```ts
|
|
2284
|
+
* const submitted = await swaps.submitSwap(dto);
|
|
2285
|
+
* const applied = await submitted.confirm();
|
|
2286
|
+
* ```
|
|
2287
|
+
*/
|
|
2288
|
+
submitSwap(dto: RequestTradeDTO): Promise<SubmittedTransaction<AppliedTrade>>;
|
|
2289
|
+
/** Signs and shadow-submits a DTO built by {@link buildSwap}; see {@link swapShadow}. */
|
|
2290
|
+
submitSwapShadow(dto: RequestTradeDTO): Promise<ShadowSubmitOutcome>;
|
|
2291
|
+
private submitOptions;
|
|
2292
|
+
private signRequestTrade;
|
|
2293
|
+
/** The pool's two symbols in contract order: the quote's own when pinned, else string order. */
|
|
2294
|
+
private orientPool;
|
|
1256
2295
|
/**
|
|
1257
2296
|
* Confirm a swap by its durable `uniqueKey` without resubmitting it. This is the recovery
|
|
1258
2297
|
* path after a `CONFIRMATION_TIMEOUT`, a `SUBMISSION_OUTCOME_UNKNOWN`, a `409` replay
|
|
@@ -1263,11 +2302,10 @@ export declare class Swaps {
|
|
|
1263
2302
|
*
|
|
1264
2303
|
* @example
|
|
1265
2304
|
* ```ts
|
|
1266
|
-
* const applied = await swaps.confirmSwap('
|
|
2305
|
+
* const applied = await swaps.confirmSwap('galaswap-operation-2f1c…');
|
|
1267
2306
|
* ```
|
|
1268
2307
|
*/
|
|
1269
2308
|
confirmSwap(uniqueKey: string, options?: ConfirmOptions): Promise<AppliedTrade>;
|
|
1270
|
-
private buildRequestTradeDto;
|
|
1271
2309
|
}
|
|
1272
2310
|
//#endregion
|
|
1273
2311
|
//#region src/types/env.d.ts
|
|
@@ -1290,11 +2328,37 @@ export interface GSwapOptions {
|
|
|
1290
2328
|
env?: GSwapEnv | undefined;
|
|
1291
2329
|
dexBackendBaseUrl?: string | undefined;
|
|
1292
2330
|
httpRequestor?: HttpRequestor | undefined;
|
|
2331
|
+
/** Request timeout in milliseconds (default 30 000); `Infinity` arms no timer. */
|
|
1293
2332
|
chainCallTimeoutMs?: number | undefined;
|
|
2333
|
+
/** Query encoding and `User-Agent` of the read requests (see {@link WireOptions}). */
|
|
2334
|
+
wire?: WireOptions | undefined;
|
|
2335
|
+
/**
|
|
2336
|
+
* How tokens are turned into trading symbols. `'registry'` (default) reads the symbol registry
|
|
2337
|
+
* once (`GET /v2/trade/symbols`, cached) and accepts symbols or class keys. `'canonical'` makes
|
|
2338
|
+
* no registry request: the caller passes the backend's canonical trading symbols (from a quote,
|
|
2339
|
+
* an estimate or a position), reads send tokens and ticks exactly as given (composite keys
|
|
2340
|
+
* included) and the backend orients the pair; see {@link CanonicalSymbols}.
|
|
2341
|
+
*/
|
|
2342
|
+
symbolResolution?: 'registry' | 'canonical' | undefined;
|
|
2343
|
+
/**
|
|
2344
|
+
* Told about every row of a pool, symbol or position list that was skipped as unusable (see
|
|
2345
|
+
* {@link InvalidEntryHandler}); without it such rows are skipped silently.
|
|
2346
|
+
*/
|
|
2347
|
+
onInvalidEntry?: InvalidEntryHandler | undefined;
|
|
1294
2348
|
/** Realtime stream endpoint. Defaults to the environment's, or is derived from `dexBackendBaseUrl`. */
|
|
1295
2349
|
dexBackendWsUrl?: string | undefined;
|
|
1296
2350
|
/** WebSocket constructor for the realtime stream; required on Node.js older than 22. */
|
|
1297
2351
|
webSocketImpl?: unknown;
|
|
2352
|
+
/**
|
|
2353
|
+
* `x-api-key` for the privileged stream view; server-side only, and it requires `webSocketImpl`
|
|
2354
|
+
* (see `GdexStreamConfig.apiKey`).
|
|
2355
|
+
*/
|
|
2356
|
+
streamApiKey?: string | undefined;
|
|
2357
|
+
/**
|
|
2358
|
+
* Prefix of every write's `uniqueKey` (`<prefix><uuid>`). Defaults to `galaswap-operation-`,
|
|
2359
|
+
* what frontend_v2 and wallet_extension send; defi-backend does not depend on it.
|
|
2360
|
+
*/
|
|
2361
|
+
uniqueKeyPrefix?: string | undefined;
|
|
1298
2362
|
}
|
|
1299
2363
|
/** Main entry point for the current GalaChainDex SDK. */
|
|
1300
2364
|
export declare class GSwap {
|
|
@@ -1309,8 +2373,11 @@ export declare class GSwap {
|
|
|
1309
2373
|
readonly positions: Positions;
|
|
1310
2374
|
readonly swaps: Swaps;
|
|
1311
2375
|
readonly assets: Assets;
|
|
2376
|
+
/** Network-fee quotes (DryRun) signed with this client's signer. */
|
|
2377
|
+
readonly fees: DexFees;
|
|
1312
2378
|
readonly dexBackendWsUrl: string;
|
|
1313
2379
|
private readonly webSocketImpl;
|
|
2380
|
+
private readonly streamApiKey;
|
|
1314
2381
|
private streamClient;
|
|
1315
2382
|
/**
|
|
1316
2383
|
* Create an SDK client for prod or stage.
|
|
@@ -1336,141 +2403,583 @@ export declare class GSwap {
|
|
|
1336
2403
|
get stream(): GdexStreamService;
|
|
1337
2404
|
}
|
|
1338
2405
|
//#endregion
|
|
1339
|
-
//#region src/classes/
|
|
1340
|
-
/**
|
|
1341
|
-
export declare
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
2406
|
+
//#region src/classes/pending_swaps.d.ts
|
|
2407
|
+
/** Key the wallet_extension has always used; its storage value is a plain array of entries. */
|
|
2408
|
+
export declare const PENDING_SWAPS_STORAGE_KEY = "pendingSwaps.v1";
|
|
2409
|
+
/** Entries older than this are dropped the next time a wallet's swaps are listed. */
|
|
2410
|
+
export declare const PENDING_SWAP_EXPIRY_MS: number;
|
|
2411
|
+
/**
|
|
2412
|
+
* Async key/value storage the pending-swap store persists through. It stores STRUCTURED VALUES
|
|
2413
|
+
* (the store never serializes), so each platform decides how a value lands on disk:
|
|
2414
|
+
*
|
|
2415
|
+
* - `chrome.storage.local`: `get: async (k) => (await chrome.storage.local.get(k))[k]`,
|
|
2416
|
+
* `set: (k, v) => chrome.storage.local.set({ [k]: v })`. This is the wallet's stored shape.
|
|
2417
|
+
* - `localStorage` (frontend_v2): `get: async (k) => { const raw = localStorage.getItem(k);
|
|
2418
|
+
* if (raw === null) return undefined; try { return JSON.parse(raw); } catch { return raw; } }`,
|
|
2419
|
+
* `set: async (k, v) => localStorage.setItem(k, JSON.stringify(v))`. Corrupt JSON MUST come back
|
|
2420
|
+
* as a value (here the raw string), not as a rejection: a value that is not an array reads as
|
|
2421
|
+
* "no entries" and the next write repairs it, whereas a `get` that rejects forever makes every
|
|
2422
|
+
* `remember` a no-op.
|
|
2423
|
+
* - React Native: AsyncStorage with the same JSON wrapping and the same corrupt-JSON rule.
|
|
2424
|
+
*
|
|
2425
|
+
* `get` resolves `undefined` for a missing key. Either method may reject; the store treats that
|
|
2426
|
+
* as "storage unavailable" and never lets it surface (see {@link PendingSwapStore}).
|
|
2427
|
+
*/
|
|
2428
|
+
export interface StorageAdapter {
|
|
2429
|
+
get(key: string): Promise<unknown>;
|
|
2430
|
+
set(key: string, value: unknown): Promise<void>;
|
|
2431
|
+
}
|
|
2432
|
+
/** A RequestTrade that was accepted by the gateway but whose outcome has not been read yet. */
|
|
2433
|
+
export interface PendingSwap {
|
|
2434
|
+
uniqueKey: string;
|
|
2435
|
+
requestTransactionId: string | null;
|
|
2436
|
+
/** The wallet (account) that submitted the swap; `list` filters by it. */
|
|
2437
|
+
wallet: string;
|
|
2438
|
+
token0Symbol: string;
|
|
2439
|
+
token1Symbol: string;
|
|
2440
|
+
/** Whether the swap was a shadow ("dark") swap. */
|
|
2441
|
+
isDarkSwap: boolean;
|
|
2442
|
+
/** Epoch milliseconds when the swap was queued. */
|
|
2443
|
+
createdAt: number;
|
|
2444
|
+
}
|
|
2445
|
+
/** Options for {@link PendingSwapStore}. */
|
|
2446
|
+
export interface PendingSwapStoreOptions {
|
|
2447
|
+
/** Storage key. Default {@link PENDING_SWAPS_STORAGE_KEY}. */
|
|
2448
|
+
storageKey?: string | undefined;
|
|
2449
|
+
/**
|
|
2450
|
+
* The stored name of the dark-swap flag. `isDarkSwap` (default) is wallet_extension's shape;
|
|
2451
|
+
* `shadow` is frontend_v2's. Entries are always exposed to callers as `isDarkSwap`.
|
|
2452
|
+
*/
|
|
2453
|
+
darkFlagField?: 'isDarkSwap' | 'shadow' | undefined;
|
|
2454
|
+
/**
|
|
2455
|
+
* Where `remember` puts a new entry in the stored array: `end` (default, wallet_extension) or
|
|
2456
|
+
* `start` (frontend_v2).
|
|
2457
|
+
*/
|
|
2458
|
+
insertAt?: 'end' | 'start' | undefined;
|
|
2459
|
+
/**
|
|
2460
|
+
* The order of `list`: `stored` (default, wallet_extension: oldest first for `insertAt: 'end'`)
|
|
2461
|
+
* or `newest-first` (frontend_v2).
|
|
2462
|
+
*/
|
|
2463
|
+
listOrder?: 'stored' | 'newest-first' | undefined;
|
|
2464
|
+
/** Clock, in epoch milliseconds. Defaults to `Date.now`. */
|
|
2465
|
+
now?: (() => number) | undefined;
|
|
2466
|
+
}
|
|
2467
|
+
/**
|
|
2468
|
+
* Remembers queued swaps so their outcome can be confirmed after the UI, popup or service worker
|
|
2469
|
+
* that submitted them is gone (`confirmAppliedTrade` with the stored `uniqueKey`).
|
|
2470
|
+
*
|
|
2471
|
+
* Guarantees:
|
|
2472
|
+
* - Persistence is best effort and NEVER throws: a failing or missing storage must not turn an
|
|
2473
|
+
* accepted request into a client-side resubmission. `list` resolves `[]` when storage fails.
|
|
2474
|
+
* - Operations of one store instance are serialized, so concurrent `remember` / `forget` calls
|
|
2475
|
+
* cannot lose each other's write (read-modify-write over an async adapter). Two store instances
|
|
2476
|
+
* over the same storage (for example popup and service worker) are not coordinated.
|
|
2477
|
+
* - Entries that do not match the expected shape are ignored and dropped on the next write.
|
|
2478
|
+
* - Entries expire after seven days (an entry exactly seven days old is expired; frontend_v2
|
|
2479
|
+
* kept it for that one millisecond); `list` removes them from storage, which frontend_v2 never
|
|
2480
|
+
* did on read.
|
|
2481
|
+
* - New entries go to the end (or `insertAt: 'start'`); `list` returns the wallet's entries in
|
|
2482
|
+
* stored order (or `listOrder: 'newest-first'`).
|
|
2483
|
+
* - The stored shape is wallet_extension's by default; `storageKey`, `darkFlagField`, `insertAt`
|
|
2484
|
+
* and `listOrder` reproduce frontend_v2's. JSON key order inside an entry is not preserved.
|
|
2485
|
+
*
|
|
2486
|
+
* Passing no `storage` yields a store that remembers nothing.
|
|
2487
|
+
*
|
|
2488
|
+
* @example
|
|
2489
|
+
* ```ts
|
|
2490
|
+
* const store = new PendingSwapStore({
|
|
2491
|
+
* get: async (key) => (await chrome.storage.local.get(key))[key],
|
|
2492
|
+
* set: (key, value) => chrome.storage.local.set({ [key]: value }),
|
|
2493
|
+
* });
|
|
2494
|
+
* await store.remember({ uniqueKey, requestTransactionId, wallet, token0Symbol: 'GALA',
|
|
2495
|
+
* token1Symbol: 'GUSDC', isDarkSwap: false, createdAt: Date.now() });
|
|
2496
|
+
* for (const swap of await store.list(wallet)) await confirmAppliedTrade(client, swap);
|
|
2497
|
+
* ```
|
|
2498
|
+
*/
|
|
2499
|
+
export declare class PendingSwapStore {
|
|
2500
|
+
private readonly storage;
|
|
2501
|
+
private readonly storageKey;
|
|
2502
|
+
private readonly darkFlagField;
|
|
2503
|
+
private readonly insertAt;
|
|
2504
|
+
private readonly listOrder;
|
|
2505
|
+
private readonly now;
|
|
2506
|
+
private queue;
|
|
2507
|
+
constructor(storage: StorageAdapter | undefined, options?: PendingSwapStoreOptions);
|
|
2508
|
+
/** Saves (or replaces, by `uniqueKey`) a pending swap. */
|
|
2509
|
+
remember(swap: PendingSwap): Promise<void>;
|
|
2510
|
+
/** Removes a pending swap once its outcome is known. */
|
|
2511
|
+
forget(uniqueKey: string): Promise<void>;
|
|
2512
|
+
/** The wallet's unexpired pending swaps (see `listOrder`). Expired entries are pruned. */
|
|
2513
|
+
list(wallet: string): Promise<PendingSwap[]>;
|
|
2514
|
+
private enqueue;
|
|
2515
|
+
private read;
|
|
2516
|
+
private readonly toStored;
|
|
2517
|
+
private fromStored;
|
|
1365
2518
|
}
|
|
1366
|
-
/** Narrow an object property without trusting a cast at a network boundary. */
|
|
1367
|
-
export declare function getObjectProperty(value: unknown, property: string): Record<string, unknown> | undefined;
|
|
1368
|
-
/** Read a string property from an unknown object. */
|
|
1369
|
-
export declare function getStringProperty(value: unknown, property: string): string | undefined;
|
|
1370
|
-
/** Parse a response body, preserving non-JSON text for error reporting. */
|
|
1371
|
-
export declare function parseJson(text: string): unknown;
|
|
1372
2519
|
//#endregion
|
|
1373
|
-
//#region src/
|
|
1374
|
-
/**
|
|
1375
|
-
|
|
2520
|
+
//#region src/utils/signing.d.ts
|
|
2521
|
+
/**
|
|
2522
|
+
* GalaChain's deterministic JSON: object keys sorted (UTF-16 code-unit order) at every depth, no
|
|
2523
|
+
* whitespace, `undefined`/function members dropped, `toJSON()` honored. Byte-identical to
|
|
2524
|
+
* `serialize` from `@gala-chain/api` / `json-stringify-deterministic` for every JSON-shaped
|
|
2525
|
+
* value, which is all a DTO ever is.
|
|
2526
|
+
*
|
|
2527
|
+
* @throws TypeError for circular structures and BigInt values (as `JSON.stringify` does) and
|
|
2528
|
+
* when the value itself has no JSON representation (`undefined`, a function, a symbol).
|
|
2529
|
+
*/
|
|
2530
|
+
export declare function serialize(value: unknown): string;
|
|
2531
|
+
/**
|
|
2532
|
+
* The exact string GalaChain hashes for a DTO: the (optional, string) `prefix` field PREPENDED to
|
|
2533
|
+
* the deterministic serialization of the DTO WITHOUT `signature`, `multisig`, `trace` and `prefix`.
|
|
2534
|
+
* Equivalent to `@gala-chain/api` 3.x `getPayloadToSign` for every non-EIP-712 DTO.
|
|
2535
|
+
*/
|
|
2536
|
+
export declare function getPayloadToSign(dto: Record<string, unknown>): string;
|
|
2537
|
+
/**
|
|
2538
|
+
* The EIP-191 header for `message`: `"\x19Ethereum Signed Message:\n"` + the message's UTF-8 BYTE
|
|
2539
|
+
* length. This is what a wallet's `personal_sign` prepends, and what the chain recomputes when it
|
|
2540
|
+
* recovers a personal-signed DTO.
|
|
2541
|
+
*/
|
|
2542
|
+
export declare function calculatePersonalSignPrefix(message: string): string;
|
|
2543
|
+
/**
|
|
2544
|
+
* The EIP-191 header for `serialize(dto)` (any `prefix` already on the DTO is ignored). This is
|
|
2545
|
+
* deliberately the same string the signers hand a wallet to sign, so the header's length can never
|
|
2546
|
+
* disagree with the signed message. Wallet-neutral: it is the value both a browser wallet's
|
|
2547
|
+
* `personal_sign` and Gala Wallet's `gala_signChainDto` (personal-sign scheme) prepend.
|
|
2548
|
+
*/
|
|
2549
|
+
export declare function personalSignPrefixFor(dto: Record<string, unknown>): string;
|
|
2550
|
+
/**
|
|
2551
|
+
* The `@gala-chain/connect`-style prefix frontend_v2 puts in the body of an EIP-712 write: the
|
|
2552
|
+
* EIP-191 header whose number counts the prefix string ITSELF plus the body (the UTF-8 length of
|
|
2553
|
+
* `getPayloadToSign({ ...dto, prefix })`), found by fixpoint because adding the prefix changes the
|
|
2554
|
+
* length (a body of 99 bytes settles on 101).
|
|
2555
|
+
*
|
|
2556
|
+
* It is NOT a personal-sign prefix (a personal-sign write with this value recovers a phantom
|
|
2557
|
+
* signer; use `personalSignPrefixFor`). Under EIP-712 the field is an untyped extra that the
|
|
2558
|
+
* typed-data hash ignores and defi-backend recomputes, so it only exists to keep the submitted
|
|
2559
|
+
* body byte-identical to what frontend_v2 has always sent.
|
|
2560
|
+
*/
|
|
2561
|
+
export declare function fixpointPrefixFor(dto: Record<string, unknown>): string;
|
|
2562
|
+
/**
|
|
2563
|
+
* Normalizes a secp256k1 private key to a fresh 32-byte array (the caller may zero it). Also
|
|
2564
|
+
* accepts 32 raw bytes, which are validated and copied. For strings it accepts what `@gala-chain/api`'s
|
|
2565
|
+
* `normalizePrivateKey` accepted for a usable key: 64 hex characters (optionally `0x`-prefixed;
|
|
2566
|
+
* a 63-character hex key is left-padded with a zero) or a 44-character base64 string.
|
|
2567
|
+
*
|
|
2568
|
+
* @throws GSwapSDKError (`VALIDATION_ERROR`) for any other shape or an out-of-range scalar.
|
|
2569
|
+
*/
|
|
2570
|
+
export declare function normalizePrivateKey(input: string | Uint8Array): Uint8Array;
|
|
2571
|
+
/**
|
|
2572
|
+
* The lowercase `0x` Ethereum address (last 20 bytes of keccak256 of the uncompressed public key)
|
|
2573
|
+
* of a normalized private key. The Gala `eth|` identity of a key is this address.
|
|
2574
|
+
*/
|
|
2575
|
+
export declare function ethAddressOfPrivateKey(privateKey: Uint8Array): string;
|
|
2576
|
+
/**
|
|
2577
|
+
* GalaChain NATIVE signature over an already-serialized DTO: keccak256 of the exact bytes, with no
|
|
2578
|
+
* prefix and no signature envelope. The caller owns serialization, so the bytes shown to a user
|
|
2579
|
+
* and the bytes signed can never diverge.
|
|
2580
|
+
*/
|
|
2581
|
+
export declare function signSerializedNative(privateKey: Uint8Array, serializedDto: string): string;
|
|
2582
|
+
/**
|
|
2583
|
+
* GalaChain NATIVE signature for a DTO: keccak256 of `getPayloadToSign(dto)`, signed with
|
|
2584
|
+
* secp256k1. Byte-identical to `signatures.getSignature` from `@gala-chain/api`.
|
|
2585
|
+
*/
|
|
2586
|
+
export declare function signNative(privateKey: Uint8Array, dto: Record<string, unknown>): string;
|
|
2587
|
+
/**
|
|
2588
|
+
* Personal-sign hash and signature: keccak256(`prefix` + `message`), both hashed VERBATIM with no
|
|
2589
|
+
* further EIP-191 wrapping. Passing `prefix = calculatePersonalSignPrefix(message)` reproduces a
|
|
2590
|
+
* wallet's `personal_sign` of `message`. Gala Wallet's `gala_signChainDto` (personal-sign
|
|
2591
|
+
* scheme) hashes `prefix` + the exact string it is handed, which can differ from the bare message
|
|
2592
|
+
* (see the `signatureOverPrefixlessBody` vectors); that quirk is why the two inputs stay separate.
|
|
2593
|
+
*/
|
|
2594
|
+
export declare function signPersonalMessage(privateKey: Uint8Array, prefix: string, message: string): string;
|
|
2595
|
+
//#endregion
|
|
2596
|
+
//#region src/utils/chain_dto_signing.d.ts
|
|
2597
|
+
/** A secp256k1 private key as a hex/base64 string or as raw 32 bytes. */
|
|
2598
|
+
type PrivateKeyInput = string | Uint8Array;
|
|
2599
|
+
/**
|
|
2600
|
+
* Runs `action` with a private normalized copy of the key, zeroed afterwards (also when `action`
|
|
2601
|
+
* throws). Bytes given by the caller are copied, never modified: the caller owns them.
|
|
2602
|
+
*/
|
|
2603
|
+
export declare function withPrivateKey<T>(privateKey: PrivateKeyInput, action: (key: Uint8Array) => T): T;
|
|
2604
|
+
/**
|
|
2605
|
+
* GalaChain NATIVE signature over an already-serialized DTO: keccak256 of the exact bytes with no
|
|
2606
|
+
* prefix and no envelope (wallet `signChainDtoNative`). The caller owns serialization, so the
|
|
2607
|
+
* bytes a user reviewed and the bytes signed cannot diverge.
|
|
2608
|
+
*
|
|
2609
|
+
* @returns 130 lowercase hex characters, `r || s || v` with `v` = `1b`/`1c`, no `0x`.
|
|
2610
|
+
*/
|
|
2611
|
+
export declare function signChainDtoNative(privateKey: PrivateKeyInput, serializedDto: string): string;
|
|
2612
|
+
/**
|
|
2613
|
+
* The personal-sign hash primitive (wallet `signChainDtoHash`): keccak256(`prefix` + `message`),
|
|
2614
|
+
* both verbatim, with no further EIP-191 wrap. `message` must be the DTO's serialization WITHOUT
|
|
2615
|
+
* its `prefix` field; callers holding a dApp-supplied string go through `signChainDtoPersonalSign`,
|
|
2616
|
+
* which derives both inputs from it.
|
|
2617
|
+
*/
|
|
2618
|
+
export declare function signChainDtoHash(privateKey: PrivateKeyInput, prefix: string, message: string): string;
|
|
2619
|
+
/** What a `gala_signChainDto` personal-sign request hashes. */
|
|
2620
|
+
interface PersonalSignChainDtoPayload {
|
|
2621
|
+
/** The `prefix` the chain prepends: the DTO's own `prefix` field, or `''` when it has none. */
|
|
2622
|
+
prefix: string;
|
|
2623
|
+
/** The exact message hashed after `prefix`. */
|
|
2624
|
+
message: string;
|
|
2625
|
+
}
|
|
2626
|
+
/**
|
|
2627
|
+
* Derives what to hash for a `gala_signChainDto` personal-sign request from the exact string the
|
|
2628
|
+
* dApp sent (and the approval card displayed): wallet `resolvePersonalSignChainDtoPayload`.
|
|
2629
|
+
*
|
|
2630
|
+
* The dApp submits `{ ...dto, prefix, signature }`, which the chain recovers from
|
|
2631
|
+
* `keccak256(prefix + serialize(dto WITHOUT prefix))`. So when the string embeds a `prefix`
|
|
2632
|
+
* field, that field is removed and the remainder re-serialized; the prefix used is the dApp's own
|
|
2633
|
+
* value byte for byte. A string with no `prefix` field is hashed verbatim with an empty prefix
|
|
2634
|
+
* (chain-equivalent to a native signature of that exact string).
|
|
2635
|
+
*
|
|
2636
|
+
* Fails closed (throws `GSwapSDKError` `INVALID_PERSONAL_SIGN_DTO`, message text identical to the
|
|
2637
|
+
* wallet's) on: malformed JSON; JSON that is not a plain object; a `prefix` that is not an EIP-191
|
|
2638
|
+
* "Ethereum Signed Message" header; any signing-envelope field (`signature`, `multisig`, `trace`,
|
|
2639
|
+
* `types`, `domain`, `stringsInstructions`); and a string that is not already the canonical
|
|
2640
|
+
* serialization of what it parses to (duplicate keys, lossy numbers, key-order tricks the card
|
|
2641
|
+
* would render differently). Stripping `prefix` is therefore the ONLY byte change between the
|
|
2642
|
+
* reviewed string and the signed message.
|
|
2643
|
+
*/
|
|
2644
|
+
export declare function resolvePersonalSignChainDtoPayload(data: string): PersonalSignChainDtoPayload;
|
|
2645
|
+
/**
|
|
2646
|
+
* Signs a GalaChain personal-sign scheme DTO from the exact string a dApp sent through
|
|
2647
|
+
* `gala_signChainDto` (wallet `signChainDtoPersonalSign`). See
|
|
2648
|
+
* `resolvePersonalSignChainDtoPayload` for what is signed and what is refused; the signature
|
|
2649
|
+
* recovers, under the chain's `getPayloadToSign`, to this key for the DTO the dApp submits with
|
|
2650
|
+
* its `prefix`, and equals a `personal_sign` of the bare body when that prefix is the EIP-191
|
|
2651
|
+
* header of the bare body's byte length.
|
|
2652
|
+
*
|
|
2653
|
+
* @throws GSwapSDKError (`INVALID_PERSONAL_SIGN_DTO`) before any signing when the input is refused.
|
|
2654
|
+
*/
|
|
2655
|
+
export declare function signChainDtoPersonalSign(privateKey: PrivateKeyInput, data: string): string;
|
|
2656
|
+
/**
|
|
2657
|
+
* Raw object signing (wallet `signObject`), used for transfers, bridge and fee-dry-run DTOs the
|
|
2658
|
+
* wallet signs itself. Removes ONLY `signature`, signs `keccak256(serialize(rest))` natively
|
|
2659
|
+
* (no `prefix` handling, and `trace` / `multisig` stay in the signed bytes, unlike
|
|
2660
|
+
* `signNative`), and returns `{ signature, ...rest }` with the signature as the FIRST key, exactly
|
|
2661
|
+
* like the wallet. Callers that must not sign extra fields strip them first.
|
|
2662
|
+
*/
|
|
2663
|
+
export declare function signRawObject(privateKey: PrivateKeyInput, obj: Record<string, unknown>): {
|
|
2664
|
+
signature: string;
|
|
2665
|
+
} & Record<string, unknown>;
|
|
2666
|
+
/**
|
|
2667
|
+
* Drops the `EIP712Domain` entry from a dApp-supplied types map (a typed-data encoder derives the
|
|
2668
|
+
* domain type itself and rejects an explicit one). The order of the remaining types is preserved.
|
|
2669
|
+
*/
|
|
2670
|
+
export declare function stripEip712DomainType<T>(types: Record<string, T>): Record<string, T>;
|
|
2671
|
+
/**
|
|
2672
|
+
* `collection$category$type$additionalKey` for a token-class object (wallet `decodeTokenData`).
|
|
2673
|
+
* Lenient on purpose: any missing or non-string part becomes `''`, so a display layer never
|
|
2674
|
+
* throws on odd input.
|
|
2675
|
+
*/
|
|
2676
|
+
export declare function tokenClassDollarKey(token: Record<string, unknown> | null | undefined): string;
|
|
2677
|
+
/**
|
|
2678
|
+
* A quantity in the form GalaChain's `IsBigNumber` validator accepts: FIXED notation, no leading
|
|
2679
|
+
* zeros, no trailing decimal zeros (`BigNumber#toFixed()`; never `toString()`, which turns
|
|
2680
|
+
* `0.00000001` into `1e-8`, and never a JS number in between).
|
|
2681
|
+
*
|
|
2682
|
+
* @throws GSwapSDKError (`VALIDATION_ERROR`) for a value that is not a finite number. The wallet's
|
|
2683
|
+
* `cleanNumber` returned the string `'NaN'` there; signing that text can only fail on chain.
|
|
2684
|
+
*/
|
|
2685
|
+
export declare function canonicalDecimalString(value: string | number): string;
|
|
2686
|
+
//#endregion
|
|
2687
|
+
//#region src/utils/eip712.d.ts
|
|
2688
|
+
type EIP712Types = Record<string, Array<{
|
|
2689
|
+
name: string;
|
|
2690
|
+
type: string;
|
|
2691
|
+
}>>;
|
|
2692
|
+
/**
|
|
2693
|
+
* Derives the EIP-712 `types` for a DTO from its runtime shape.
|
|
2694
|
+
*
|
|
2695
|
+
* The generated `types` travel with the signed payload and are what BOTH sides hash, so they
|
|
2696
|
+
* must enumerate EVERY field the chain-side DTO will carry. GalaChain refuses any signature
|
|
2697
|
+
* whose `types` leave a DTO field uncovered (`assertNoUnsignedFields`, the fix for the
|
|
2698
|
+
* 2026-08-18 unsigned-field-injection drain); when that happens signature recovery fails
|
|
2699
|
+
* outright and the chain reports "Missing signerPublicKey or signerAddress field in dto".
|
|
2700
|
+
*/
|
|
2701
|
+
export declare function generateEIP712Types(typeName: string, params: Record<string, unknown>): EIP712Types;
|
|
2702
|
+
/** The EIP-712 domain carried by a signed payload: GalaChain only uses `name` and `chainId`. */
|
|
2703
|
+
interface EIP712DomainValue {
|
|
2704
|
+
name: string;
|
|
2705
|
+
chainId: number;
|
|
2706
|
+
}
|
|
2707
|
+
/**
|
|
2708
|
+
* Builds the EIP-712 domain from the wallet's LIVE `eth_chainId` result, exactly like frontend_v2
|
|
2709
|
+
* (DEFI-1895): a wallet hashes whatever domain it is handed, and MetaMask refuses a `chainId` that
|
|
2710
|
+
* differs from its active network, so a hardcoded `1` breaks every wallet that is not on Mainnet.
|
|
2711
|
+
* defi-backend recovers the signer from the `domain` the payload carries (live-proven for chain
|
|
2712
|
+
* ids 1, 56 and 11155111), so following the wallet is correct on every network.
|
|
2713
|
+
*
|
|
2714
|
+
* @param chainId - The raw `eth_chainId` result: a `0x` hex string (the JSON-RPC form) or an integer.
|
|
2715
|
+
* @throws GSwapSDKError (`INVALID_CHAIN_ID`) when the wallet answers with anything else.
|
|
2716
|
+
*/
|
|
2717
|
+
export declare function eip712DomainFor(chainId: unknown): EIP712DomainValue;
|
|
2718
|
+
/**
|
|
2719
|
+
* The four v2 operations proven to recover the signer correctly via genuine EIP-712: `RequestTrade`
|
|
2720
|
+
* never had the problem (one numeric field). `AddLiquidity`/`RemoveLiquidity`/
|
|
2721
|
+
* `CollectPositionFees` each need their `types` completed with a handful of fields their real
|
|
2722
|
+
* server-side DTO always carries — see the `complete*Fields` functions below. `CreatePool` is a
|
|
2723
|
+
* genuinely different, unsolved problem (nested `TokenClassKey` structs, not a flat
|
|
2724
|
+
* missing-field gap) and is NOT in this set — callers must keep using `personal-sign` for it.
|
|
2725
|
+
*/
|
|
2726
|
+
export declare const EIP712_CAPABLE_METHODS: ReadonlySet<string>;
|
|
2727
|
+
/**
|
|
2728
|
+
* Completes a DTO's fields for EIP-712 signing (a no-op for methods with no known gap, e.g.
|
|
2729
|
+
* `RequestTrade`) and derives its `types`. Exported separately from the signing call itself so tests
|
|
2730
|
+
* can assert on the exact payload without needing a live provider.
|
|
2731
|
+
*/
|
|
2732
|
+
export declare function buildEIP712Payload(methodName: string, dto: Record<string, unknown>): {
|
|
2733
|
+
completedDto: Record<string, unknown>;
|
|
2734
|
+
types: EIP712Types;
|
|
2735
|
+
};
|
|
2736
|
+
//#endregion
|
|
2737
|
+
//#region src/utils/typed_data.d.ts
|
|
2738
|
+
/** A typed-data payload as `eth_signTypedData_v4` carries it, minus `primaryType` (it is inferred). */
|
|
2739
|
+
interface TypedDataPayload {
|
|
2740
|
+
domain: Record<string, unknown>;
|
|
2741
|
+
/** Struct definitions WITHOUT `EIP712Domain` (see `stripEip712DomainType`). */
|
|
2742
|
+
types: Record<string, readonly unknown[]>;
|
|
2743
|
+
message: Record<string, unknown>;
|
|
2744
|
+
}
|
|
2745
|
+
/**
|
|
2746
|
+
* The EIP-712 digest `keccak256(0x1901 || domainSeparator || hashStruct(primaryType, message))`
|
|
2747
|
+
* that a wallet signs for `eth_signTypedData_v4`. The primary type is inferred, as ethers does.
|
|
2748
|
+
*
|
|
2749
|
+
* @throws GSwapSDKError (`INVALID_TYPED_DATA`) for any type graph or value it cannot encode
|
|
2750
|
+
* exactly (see the module note on strictness).
|
|
2751
|
+
*/
|
|
2752
|
+
export declare function hashTypedData(payload: TypedDataPayload): Uint8Array;
|
|
2753
|
+
/**
|
|
2754
|
+
* Signs a dApp's EIP-712 typed-data approval (the wallet's `signTypedMessage` path), replacing
|
|
2755
|
+
* `new ethers.Wallet(key).signTypedData(domain, types, message)`. `types` must already have
|
|
2756
|
+
* `EIP712Domain` removed (`stripEip712DomainType`).
|
|
2757
|
+
*
|
|
2758
|
+
* @returns `0x` + r + s + v with `v` = `0x1b`/`0x1c` (27/28): ethers' serialized signature form,
|
|
2759
|
+
* recoverable with `verifyTypedData` / `eth_signTypedData_v4` verifiers. Rejects (never throws
|
|
2760
|
+
* synchronously) on invalid input.
|
|
2761
|
+
*/
|
|
2762
|
+
export declare function signTypedDataPayload(privateKey: PrivateKeyInput, payload: TypedDataPayload): Promise<string>;
|
|
2763
|
+
//#endregion
|
|
2764
|
+
//#region src/utils/dto_builders.d.ts
|
|
2765
|
+
/** The pool a RequestTrade trades in, its fee tier, the `uniqueKey` and what is traded. */
|
|
2766
|
+
type RequestTradeInput = {
|
|
2767
|
+
/** Canonical pool symbols: `token0 < token1`. Take them from a quote verbatim. */
|
|
1376
2768
|
token0: string;
|
|
1377
2769
|
token1: string;
|
|
1378
|
-
fee:
|
|
2770
|
+
fee: number;
|
|
2771
|
+
/** Which side of the pool is sold: `true` when the input token is `token0`. */
|
|
2772
|
+
tokenInIsToken0: boolean;
|
|
1379
2773
|
uniqueKey: string;
|
|
1380
|
-
}
|
|
1381
|
-
/**
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
amountOutMinimum?: string | undefined;
|
|
1404
|
-
amountInMaximum?: string | undefined;
|
|
1405
|
-
};
|
|
1406
|
-
/** A v2 liquidity deposit with exactly one selected deposit quantity. */
|
|
1407
|
-
export type AddLiquidityDTO = V2PoolWriteBase & {
|
|
1408
|
-
tickLower: number;
|
|
1409
|
-
tickUpper: number;
|
|
1410
|
-
} & ({
|
|
1411
|
-
depositQuantityToken0: string;
|
|
1412
|
-
depositQuantityToken1?: never;
|
|
1413
|
-
} | {
|
|
1414
|
-
depositQuantityToken0?: never;
|
|
1415
|
-
depositQuantityToken1: string;
|
|
1416
|
-
});
|
|
1417
|
-
/** A v2 liquidity withdrawal; omitting both quantities closes the position. */
|
|
1418
|
-
export type RemoveLiquidityDTO = V2PoolWriteBase & {
|
|
2774
|
+
} & SwapAmount;
|
|
2775
|
+
/**
|
|
2776
|
+
* Builds the RequestTrade DTO: `exactIn` sells that much of the input token (`sell0Qty` or
|
|
2777
|
+
* `sell1Qty`), `exactOut` buys that much of the output token (`buy1Qty` or `buy0Qty`), plus the
|
|
2778
|
+
* side's slippage bound and an optional `priceLimit`. Key order: `token0, token1, fee, uniqueKey,
|
|
2779
|
+
* <quantity>, amountOutMinimum | amountInMaximum, priceLimit`.
|
|
2780
|
+
*
|
|
2781
|
+
* @example
|
|
2782
|
+
* ```ts
|
|
2783
|
+
* const dto = buildRequestTradeDto({
|
|
2784
|
+
* token0: quote.token0Symbol, token1: quote.token1Symbol,
|
|
2785
|
+
* tokenInIsToken0: quote.tokenInIsToken0, fee: quote.fee,
|
|
2786
|
+
* uniqueKey: createUniqueKey('galaswap-operation-'),
|
|
2787
|
+
* exactIn: '100', amountOutMinimum: '14',
|
|
2788
|
+
* });
|
|
2789
|
+
* ```
|
|
2790
|
+
*/
|
|
2791
|
+
export declare function buildRequestTradeDto(input: RequestTradeInput): RequestTradeDTO;
|
|
2792
|
+
/** A canonical pool position: the pair, fee tier, tick range and the attempt's `uniqueKey`. */
|
|
2793
|
+
interface PoolPositionInput {
|
|
2794
|
+
token0: string;
|
|
2795
|
+
token1: string;
|
|
2796
|
+
fee: number;
|
|
1419
2797
|
tickLower: number;
|
|
1420
2798
|
tickUpper: number;
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
2799
|
+
uniqueKey: string;
|
|
2800
|
+
}
|
|
2801
|
+
/** Exactly one canonical deposit side. */
|
|
2802
|
+
type AddLiquidityInput = PoolPositionInput & ({
|
|
2803
|
+
depositQuantityToken0: NumericAmount;
|
|
2804
|
+
depositQuantityToken1?: undefined;
|
|
1427
2805
|
} | {
|
|
1428
|
-
|
|
1429
|
-
|
|
2806
|
+
depositQuantityToken0?: undefined;
|
|
2807
|
+
depositQuantityToken1: NumericAmount;
|
|
1430
2808
|
});
|
|
1431
|
-
/**
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
2809
|
+
/**
|
|
2810
|
+
* Builds the AddLiquidity DTO: exactly one of `depositQuantityToken0` / `depositQuantityToken1`
|
|
2811
|
+
* (the other side is derived on chain). Key order: `token0, token1, fee, tickLower, tickUpper,
|
|
2812
|
+
* uniqueKey, <deposit>`.
|
|
2813
|
+
*/
|
|
2814
|
+
export declare function buildAddLiquidityDto(input: AddLiquidityInput): AddLiquidityDTO;
|
|
2815
|
+
/** At most one canonical withdrawal side; neither closes the position. */
|
|
2816
|
+
type RemoveLiquidityInput = PoolPositionInput & {
|
|
2817
|
+
withdrawalQuantityToken0?: NumericAmount | undefined;
|
|
2818
|
+
withdrawalQuantityToken1?: NumericAmount | undefined;
|
|
2819
|
+
};
|
|
2820
|
+
/**
|
|
2821
|
+
* Builds the RemoveLiquidity DTO: at most one of `withdrawalQuantityToken0` /
|
|
2822
|
+
* `withdrawalQuantityToken1`; omitting both closes the position and sweeps its fees.
|
|
2823
|
+
*/
|
|
2824
|
+
export declare function buildRemoveLiquidityDto(input: RemoveLiquidityInput): RemoveLiquidityDTO;
|
|
2825
|
+
/** Builds the CollectPositionFees DTO (the contract sweeps all of a position's fees). */
|
|
2826
|
+
export declare function buildCollectPositionFeesDto(input: PoolPositionInput): CollectPositionFeesDTO;
|
|
2827
|
+
/** A CreatePool in canonical orientation, with exactly one starting price. */
|
|
2828
|
+
type CreatePoolInput = {
|
|
1438
2829
|
token0Key: GalaChainTokenClassKey;
|
|
1439
2830
|
token1Key: GalaChainTokenClassKey;
|
|
2831
|
+
/** The symbols to register; `token0Symbol < token1Symbol` and both proposable. */
|
|
1440
2832
|
token0Symbol: string;
|
|
1441
2833
|
token1Symbol: string;
|
|
1442
|
-
fee:
|
|
2834
|
+
fee: number;
|
|
2835
|
+
/** Optional display name; omitted when undefined or empty. */
|
|
2836
|
+
name?: string | undefined;
|
|
1443
2837
|
isPrivate?: boolean | undefined;
|
|
1444
2838
|
privateAccess?: string[] | undefined;
|
|
1445
2839
|
uniqueKey: string;
|
|
1446
2840
|
} & ({
|
|
1447
|
-
startingPrice:
|
|
1448
|
-
startingSqrtPrice?:
|
|
2841
|
+
startingPrice: NumericAmount;
|
|
2842
|
+
startingSqrtPrice?: undefined;
|
|
1449
2843
|
} | {
|
|
1450
|
-
startingPrice?:
|
|
1451
|
-
startingSqrtPrice:
|
|
2844
|
+
startingPrice?: undefined;
|
|
2845
|
+
startingSqrtPrice: NumericAmount;
|
|
1452
2846
|
});
|
|
1453
|
-
/**
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
2847
|
+
/**
|
|
2848
|
+
* Builds the CreatePool DTO. Key order: `token0Key, token1Key, fee, startingPrice |
|
|
2849
|
+
* startingSqrtPrice, token0Symbol, token1Symbol, uniqueKey, name, isPrivate, privateAccess`.
|
|
2850
|
+
* Prices are those of the canonical pair (token1 per token0); a price quoted the other way round
|
|
2851
|
+
* is inverted by the caller before it gets here.
|
|
2852
|
+
*/
|
|
2853
|
+
export declare function buildCreatePoolDto(input: CreatePoolInput): CreatePoolDTO;
|
|
2854
|
+
/** The methods whose DTOs the builders produce. */
|
|
2855
|
+
type V2WriteMethod = 'RequestTrade' | 'AddLiquidity' | 'RemoveLiquidity' | 'CollectPositionFees' | 'CreatePool';
|
|
2856
|
+
/**
|
|
2857
|
+
* Asserts that `dto` is EXACTLY what the builder of `method` produces for its own fields — the
|
|
2858
|
+
* same fields, canonical decimal text, builder key order, nothing extra (no `signature`). The
|
|
2859
|
+
* `submit*` methods use it so that what an app showed a user (a DTO it built) is byte for byte
|
|
2860
|
+
* what gets signed; a DTO edited by hand, or built elsewhere, is refused rather than signed.
|
|
2861
|
+
*
|
|
2862
|
+
* @throws GSwapSDKError VALIDATION_ERROR (`details.type` = `INVALID_DTO` or `DTO_NOT_CANONICAL`).
|
|
2863
|
+
*/
|
|
2864
|
+
export declare function assertCanonicalV2Dto(method: V2WriteMethod, dto: Record<string, unknown>): void;
|
|
2865
|
+
//#endregion
|
|
2866
|
+
//#region src/utils/axios_requestor.d.ts
|
|
2867
|
+
/** What the adapter reads of an axios response. */
|
|
2868
|
+
export interface AxiosLikeResponse {
|
|
2869
|
+
status: number;
|
|
2870
|
+
data?: unknown;
|
|
2871
|
+
/** axios' `AxiosHeaders` (has `get`) or a plain header record. */
|
|
2872
|
+
headers?: unknown;
|
|
1457
2873
|
}
|
|
1458
|
-
/**
|
|
1459
|
-
export
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
token1: string;
|
|
1464
|
-
fee: FEE_TIER;
|
|
2874
|
+
/** The request config the adapter hands to axios. */
|
|
2875
|
+
export interface AxiosLikeConfig {
|
|
2876
|
+
headers: Record<string, string>;
|
|
2877
|
+
signal?: AbortSignal;
|
|
2878
|
+
validateStatus?: () => boolean;
|
|
1465
2879
|
}
|
|
1466
|
-
/**
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
2880
|
+
/**
|
|
2881
|
+
* The part of an axios instance the adapter calls. Declared structurally, so the SDK takes no
|
|
2882
|
+
* dependency on axios and any axios instance (with its interceptors) satisfies it.
|
|
2883
|
+
*/
|
|
2884
|
+
export interface AxiosLikeInstance {
|
|
2885
|
+
get(url: string, config?: AxiosLikeConfig): Promise<unknown>;
|
|
2886
|
+
post(url: string, data?: unknown, config?: AxiosLikeConfig): Promise<unknown>;
|
|
2887
|
+
}
|
|
2888
|
+
/** Options of {@link httpRequestorFromAxios}. */
|
|
2889
|
+
export interface AxiosRequestorOptions {
|
|
2890
|
+
/**
|
|
2891
|
+
* `true`: leave axios' default status validation alone, so a 4xx/5xx REJECTS through the
|
|
2892
|
+
* instance's own interceptors and the SDK rethrows what the app's error handling produced.
|
|
2893
|
+
* `false`: every HTTP status resolves, so the SDK classifies it itself (shadow submits,
|
|
2894
|
+
* apply-results reads); transport failures still reject.
|
|
2895
|
+
*/
|
|
2896
|
+
rejectOnHttpError: boolean;
|
|
2897
|
+
/**
|
|
2898
|
+
* Request headers NOT to hand to axios, matched case-insensitively. Default `['content-type']`:
|
|
2899
|
+
* axios derives `Content-Type: application/json` from the object body it is given, and an
|
|
2900
|
+
* interceptor may set its own, so the SDK's copy would only be a second opinion.
|
|
2901
|
+
*/
|
|
2902
|
+
omitHeaders?: readonly string[] | undefined;
|
|
2903
|
+
}
|
|
2904
|
+
/**
|
|
2905
|
+
* An SDK {@link HttpRequestor} over an axios instance, so the SDK's requests travel through the
|
|
2906
|
+
* app's own base URL, interceptors and error handling.
|
|
2907
|
+
*
|
|
2908
|
+
* A POST's string body is parsed back to the object the SDK serialized it from (axios serializes
|
|
2909
|
+
* again, and an interceptor may read the object); a GET goes through `instance.get`. The answer
|
|
2910
|
+
* is an HTTP response whose `json()`/`text()` read `response.data`. An answer that is not an
|
|
2911
|
+
* axios response is a `TRANSPORT_ERROR` rejection.
|
|
2912
|
+
*
|
|
2913
|
+
* Pair it with `ChainGateway`'s `dexBackendBaseUrl: ''` when the instance owns the base URL.
|
|
2914
|
+
*
|
|
2915
|
+
* @example
|
|
2916
|
+
* ```ts
|
|
2917
|
+
* const submitGateway = new ChainGateway({
|
|
2918
|
+
* dexBackendBaseUrl: '',
|
|
2919
|
+
* httpRequestor: httpRequestorFromAxios(chainGatewayInstance, { rejectOnHttpError: true }),
|
|
2920
|
+
* });
|
|
2921
|
+
* ```
|
|
2922
|
+
*/
|
|
2923
|
+
export declare function httpRequestorFromAxios(instance: AxiosLikeInstance, options: AxiosRequestorOptions): HttpRequestor;
|
|
2924
|
+
//#endregion
|
|
2925
|
+
//#region src/utils/ethers_provider.d.ts
|
|
2926
|
+
/**
|
|
2927
|
+
* The part of an ethers v6 signer (`JsonRpcSigner`, `Wallet`) the adapter calls. Declared
|
|
2928
|
+
* structurally, so the SDK takes no dependency on ethers and an ethers object satisfies it as is.
|
|
2929
|
+
*/
|
|
2930
|
+
export interface EthersLikeSigner {
|
|
2931
|
+
signTypedData(domain: Record<string, unknown>, types: Record<string, Array<{
|
|
2932
|
+
name: string;
|
|
2933
|
+
type: string;
|
|
2934
|
+
}>>, value: Record<string, unknown>): Promise<string>;
|
|
2935
|
+
signMessage(message: string): Promise<string>;
|
|
2936
|
+
}
|
|
2937
|
+
/** The part of an ethers v6 provider (`BrowserProvider`) the adapter calls. */
|
|
2938
|
+
export interface EthersLikeProvider {
|
|
2939
|
+
getSigner(): Promise<EthersLikeSigner>;
|
|
2940
|
+
/** The raw JSON-RPC passthrough (`BrowserProvider.send`). */
|
|
2941
|
+
send(method: string, params: unknown[]): Promise<unknown>;
|
|
2942
|
+
}
|
|
2943
|
+
/** Options of {@link eip1193ProviderFromEthers}. */
|
|
2944
|
+
export interface EthersEip1193Options {
|
|
2945
|
+
/**
|
|
2946
|
+
* Signs a `personal_sign` message when the provider cannot or should not: a wallet SDK that
|
|
2947
|
+
* signs through its own object (TrustWallet's `web3Wallet.signMessage`). When set it answers
|
|
2948
|
+
* every `personal_sign`, and the provider is not touched for it.
|
|
2949
|
+
*/
|
|
2950
|
+
personalSign?: ((message: string) => Promise<string>) | undefined;
|
|
2951
|
+
/**
|
|
2952
|
+
* The message of the `WALLET_UNAVAILABLE` error raised when a request needs the provider and
|
|
2953
|
+
* there is none (no wallet connected). Default: "No wallet is connected."
|
|
2954
|
+
*/
|
|
2955
|
+
unavailableMessage?: string | undefined;
|
|
1473
2956
|
}
|
|
2957
|
+
/**
|
|
2958
|
+
* An EIP-1193 provider over an ethers v6 provider, for {@link BrowserWalletSigner}: apps whose
|
|
2959
|
+
* wallet connection is an ethers `BrowserProvider` sign through the very ethers calls they always
|
|
2960
|
+
* made, with no hand-written shim.
|
|
2961
|
+
*
|
|
2962
|
+
* - `eth_chainId` is `provider.send('eth_chainId', [])`: the wallet's LIVE chain. Never
|
|
2963
|
+
* `provider.getNetwork()`, which ethers caches and does not invalidate on `chainChanged`, so a
|
|
2964
|
+
* user who switches networks after connecting would sign against a stale chainId.
|
|
2965
|
+
* - `eth_signTypedData_v4` parses the `[account, JSON]` params and calls
|
|
2966
|
+
* `signer.signTypedData(domain, types, message)` with `EIP712Domain` removed from `types`.
|
|
2967
|
+
* - `personal_sign` is `options.personalSign(message)` when given, else `signer.signMessage`.
|
|
2968
|
+
* - Anything else is `UNSUPPORTED_WALLET_METHOD`; a malformed request is
|
|
2969
|
+
* `MALFORMED_WALLET_REQUEST`; a missing provider is `WALLET_UNAVAILABLE`.
|
|
2970
|
+
*
|
|
2971
|
+
* `provider` may be `null`/`undefined` (nothing connected): a request that needs it then fails
|
|
2972
|
+
* with `WALLET_UNAVAILABLE` rather than at construction, so a signer can be built before the
|
|
2973
|
+
* connection state is known.
|
|
2974
|
+
*
|
|
2975
|
+
* @example
|
|
2976
|
+
* ```ts
|
|
2977
|
+
* const signer = new BrowserWalletSigner(eip1193ProviderFromEthers(browserProvider), account, {
|
|
2978
|
+
* scheme: 'eip712',
|
|
2979
|
+
* });
|
|
2980
|
+
* ```
|
|
2981
|
+
*/
|
|
2982
|
+
export declare function eip1193ProviderFromEthers(provider: EthersLikeProvider | null | undefined, options?: EthersEip1193Options): BrowserWalletProvider;
|
|
1474
2983
|
//#endregion
|
|
1475
2984
|
//#region src/utils/ticks.d.ts
|
|
1476
2985
|
/** Minimum tick supported by GalaChainDex. */
|
|
@@ -1489,6 +2998,32 @@ export declare function alignTickDown(tick: number, spacing: number): number;
|
|
|
1489
2998
|
export declare function alignTickUp(tick: number, spacing: number): number;
|
|
1490
2999
|
/** Validate a position range against the global tick bounds and fee-tier spacing. */
|
|
1491
3000
|
export declare function assertTickRange(lower: number, upper: number, fee: FEE_TIER): void;
|
|
3001
|
+
/** A pool's current price in the frame of the request that asked for it. */
|
|
3002
|
+
export interface FramedSlot0 {
|
|
3003
|
+
/** The square-root price, token1 per token0 in the REQUESTED order. */
|
|
3004
|
+
sqrtPrice: string;
|
|
3005
|
+
/** The greatest tick whose square-root price is no greater than `sqrtPrice`. */
|
|
3006
|
+
tick: number;
|
|
3007
|
+
}
|
|
3008
|
+
/**
|
|
3009
|
+
* Puts a `slot0` answer into the frame of the request. The backend always answers in the pool's
|
|
3010
|
+
* canonical order and says so with `flippedFromRequest`; when the caller asked for the reverse
|
|
3011
|
+
* order the price is inverted here (at 60 significant digits, so a very large or very small
|
|
3012
|
+
* reciprocal keeps its precision) and the tick is re-derived from the inverted price with the
|
|
3013
|
+
* contract's greatest-tick rule. Negating the tick instead is wrong for a price between ticks
|
|
3014
|
+
* (and `-t - 1` is wrong for a price exactly on a tick: sqrtPrice 1 / tick 0 stays 1 / 0).
|
|
3015
|
+
*
|
|
3016
|
+
* @example
|
|
3017
|
+
* ```ts
|
|
3018
|
+
* const slot0 = await gSwap.pools.getSlot0('A', 'B', 500);
|
|
3019
|
+
* const { sqrtPrice, tick } = frameSlot0(slot0);
|
|
3020
|
+
* ```
|
|
3021
|
+
*/
|
|
3022
|
+
export declare function frameSlot0(slot0: {
|
|
3023
|
+
sqrtPrice: string;
|
|
3024
|
+
tick: number;
|
|
3025
|
+
flippedFromRequest?: boolean | undefined;
|
|
3026
|
+
}): FramedSlot0;
|
|
1492
3027
|
//#endregion
|
|
1493
3028
|
//#region src/utils/validation.d.ts
|
|
1494
3029
|
export declare function validateNumericAmount(amount: NumericAmount, parameterName: string, allowZero?: boolean): void;
|
|
@@ -1498,5 +3033,20 @@ export declare function validateTickRange(tickLower: number, tickUpper: number):
|
|
|
1498
3033
|
export declare function validateFee(fee: number): asserts fee is FEE_TIER;
|
|
1499
3034
|
export declare function validateTickSpacing(tickSpacing: number): void;
|
|
1500
3035
|
export declare function validateWalletAddress(address?: string): asserts address is string;
|
|
3036
|
+
/**
|
|
3037
|
+
* True when `symbol` is acceptable to propose into the trading-symbol registry: ASCII letters and
|
|
3038
|
+
* digits only, 1 to 32 characters, and not a reserved word (`Token`, `Unit`, `none`) — the rules
|
|
3039
|
+
* the chain gateway enforces on a CreatePool symbol.
|
|
3040
|
+
*/
|
|
3041
|
+
export declare function isProposableTradingSymbol(symbol: string): boolean;
|
|
3042
|
+
/**
|
|
3043
|
+
* Asserts that a pair is in the contract's canonical order (`token0 < token1` by plain string
|
|
3044
|
+
* comparison), which every write DTO requires. A pair a caller took from a stale quote or
|
|
3045
|
+
* position can be reversed; signing it would sign something other than what was priced.
|
|
3046
|
+
*
|
|
3047
|
+
* @throws GSwapSDKError VALIDATION_ERROR (`details.type` = `NON_CANONICAL_PAIR`) otherwise.
|
|
3048
|
+
*/
|
|
3049
|
+
export declare function assertCanonicalPair(token0: string, token1: string): void;
|
|
1501
3050
|
//#endregion
|
|
3051
|
+
export type { AddLiquidityInput, CreatePoolInput, EIP712DomainValue, EIP712Types, EntryParse, InvalidEntry, InvalidEntryHandler, PersonalSignChainDtoPayload, PoolPositionInput, PrivateKeyInput, RemoveLiquidityInput, RequestTradeInput, TypedDataPayload, V2WriteMethod };
|
|
1502
3052
|
//# sourceMappingURL=index.d.cts.map
|