@pegaroute/sdk 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +199 -2
- package/dist/index-CeY_5Z4u.d.ts +1070 -0
- package/dist/index.d.ts +499 -0
- package/dist/index.js +901 -0
- package/dist/types-Cz8gDMIR.js +64 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +2 -0
- package/package.json +63 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { $ as KnownErrorCode, A as toExternalStatus, B as JsonSwapExecution, C as SwapInput, Ct as Token, D as InternalSwapStatus, E as SwapTimestamps, F as EvmSwapExecution, G as UtxoSwapExecution, H as OtherDepositSwapExecution, I as ExecutionFamily, J as GetQuoteParams, K as isExecutionFamily, L as ExecutionMode, M as CosmosMsgDepositSwapExecution, N as CosmosMsgExecuteSwapExecution, O as SwapStatus, P as EvmApproval, Q as ErrorCode, R as ExecutionOfFamily, S as SwapFailure, St as ProvidersResponse, T as SwapProviderInfo, U as SerializedSwapExecution, V as NamedDepositSwapExecution, W as SwapExecution, X as QuoteRoute, Y as QuoteResponse, Z as RouteWarning, _ as ProviderStatusInfo, _t as ProviderFeeStructure, a as WebhookEvent, at as QuoteFees, b as SwapEvent, bt as ProviderTakeStructure, c as ExpectedAffiliateEntry, ct as StreamingProgress, d as TransactionsResponse, dt as ChainsResponse, et as AffiliateFeeBreakdown, f as CreateSwapParams, ft as HealthResponse, g as InstaswapSwapLiteSnapshot, gt as ProviderAffiliateFeeStructure, h as InstaswapFeeLine, ht as PingResponse, i as TransactionWebhookEventType, it as Provider, j as CosmosBankSendSwapExecution, k as isTerminalStatus, l as ListTransactionsParams, lt as TokenAmount, m as GetSwapResponse, mt as ListProvidersParams, n as TransactionWebhookData, nt as OpenOceanRouteMeta, o as WebhookStreamingProgress, ot as RefundInfo, p as CreateSwapResponse, pt as KnownProviderType, q as isExecutionMode, r as TransactionWebhookEvent, rt as PrivateSwapMode, s as CursorPagination, st as RouteInfo, t as TestWebhookEvent, tt as KnownProvider, u as Transaction, ut as Chain, v as SubmitTxHashParams, vt as ProviderHealth, w as SwapOutput, wt as TokensResponse, x as SwapEventsResponse, xt as ProviderType, y as SubmitTxHashResponse, yt as ProviderInfo, z as ExecutionOfMode } from "./index-CeY_5Z4u.js";
|
|
2
|
+
//#region src/core/http.d.ts
|
|
3
|
+
/** Per-call options accepted by every SDK method. */
|
|
4
|
+
interface RequestOptions {
|
|
5
|
+
/** Cancels the request (and any pending retry). Cancellation is never retried. */
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
/** Overrides the client's `timeoutMs` for this call. */
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
}
|
|
10
|
+
/** Minimal `fetch` signature the SDK needs; any standard `fetch` satisfies it. */
|
|
11
|
+
type Fetch = (url: string, init: RequestInit) => Promise<Response>;
|
|
12
|
+
/** Resolved client settings the HTTP layer works with (defaults already applied). */
|
|
13
|
+
interface HttpClientConfig {
|
|
14
|
+
/** Integration API key, sent as the `X-API-Key` header. */
|
|
15
|
+
apiKey: string;
|
|
16
|
+
/** Base URL without a trailing slash. */
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
/** Default per-request timeout in milliseconds. */
|
|
19
|
+
timeoutMs: number;
|
|
20
|
+
/** How many times a GET may be retried after the first attempt. */
|
|
21
|
+
maxRetries: number;
|
|
22
|
+
/** The `fetch` implementation used to send requests. */
|
|
23
|
+
fetch: Fetch;
|
|
24
|
+
}
|
|
25
|
+
/** Query string values; `undefined` entries are left out of the URL. */
|
|
26
|
+
type QueryParams = Record<string, string | number | boolean | undefined>;
|
|
27
|
+
/** One API call, described independently of how it is sent. */
|
|
28
|
+
interface HttpRequest {
|
|
29
|
+
/** HTTP method. Only GETs are retried. */
|
|
30
|
+
method: "GET" | "POST";
|
|
31
|
+
/** Endpoint path starting with `/`, e.g. `/quote`. */
|
|
32
|
+
path: string;
|
|
33
|
+
/** Query string parameters; `undefined` values are left out. */
|
|
34
|
+
query?: QueryParams;
|
|
35
|
+
/** JSON body; serialised with `JSON.stringify`. */
|
|
36
|
+
body?: unknown;
|
|
37
|
+
/**
|
|
38
|
+
* Non-2xx statuses that still carry a normal response body, e.g. `/health` answers 503 when degraded.
|
|
39
|
+
* That body is returned (never retried) unless it isn't JSON or is an error envelope, which are handled as usual.
|
|
40
|
+
*/
|
|
41
|
+
successStatuses?: number[];
|
|
42
|
+
}
|
|
43
|
+
/** Sends requests to the Pegaroute API: auth, timeouts, retries and error mapping. */
|
|
44
|
+
declare class HttpClient {
|
|
45
|
+
#private;
|
|
46
|
+
constructor(config: HttpClientConfig);
|
|
47
|
+
/** Sends a request, retrying GETs on connection errors and on errors marked `retryable` (see `errorFromResponse`). */
|
|
48
|
+
request<T>(request: HttpRequest, options?: RequestOptions): Promise<T>;
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/resources/chains.d.ts
|
|
52
|
+
/** Chains Pegaroute supports. Available as `pr.chains`. */
|
|
53
|
+
declare class Chains {
|
|
54
|
+
#private;
|
|
55
|
+
constructor(http: HttpClient);
|
|
56
|
+
/**
|
|
57
|
+
* Lists every supported chain.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* const { chains } = await pr.chains.list();
|
|
61
|
+
*/
|
|
62
|
+
list(options?: RequestOptions): Promise<ChainsResponse>;
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/resources/providers.d.ts
|
|
66
|
+
/** Swap providers behind Pegaroute and their live status. Available as `pr.providers`. */
|
|
67
|
+
declare class Providers {
|
|
68
|
+
#private;
|
|
69
|
+
constructor(http: HttpClient);
|
|
70
|
+
/**
|
|
71
|
+
* Lists the providers that are switched on, or every provider with `includeDisabled: true`.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const { providers } = await pr.providers.list({ includeDisabled: true });
|
|
75
|
+
*/
|
|
76
|
+
list(params?: ListProvidersParams, options?: RequestOptions): Promise<ProvidersResponse>;
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/resources/quotes.d.ts
|
|
80
|
+
/** Swap quotes. Available as `pr.quotes`. */
|
|
81
|
+
declare class Quotes {
|
|
82
|
+
#private;
|
|
83
|
+
constructor(http: HttpClient);
|
|
84
|
+
/**
|
|
85
|
+
* Gets routes for a swap from every available provider.
|
|
86
|
+
*
|
|
87
|
+
* Throws `BadRequestError` for invalid input or an amount too low for every provider (`AMOUNT_TOO_LOW`),
|
|
88
|
+
* and `ServiceUnavailableError` when the chain is disabled (`CHAIN_DISABLED`).
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* const quote = await pr.quotes.get({ fromChain: "ETH", fromToken: "ETH", toChain: "BTC", toToken: "BTC", amount: "0.5" });
|
|
92
|
+
* const best = quote.routes[0];
|
|
93
|
+
*/
|
|
94
|
+
get(params: GetQuoteParams, options?: RequestOptions): Promise<QuoteResponse>;
|
|
95
|
+
}
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/resources/swaps.d.ts
|
|
98
|
+
/** Options for {@link Swaps.waitForCompletion}. */
|
|
99
|
+
interface WaitForCompletionOptions {
|
|
100
|
+
/** Wait between polls in milliseconds. Default 10 000; at least 1 000. */
|
|
101
|
+
intervalMs?: number;
|
|
102
|
+
/**
|
|
103
|
+
* Deadline for the whole wait in milliseconds, after which `WaitTimeoutError` is thrown. Default 3 600 000 (1 hour).
|
|
104
|
+
* Each poll still uses the client's own per-request `timeoutMs`.
|
|
105
|
+
*/
|
|
106
|
+
timeoutMs?: number;
|
|
107
|
+
/** Stops waiting (and cancels the poll in flight); the signal's reason is thrown. */
|
|
108
|
+
signal?: AbortSignal;
|
|
109
|
+
}
|
|
110
|
+
/** Swap creation and tracking. Available as `pr.swaps`. */
|
|
111
|
+
declare class Swaps {
|
|
112
|
+
#private;
|
|
113
|
+
constructor(http: HttpClient);
|
|
114
|
+
/**
|
|
115
|
+
* Creates a swap and returns what the user must sign.
|
|
116
|
+
*
|
|
117
|
+
* Never retried: the HTTP client only retries GET requests, so a timeout can't create a duplicate swap.
|
|
118
|
+
*
|
|
119
|
+
* Throws `ProviderChangedError` when the quoted route is gone: retry with its `newQuote`.
|
|
120
|
+
* Throws `QuoteExpiredError` when the quote expired, and `BadRequestError` for invalid input or
|
|
121
|
+
* parameters that don't match the quote (`QUOTE_MISMATCH`).
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const swap = await pr.swaps.create({
|
|
125
|
+
* fromChain: "ETH", fromToken: "ETH", toChain: "BTC", toToken: "BTC", amount: "0.5",
|
|
126
|
+
* senderAddress: "0xabc…", destinationAddress: "bc1q…",
|
|
127
|
+
* quoteId: quote.quoteId, routeProvider: quote.routes[0].provider,
|
|
128
|
+
* });
|
|
129
|
+
* // send swap.execution to the frontend for signing
|
|
130
|
+
*/
|
|
131
|
+
create(params: CreateSwapParams, options?: RequestOptions): Promise<CreateSwapResponse>;
|
|
132
|
+
/**
|
|
133
|
+
* Gets a swap's current state. Throws `NotFoundError` for an unknown ID.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* const swap = await pr.swaps.get(transactionId);
|
|
137
|
+
* if (swap.status === "fail") console.log(swap.error?.userMessage, swap.refund);
|
|
138
|
+
*/
|
|
139
|
+
get(transactionId: string, options?: RequestOptions): Promise<GetSwapResponse>;
|
|
140
|
+
/**
|
|
141
|
+
* Polls `swaps.get` until the swap reaches a terminal status (`success` or `fail`), then returns it.
|
|
142
|
+
* Webhooks are the better fit for production; use this as a fallback or in scripts.
|
|
143
|
+
*
|
|
144
|
+
* Throws `WaitTimeoutError` (with the last swap seen) if `timeoutMs` passes first. A failing poll is thrown
|
|
145
|
+
* unchanged, after `swaps.get`'s own retries.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* const final = await pr.swaps.waitForCompletion(swap.transactionId);
|
|
149
|
+
* if (final.status === "fail") console.log(final.error?.userMessage, final.refund);
|
|
150
|
+
*/
|
|
151
|
+
waitForCompletion(transactionId: string, options?: WaitForCompletionOptions): Promise<GetSwapResponse>;
|
|
152
|
+
/**
|
|
153
|
+
* Gets a swap's audit log: every internal status change, oldest first.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* const { events } = await pr.swaps.events(transactionId);
|
|
157
|
+
*/
|
|
158
|
+
events(transactionId: string, options?: RequestOptions): Promise<SwapEventsResponse>;
|
|
159
|
+
/**
|
|
160
|
+
* Reports the hash of the source transaction the user broadcast, so Pegaroute starts tracking it.
|
|
161
|
+
* Returns the internal status `"submitted"`.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* await pr.swaps.submitTxHash(swap.transactionId, { txHash });
|
|
165
|
+
*/
|
|
166
|
+
submitTxHash(transactionId: string, params: SubmitTxHashParams, options?: RequestOptions): Promise<SubmitTxHashResponse>;
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/resources/tokens.d.ts
|
|
170
|
+
/** Tokens Pegaroute recognises on each chain. Available as `pr.tokens`. */
|
|
171
|
+
declare class Tokens {
|
|
172
|
+
#private;
|
|
173
|
+
constructor(http: HttpClient);
|
|
174
|
+
/**
|
|
175
|
+
* Lists the tokens on one chain. Throws `BadRequestError` (`VALIDATION_ERROR`) for an unknown chain.
|
|
176
|
+
*
|
|
177
|
+
* @param chain A chain ID from `chains.list()`; case is ignored.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* const { tokens } = await pr.tokens.list("SOL");
|
|
181
|
+
*/
|
|
182
|
+
list(chain: string, options?: RequestOptions): Promise<TokensResponse>;
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/core/pagination.d.ts
|
|
186
|
+
/** How a {@link PagePromise} fetches pages and reads them. */
|
|
187
|
+
interface PagePromiseConfig<Page, Item> {
|
|
188
|
+
/** Fetches the page that starts after `cursor`; `undefined` for the first page. */
|
|
189
|
+
fetchPage: (cursor: string | undefined) => Promise<Page>;
|
|
190
|
+
/** Cursor to start from, when the caller passed one. */
|
|
191
|
+
firstCursor?: string | undefined;
|
|
192
|
+
/** The items on a page. */
|
|
193
|
+
items: (page: Page) => Item[];
|
|
194
|
+
/** The cursor of the next page, or `null` when this is the last page. */
|
|
195
|
+
nextCursor: (page: Page) => string | null;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The result of a cursor-paginated list: await it for one page, or iterate it for every item.
|
|
199
|
+
*
|
|
200
|
+
* Nothing is requested until it is awaited or iterated. Awaiting and then iterating the same
|
|
201
|
+
* `PagePromise` fetches the first page only once.
|
|
202
|
+
*
|
|
203
|
+
* `.catch()` and `.finally()` only cover the first page. When iterating, later pages are fetched inside
|
|
204
|
+
* the loop, so wrap the loop in `try`/`catch` to handle a failure on any page.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* // One page, as the API returns it
|
|
208
|
+
* const page = await pr.transactions.list({ count: 50 });
|
|
209
|
+
*
|
|
210
|
+
* // Every item, fetching the next page as needed
|
|
211
|
+
* try {
|
|
212
|
+
* for await (const tx of pr.transactions.list()) console.log(tx.id);
|
|
213
|
+
* } catch (e) {
|
|
214
|
+
* // any page failed
|
|
215
|
+
* }
|
|
216
|
+
*/
|
|
217
|
+
declare class PagePromise<Page, Item> implements Promise<Page>, AsyncIterable<Item> {
|
|
218
|
+
#private;
|
|
219
|
+
/** Shown by `Object.prototype.toString`, like `[object Promise]` for a real promise. */
|
|
220
|
+
readonly [Symbol.toStringTag]: string;
|
|
221
|
+
constructor(config: PagePromiseConfig<Page, Item>);
|
|
222
|
+
/** Resolves to the first page, so `await` works. */
|
|
223
|
+
then<TResult1 = Page, TResult2 = never>(onfulfilled?: ((page: Page) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
224
|
+
/** Handles a failure to fetch the first page, like `Promise.prototype.catch`. */
|
|
225
|
+
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<Page | TResult>;
|
|
226
|
+
/** Runs once the first page is fetched or has failed, like `Promise.prototype.finally`. */
|
|
227
|
+
finally(onfinally?: (() => void) | null): Promise<Page>;
|
|
228
|
+
/** Yields every item of every page, fetching each page when the previous one is used up. */
|
|
229
|
+
[Symbol.asyncIterator](): AsyncIterator<Item>;
|
|
230
|
+
}
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/resources/transactions.d.ts
|
|
233
|
+
/** Swap history for your integration. Available as `pr.transactions`. */
|
|
234
|
+
declare class Transactions {
|
|
235
|
+
#private;
|
|
236
|
+
constructor(http: HttpClient);
|
|
237
|
+
/**
|
|
238
|
+
* Lists your swaps, newest first. Await it for one page, or iterate it with `for await` to walk every page.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* // One page
|
|
242
|
+
* const { transactions, pagination } = await pr.transactions.list({ count: 50 });
|
|
243
|
+
*
|
|
244
|
+
* // Every failed swap, across pages
|
|
245
|
+
* for await (const tx of pr.transactions.list({ status: "failed" })) {
|
|
246
|
+
* console.log(tx.id, tx.error?.userMessage);
|
|
247
|
+
* }
|
|
248
|
+
*/
|
|
249
|
+
list(params?: ListTransactionsParams, options?: RequestOptions): PagePromise<TransactionsResponse, Transaction>;
|
|
250
|
+
}
|
|
251
|
+
//#endregion
|
|
252
|
+
//#region src/client.d.ts
|
|
253
|
+
/** Settings for a {@link Pegaroute} client. */
|
|
254
|
+
interface PegarouteOptions {
|
|
255
|
+
/** Integration API key. Keep it server-side. */
|
|
256
|
+
apiKey: string;
|
|
257
|
+
/** Pegaroute API base URL, e.g. `https://api.pegaroute.com`. */
|
|
258
|
+
baseUrl: string;
|
|
259
|
+
/** Per-request timeout. Default 30 000 ms. */
|
|
260
|
+
timeoutMs?: number;
|
|
261
|
+
/** Retries for GET requests on connection errors and on errors marked `retryable` (e.g. 429, 503). Default 2. */
|
|
262
|
+
maxRetries?: number;
|
|
263
|
+
/** Custom `fetch` implementation (tests, proxies). Default `globalThis.fetch`. */
|
|
264
|
+
fetch?: Fetch;
|
|
265
|
+
}
|
|
266
|
+
/** Pegaroute API client. Server-side only: it holds your API key. */
|
|
267
|
+
export declare class Pegaroute {
|
|
268
|
+
#private;
|
|
269
|
+
/** Supported chains. */
|
|
270
|
+
readonly chains: Chains;
|
|
271
|
+
/** Supported tokens per chain. */
|
|
272
|
+
readonly tokens: Tokens;
|
|
273
|
+
/** Swap providers and their status. */
|
|
274
|
+
readonly providers: Providers;
|
|
275
|
+
/** Swap quotes. */
|
|
276
|
+
readonly quotes: Quotes;
|
|
277
|
+
/** Swap creation and tracking. */
|
|
278
|
+
readonly swaps: Swaps;
|
|
279
|
+
/** Swap history for your integration. */
|
|
280
|
+
readonly transactions: Transactions;
|
|
281
|
+
constructor(options: PegarouteOptions);
|
|
282
|
+
/**
|
|
283
|
+
* Returns Pegaroute's health: database, write-ahead log and every provider.
|
|
284
|
+
*
|
|
285
|
+
* Unlike other methods, this does not throw when Pegaroute answers 503 because its database is down:
|
|
286
|
+
* it returns the body with `status: "degraded"` instead. Other failures (401, timeouts, …) still throw.
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* const health = await pr.health();
|
|
290
|
+
* if (health.status === "degraded") alert(health);
|
|
291
|
+
*/
|
|
292
|
+
health(options?: RequestOptions): Promise<HealthResponse>;
|
|
293
|
+
/**
|
|
294
|
+
* Checks that Pegaroute is reachable.
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* await pr.ping(); // { response: "pong", timestamp: "…", service: "pegaroute" }
|
|
298
|
+
*/
|
|
299
|
+
ping(options?: RequestOptions): Promise<PingResponse>;
|
|
300
|
+
}
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/core/errors.d.ts
|
|
303
|
+
/**
|
|
304
|
+
* The data needed to create a {@link PegarouteError} ("Init" = initialisation).
|
|
305
|
+
*
|
|
306
|
+
* Passed as one object with named fields instead of many positional arguments, so fields can't be
|
|
307
|
+
* mixed up. Only the SDK creates these errors; integrators just read the same fields on the error they catch.
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* new QuoteExpiredError({ code: "QUOTE_EXPIRED", status: 410, message: "…", userMessage: "…", retryable: false });
|
|
311
|
+
*/
|
|
312
|
+
interface PegarouteErrorInit {
|
|
313
|
+
/** Machine-readable error code, e.g. `QUOTE_EXPIRED`. */
|
|
314
|
+
code: ErrorCode;
|
|
315
|
+
/** HTTP status, or `null` when no response was received. */
|
|
316
|
+
status: number | null;
|
|
317
|
+
/** Technical message for developers and logs. */
|
|
318
|
+
message: string;
|
|
319
|
+
/** Message that is safe to show to end users. */
|
|
320
|
+
userMessage: string;
|
|
321
|
+
/** Whether the same request may succeed if tried again. */
|
|
322
|
+
retryable: boolean;
|
|
323
|
+
/** Seconds the server asked us to wait before retrying, if any. */
|
|
324
|
+
retryAfterSeconds?: number | null;
|
|
325
|
+
/** Provider that caused the error, when the failure is provider-specific. */
|
|
326
|
+
provider?: string;
|
|
327
|
+
/** Extra context from the server (or the SDK) about the failure. */
|
|
328
|
+
details?: Record<string, unknown>;
|
|
329
|
+
/** The underlying error, e.g. the network failure behind a `ConnectionError`. */
|
|
330
|
+
cause?: unknown;
|
|
331
|
+
}
|
|
332
|
+
/** Base class for every error the SDK throws after a request is made. */
|
|
333
|
+
export declare class PegarouteError extends Error {
|
|
334
|
+
/** Machine-readable error code, e.g. `QUOTE_EXPIRED`. */
|
|
335
|
+
readonly code: ErrorCode;
|
|
336
|
+
/** HTTP status, or `null` when no response was received. */
|
|
337
|
+
readonly status: number | null;
|
|
338
|
+
/** Safe to show to end users. */
|
|
339
|
+
readonly userMessage: string;
|
|
340
|
+
/**
|
|
341
|
+
* Whether the same request may succeed if tried again.
|
|
342
|
+
* The SDK retries such GETs itself, up to `maxRetries` times, unless the server asks to wait more than 60 seconds.
|
|
343
|
+
* POSTs are never retried, so retrying one is up to you.
|
|
344
|
+
*/
|
|
345
|
+
readonly retryable: boolean;
|
|
346
|
+
/** Seconds the server asked us to wait before retrying, or `null` when it didn't say. */
|
|
347
|
+
readonly retryAfterSeconds: number | null;
|
|
348
|
+
/** Provider that caused the error, when the failure is provider-specific. */
|
|
349
|
+
readonly provider?: string;
|
|
350
|
+
/** Extra context from the server (or the SDK) about the failure. */
|
|
351
|
+
readonly details?: Record<string, unknown>;
|
|
352
|
+
constructor(init: PegarouteErrorInit);
|
|
353
|
+
}
|
|
354
|
+
/** The request is invalid, e.g. a bad address, amount or unsupported pair (HTTP 400). */
|
|
355
|
+
export declare class BadRequestError extends PegarouteError {}
|
|
356
|
+
/** The API key is missing or invalid (HTTP 401). */
|
|
357
|
+
export declare class AuthenticationError extends PegarouteError {}
|
|
358
|
+
/** The API key isn't allowed to make this request (HTTP 403). */
|
|
359
|
+
export declare class PermissionDeniedError extends PegarouteError {}
|
|
360
|
+
/** The resource doesn't exist, e.g. an unknown swap ID (HTTP 404). */
|
|
361
|
+
export declare class NotFoundError extends PegarouteError {}
|
|
362
|
+
/** The request conflicts with the current state (HTTP 409). See {@link ProviderChangedError} for a changed provider. */
|
|
363
|
+
export declare class ConflictError extends PegarouteError {}
|
|
364
|
+
/** The data needed to create a {@link ProviderChangedError}: the base fields plus the refreshed quote. */
|
|
365
|
+
interface ProviderChangedErrorInit extends PegarouteErrorInit {
|
|
366
|
+
/** The refreshed quote to review and retry with. */
|
|
367
|
+
newQuote: QuoteResponse;
|
|
368
|
+
/** The provider that was quoted (or requested with `routeProvider`). */
|
|
369
|
+
originalProvider: string;
|
|
370
|
+
/** The best provider under the refreshed quote. */
|
|
371
|
+
newProvider: string;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* The quoted route is no longer available, so Pegaroute quoted again (HTTP 409, `PROVIDER_CHANGED`).
|
|
375
|
+
* The original `quoteId` is used up: show the user `newQuote` and call `swaps.create` again with its `quoteId`.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* catch (e) {
|
|
379
|
+
* if (e instanceof ProviderChangedError) retryWith(e.newQuote);
|
|
380
|
+
* }
|
|
381
|
+
*/
|
|
382
|
+
export declare class ProviderChangedError extends ConflictError {
|
|
383
|
+
/** The refreshed quote to review and retry with. */
|
|
384
|
+
readonly newQuote: QuoteResponse;
|
|
385
|
+
/** The provider that was quoted (or requested with `routeProvider`). */
|
|
386
|
+
readonly originalProvider: string;
|
|
387
|
+
/** The best provider under the refreshed quote. */
|
|
388
|
+
readonly newProvider: string;
|
|
389
|
+
constructor(init: ProviderChangedErrorInit);
|
|
390
|
+
}
|
|
391
|
+
/** The quote is no longer valid; request a new one. */
|
|
392
|
+
export declare class QuoteExpiredError extends PegarouteError {}
|
|
393
|
+
/** The request is well-formed but can't be carried out, e.g. the memo is too long (HTTP 422). */
|
|
394
|
+
export declare class UnprocessableEntityError extends PegarouteError {}
|
|
395
|
+
/** Too many requests (HTTP 429). `retryAfterSeconds` says how long to wait, when the server sends it. */
|
|
396
|
+
export declare class RateLimitError extends PegarouteError {}
|
|
397
|
+
/** A chain is halted or disabled, or a provider is down. */
|
|
398
|
+
export declare class ServiceUnavailableError extends PegarouteError {}
|
|
399
|
+
/** Pegaroute, a provider or a gateway in front of it failed (HTTP 500, 502, 504 or another 5xx except 503). */
|
|
400
|
+
export declare class InternalServerError extends PegarouteError {}
|
|
401
|
+
/**
|
|
402
|
+
* No complete response was received: the connection failed (DNS, TCP, TLS, …) or dropped mid-response.
|
|
403
|
+
* `status` is `null` unless the failure happened while reading the body.
|
|
404
|
+
*/
|
|
405
|
+
export declare class ConnectionError extends PegarouteError {}
|
|
406
|
+
/** The request did not complete within the configured timeout. */
|
|
407
|
+
export declare class TimeoutError extends ConnectionError {}
|
|
408
|
+
/** The data needed to create a {@link WaitTimeoutError}: the base fields plus the last swap seen. */
|
|
409
|
+
interface WaitTimeoutErrorInit extends PegarouteErrorInit {
|
|
410
|
+
/** The most recent successful poll, or `null` if the deadline passed before the first one returned. */
|
|
411
|
+
lastSwap: GetSwapResponse | null;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* `swaps.waitForCompletion` reached its `timeoutMs` before the swap reached a terminal status (code `WAIT_TIMEOUT`).
|
|
415
|
+
*
|
|
416
|
+
* The swap itself didn't fail: it may still finish, so check it again later (or wait for its webhook).
|
|
417
|
+
* Not a `TimeoutError`, which means a single HTTP request timed out.
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* catch (e) {
|
|
421
|
+
* if (e instanceof WaitTimeoutError) console.log("still", e.lastSwap?.status);
|
|
422
|
+
* }
|
|
423
|
+
*/
|
|
424
|
+
export declare class WaitTimeoutError extends PegarouteError {
|
|
425
|
+
/** The most recent successful poll, or `null` if the deadline passed before the first one returned. */
|
|
426
|
+
readonly lastSwap: GetSwapResponse | null;
|
|
427
|
+
constructor(init: WaitTimeoutErrorInit);
|
|
428
|
+
}
|
|
429
|
+
//#endregion
|
|
430
|
+
//#region src/webhooks.d.ts
|
|
431
|
+
/** Why {@link verifyWebhook} rejected a delivery. */
|
|
432
|
+
type WebhookVerificationFailure = "missing_signature" | "invalid_signature" | "invalid_payload";
|
|
433
|
+
/**
|
|
434
|
+
* A webhook delivery failed verification: don't trust its body. Answer with a 4xx (e.g. 401).
|
|
435
|
+
*
|
|
436
|
+
* Not a `PegarouteError`: no API request was made, so its HTTP fields wouldn't mean anything.
|
|
437
|
+
*/
|
|
438
|
+
export declare class WebhookVerificationError extends Error {
|
|
439
|
+
/**
|
|
440
|
+
* What was wrong:
|
|
441
|
+
* - `missing_signature`: no `X-Pegasus-Signature` header.
|
|
442
|
+
* - `invalid_signature`: the signature doesn't match the body and secret (wrong secret, altered body, or the
|
|
443
|
+
* body was re-serialised instead of passed raw).
|
|
444
|
+
* - `invalid_payload`: the signature matched, but the body isn't a JSON object.
|
|
445
|
+
*/
|
|
446
|
+
readonly reason: WebhookVerificationFailure;
|
|
447
|
+
constructor(reason: WebhookVerificationFailure, message: string, options?: ErrorOptions);
|
|
448
|
+
}
|
|
449
|
+
/** What {@link verifyWebhook} needs from a delivery. */
|
|
450
|
+
interface VerifyWebhookParams {
|
|
451
|
+
/**
|
|
452
|
+
* The request body exactly as received: the signature covers these bytes, so parse it only afterwards.
|
|
453
|
+
* A Node `Buffer` is a `Uint8Array`, so it works as-is.
|
|
454
|
+
*/
|
|
455
|
+
rawBody: string | Uint8Array;
|
|
456
|
+
/**
|
|
457
|
+
* The `X-Pegasus-Signature` header. Typed loosely so header values pass straight through:
|
|
458
|
+
* `req.headers["x-pegasus-signature"]` (Node/Express) or `request.headers.get("x-pegasus-signature")` (fetch).
|
|
459
|
+
*/
|
|
460
|
+
signature: string | string[] | null | undefined;
|
|
461
|
+
/** Your integration's webhook secret: the full `whsec_…` value from the Pegaroute UI. */
|
|
462
|
+
secret: string;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Checks that a webhook came from Pegaroute and returns its typed event.
|
|
466
|
+
*
|
|
467
|
+
* The signature is an HMAC-SHA256 of the raw body, keyed with your webhook secret. Delivery is at-least-once, so
|
|
468
|
+
* the same event can arrive more than once: make handlers idempotent.
|
|
469
|
+
*
|
|
470
|
+
* The signature proves who sent the body, not when: it has no timestamp, and events carry no ID to deduplicate on,
|
|
471
|
+
* so anyone who obtains a delivery can send it again later and it still verifies. Treat an event as a hint and
|
|
472
|
+
* confirm with `swaps.get` before acting on funds.
|
|
473
|
+
*
|
|
474
|
+
* Throws `WebhookVerificationError` when the delivery can't be trusted, and `TypeError` for a coding mistake
|
|
475
|
+
* (`secret` missing, or `signature` neither a string nor an array).
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* app.post("/webhooks/pegaroute", express.raw({ type: "application/json" }), async (req, res) => {
|
|
479
|
+
* try {
|
|
480
|
+
* const event = await verifyWebhook({
|
|
481
|
+
* rawBody: req.body,
|
|
482
|
+
* signature: req.headers["x-pegasus-signature"],
|
|
483
|
+
* secret: process.env.PEGAROUTE_WEBHOOK_SECRET!,
|
|
484
|
+
* });
|
|
485
|
+
* if (event.event === "transaction.completed") {
|
|
486
|
+
* // The event may be a replay: confirm the current state before acting on funds.
|
|
487
|
+
* const swap = await pr.swaps.get(event.data.transactionId);
|
|
488
|
+
* if (swap.status === "success") await markPaid(swap.transactionId); // idempotent
|
|
489
|
+
* }
|
|
490
|
+
* res.sendStatus(200);
|
|
491
|
+
* } catch (e) {
|
|
492
|
+
* if (e instanceof WebhookVerificationError) return res.sendStatus(401);
|
|
493
|
+
* throw e;
|
|
494
|
+
* }
|
|
495
|
+
* });
|
|
496
|
+
*/
|
|
497
|
+
export declare function verifyWebhook(params: VerifyWebhookParams): Promise<WebhookEvent>;
|
|
498
|
+
//#endregion
|
|
499
|
+
export { type AffiliateFeeBreakdown, type Chain, type ChainsResponse, type CosmosBankSendSwapExecution, type CosmosMsgDepositSwapExecution, type CosmosMsgExecuteSwapExecution, type CreateSwapParams, type CreateSwapResponse, type CursorPagination, type ErrorCode, type EvmApproval, type EvmSwapExecution, type ExecutionFamily, type ExecutionMode, type ExecutionOfFamily, type ExecutionOfMode, type ExpectedAffiliateEntry, type Fetch, type GetQuoteParams, type GetSwapResponse, type HealthResponse, type InstaswapFeeLine, type InstaswapSwapLiteSnapshot, type InternalSwapStatus, type JsonSwapExecution, type KnownErrorCode, type KnownProvider, type KnownProviderType, type ListProvidersParams, type ListTransactionsParams, type NamedDepositSwapExecution, type OpenOceanRouteMeta, type OtherDepositSwapExecution, type PagePromise, type PegarouteOptions, type PingResponse, type PrivateSwapMode, type Provider, type ProviderAffiliateFeeStructure, type ProviderFeeStructure, type ProviderHealth, type ProviderInfo, type ProviderStatusInfo, type ProviderTakeStructure, type ProviderType, type ProvidersResponse, type QuoteFees, type QuoteResponse, type QuoteRoute, type RefundInfo, type RequestOptions, type RouteInfo, type RouteWarning, type SerializedSwapExecution, type StreamingProgress, type SubmitTxHashParams, type SubmitTxHashResponse, type SwapEvent, type SwapEventsResponse, type SwapExecution, type SwapFailure, type SwapInput, type SwapOutput, type SwapProviderInfo, type SwapStatus, type SwapTimestamps, type TestWebhookEvent, type Token, type TokenAmount, type TokensResponse, type Transaction, type TransactionWebhookData, type TransactionWebhookEvent, type TransactionWebhookEventType, type TransactionsResponse, type UtxoSwapExecution, type VerifyWebhookParams, type WaitForCompletionOptions, type WebhookEvent, type WebhookStreamingProgress, type WebhookVerificationFailure, isExecutionFamily, isExecutionMode, isTerminalStatus, toExternalStatus };
|