@ravnexchange/sdk 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -21,7 +21,9 @@ export declare class RavnClient {
21
21
  submitSignature(params: SubmitSignatureParams): Promise<{
22
22
  statusRef: string;
23
23
  }>;
24
- /** GET /v1/status: `ref` is the DEPOSIT address or the statusRef from submitSignature. */
24
+ /** POST /v1/status: pass the quoteToken execute() returned (not the quote's own), and as `ref`
25
+ * the execution's statusRef, submitSignature's statusRef, or the origin tx hash. POST, not GET:
26
+ * a 2-hop quoteToken in a query string can exceed header limits and fail with 431. */
25
27
  getStatus(quoteToken: string, ref: string): Promise<StatusDTO>;
26
28
  /** GET /v1/tokens: RAVN's listed token registry for one chain. Not a per-pair routability guarantee. */
27
29
  getTokens(chainId: number): Promise<TokenDTO[]>;
package/dist/client.js CHANGED
@@ -51,10 +51,14 @@ class RavnClient {
51
51
  body: JSON.stringify(params),
52
52
  });
53
53
  }
54
- /** GET /v1/status: `ref` is the DEPOSIT address or the statusRef from submitSignature. */
54
+ /** POST /v1/status: pass the quoteToken execute() returned (not the quote's own), and as `ref`
55
+ * the execution's statusRef, submitSignature's statusRef, or the origin tx hash. POST, not GET:
56
+ * a 2-hop quoteToken in a query string can exceed header limits and fail with 431. */
55
57
  getStatus(quoteToken, ref) {
56
- const qs = new URLSearchParams({ quoteToken, ref }).toString();
57
- return this.request(`/status?${qs}`, { method: "GET" });
58
+ return this.request("/status", {
59
+ method: "POST",
60
+ body: JSON.stringify({ quoteToken, ref }),
61
+ });
58
62
  }
59
63
  /** GET /v1/tokens: RAVN's listed token registry for one chain. Not a per-pair routability guarantee. */
60
64
  getTokens(chainId) {
@@ -37,7 +37,11 @@ export interface ExecuteAndTrackResult {
37
37
  execution: ExecutionDTO;
38
38
  approvalTxHash?: string;
39
39
  txHash?: string;
40
- /** Pass to client.getStatus(quoteToken, ref): same value as txHash for TRANSACTION. */
40
+ /** Pass to client.getStatus(quoteToken, statusRef). Same as `execution.quoteToken`, NOT the
41
+ * quote's own token: on compose (2-hop) quotes execute rebinds hop 1 onto hop 2's deposit. */
42
+ quoteToken: string;
43
+ /** Pass to client.getStatus(quoteToken, statusRef). For TRANSACTION, the execution's own
44
+ * statusRef when it has one (compose, Garden, Relay), else txHash: not always a tx hash. */
41
45
  statusRef?: string;
42
46
  /** Set once pollUntilTerminal reaches a terminal status. Absent for DEPOSIT (see below) or when polling is turned off. */
43
47
  finalStatus?: StatusDTO;
@@ -11,11 +11,12 @@ const polling_1 = require("./polling");
11
11
  async function executeAndTrack(client, params, handlers, options = {}) {
12
12
  const { pollUntilTerminal = true, pollIntervalMs = 4000 } = options;
13
13
  const execution = await client.execute(params);
14
+ const { quoteToken } = execution;
14
15
  const pollStatus = async (ref) => {
15
16
  if (!pollUntilTerminal)
16
17
  return undefined;
17
18
  for (;;) {
18
- const status = await client.getStatus(params.quoteToken, ref);
19
+ const status = await client.getStatus(quoteToken, ref);
19
20
  if ((0, polling_1.isPollingTerminal)(status.status))
20
21
  return status;
21
22
  await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
@@ -35,7 +36,8 @@ async function executeAndTrack(client, params, handlers, options = {}) {
35
36
  if (execution.executionType === "TRANSACTION") {
36
37
  const approvalTxHash = await maybeSendApproval(execution.approval);
37
38
  const txHash = await handlers.sendTransaction(execution.transaction);
38
- return { execution, approvalTxHash, txHash, statusRef: txHash, finalStatus: await pollStatus(txHash) };
39
+ const statusRef = execution.statusRef ?? txHash;
40
+ return { execution, quoteToken, approvalTxHash, txHash, statusRef, finalStatus: await pollStatus(statusRef) };
39
41
  }
40
42
  if (execution.executionType === "SIGNATURE") {
41
43
  if (!handlers.signTypedData) {
@@ -54,11 +56,11 @@ async function executeAndTrack(client, params, handlers, options = {}) {
54
56
  approvalSignature = await handlers.signTypedData(execution.approvalData);
55
57
  }
56
58
  const signature = await handlers.signTypedData(execution.typedData);
57
- const { statusRef } = await client.submitSignature({ quoteToken: params.quoteToken, signature, approvalSignature });
58
- return { execution, approvalTxHash, statusRef, finalStatus: await pollStatus(statusRef) };
59
+ const { statusRef } = await client.submitSignature({ quoteToken, signature, approvalSignature });
60
+ return { execution, quoteToken, approvalTxHash, statusRef, finalStatus: await pollStatus(statusRef) };
59
61
  }
60
62
  // DEPOSIT: nothing to sign or send from here; the user moves funds to execution.deposit.address
61
63
  // out-of-band, and this helper has no way to know when that happens. Returned without polling;
62
64
  // start polling yourself (getStatus / useRavnStatus) once the deposit is actually sent.
63
- return { execution, statusRef: execution.statusRef };
65
+ return { execution, quoteToken, statusRef: execution.statusRef };
64
66
  }
package/dist/types.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Wire types for RAVN's public /api/v1 surface. Deliberately a standalone mirror of
3
3
  * src/lib/api/v1/dto.ts's public DTOs, not an import from it: this package ships to npm on
4
- * its own and can't depend on the app's internal source tree. Keep these two in sync by hand
5
- * when the API's public contract changes; that file's own comment already promises the shape
6
- * is frozen for third parties, so drift should be rare.
4
+ * its own and can't depend on the app's internal source tree. The app type-checks this copy
5
+ * against its own DTOs (dto-sdk-parity.ts), so a change on either side that isn't mirrored here
6
+ * fails the app's build.
7
7
  */
8
8
  export interface TokenDTO {
9
9
  symbol: string;
@@ -40,11 +40,7 @@ export interface QuoteDTO {
40
40
  };
41
41
  /** False means this is a preview-only price; see RavnClient.getQuote's destinationAddress note. */
42
42
  executable: boolean;
43
- slippage: {
44
- bps: number;
45
- isFirm: boolean;
46
- guaranteedMin: string | null;
47
- } | null;
43
+ slippage: SlippageDTO | null;
48
44
  gas: {
49
45
  native: string;
50
46
  nativeSymbol: string;
@@ -57,6 +53,12 @@ export interface QuoteDTO {
57
53
  estimatedTimeSeconds: number;
58
54
  estimatedTimeIsGuess: boolean;
59
55
  expiresAt: number;
56
+ /** Present on 2-hop (`venue.id === "compose"`) and Relay dest-call quotes. Sign hop 1; hop 2 is
57
+ * a unique deposit, not a second wallet tx. */
58
+ hops?: {
59
+ id: string;
60
+ name: string;
61
+ }[];
60
62
  /** Every other venue that raced and produced a usable quote, best output first. */
61
63
  alternatives: AlternativeQuoteDTO[];
62
64
  }
@@ -69,14 +71,37 @@ export interface AlternativeQuoteDTO {
69
71
  /** Pass to execute() to run THIS route instead of the primary quote. */
70
72
  quoteToken: string;
71
73
  outputAmount: string;
74
+ /** `amount` is in `token`'s base units: the output token everywhere except Fly Trade and
75
+ * Mayan, which deduct their fee from the input token. */
72
76
  fee: {
73
77
  bps: number;
74
78
  amount: string;
79
+ token: TokenDTO;
75
80
  supported: boolean;
76
81
  };
77
82
  executable: boolean;
78
83
  estimatedTimeSeconds: number;
79
84
  estimatedTimeIsGuess: boolean;
85
+ hops?: {
86
+ id: string;
87
+ name: string;
88
+ }[];
89
+ /** Same as QuoteDTO.slippage: an alternative can be executed, so it needs the same warning. */
90
+ slippage: SlippageDTO | null;
91
+ }
92
+ /**
93
+ * The slippage protection on a quote. `isFirm`: a firm RFQ price, no slippage possible.
94
+ * `guaranteedMin`: the minimum output in the output token's base units, when the venue exposes it.
95
+ *
96
+ * `noMinimum: true` means the venue enforces NO minimum output (Rift: it fills at its own best
97
+ * rate once the deposit lands), so `bps` is not a protection and the user can receive more or
98
+ * less than the quoted output. Show that to the user before they send funds.
99
+ */
100
+ export interface SlippageDTO {
101
+ bps: number;
102
+ isFirm: boolean;
103
+ guaranteedMin: string | null;
104
+ noMinimum: boolean;
80
105
  }
81
106
  export interface ChainDTO {
82
107
  chainId: number;
@@ -101,6 +126,11 @@ export interface ApprovalDTO {
101
126
  }
102
127
  export type ExecutionDTO = {
103
128
  executionType: "TRANSACTION";
129
+ /** Pass this, not the quote's own token, to getStatus. Compose: the post-bind token. */
130
+ quoteToken: string;
131
+ /** The venue's own tracking key (compose hop-2 handle, Garden order id, Relay request id).
132
+ * Poll getStatus with this when present; otherwise use the origin tx hash. */
133
+ statusRef?: string;
104
134
  approval?: ApprovalDTO;
105
135
  transaction: {
106
136
  to?: string;
@@ -111,6 +141,9 @@ export type ExecutionDTO = {
111
141
  };
112
142
  } | {
113
143
  executionType: "SIGNATURE";
144
+ /** Pass this, not the quote's own token, to submitSignature and getStatus. */
145
+ quoteToken: string;
146
+ statusRef?: string;
114
147
  approval?: ApprovalDTO;
115
148
  typedData?: Record<string, unknown>;
116
149
  approvalData?: Record<string, unknown>;
@@ -120,11 +153,17 @@ export type ExecutionDTO = {
120
153
  };
121
154
  } | {
122
155
  executionType: "DEPOSIT";
156
+ /** Pass this, not the quote's own token, to getStatus. */
157
+ quoteToken: string;
158
+ /** `expiresAt` (ISO 8601), when set, is when the deposit must have ARRIVED (confirmed on
159
+ * the origin chain) by. A later deposit lands at an expired order. */
123
160
  deposit: {
124
161
  address: string;
125
162
  amount: string;
126
163
  chainId?: number;
164
+ expiresAt?: string;
127
165
  };
166
+ /** Poll getStatus with this, not `deposit.address`. */
128
167
  statusRef: string;
129
168
  };
130
169
  export type SettlementStatus = "pending" | "processing" | "expired" | "success" | "refunded" | "failed" | "not_found" | "unknown";
@@ -153,14 +192,28 @@ export interface GetQuoteParams {
153
192
  rankingMode?: "best_output" | "fastest";
154
193
  /** Drop specific venues from this race, e.g. a risk objection to one of them. */
155
194
  excludeVenues?: string[];
195
+ /** Settle privately: the race narrows to NEAR Intents (Confidential Intents) and Houdini Swap,
196
+ * and NO_LIQUIDITY replaces a public fill if neither can quote. Houdini is sent the request's IP,
197
+ * user-agent and clientTimezone for compliance screening; its terms bar US persons and
198
+ * sanctioned jurisdictions, and you own your users' eligibility (excludeVenues: ["houdini"]). */
199
+ confidential?: boolean;
200
+ /** Your end user's IANA timezone (e.g. "Europe/Berlin"), forwarded only to Houdini. Default UTC. */
201
+ clientTimezone?: string;
202
+ /** Optional analytics handle: send the same value while re-pricing one swap so it counts as one
203
+ * intent. Never affects pricing, routing or fees. Max 64 chars. */
204
+ quoteSessionId?: string;
156
205
  /** Test quote -> execute -> status with no real funds and no live venue settlement. See
157
206
  * the API's own sandbox field description for per-venue/per-route exceptions. */
158
207
  sandbox?: boolean;
159
208
  }
160
209
  export interface ExecuteParams {
161
210
  quoteToken: string;
211
+ /** Only venues that bind the recipient at execute (Chainflip, Houdini Swap, Layerswap, Mayan,
212
+ * NEAR Intents, Rift) accept a new one; elsewhere a different address is INVALID_REQUEST. */
162
213
  destinationAddress?: string;
163
214
  refundAddress?: string;
215
+ /** Your end user's IANA timezone, forwarded only to Houdini. Default UTC. */
216
+ clientTimezone?: string;
164
217
  }
165
218
  export interface SubmitSignatureParams {
166
219
  quoteToken: string;
package/dist/types.js CHANGED
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * Wire types for RAVN's public /api/v1 surface. Deliberately a standalone mirror of
4
4
  * src/lib/api/v1/dto.ts's public DTOs, not an import from it: this package ships to npm on
5
- * its own and can't depend on the app's internal source tree. Keep these two in sync by hand
6
- * when the API's public contract changes; that file's own comment already promises the shape
7
- * is frozen for third parties, so drift should be rare.
5
+ * its own and can't depend on the app's internal source tree. The app type-checks this copy
6
+ * against its own DTOs (dto-sdk-parity.ts), so a change on either side that isn't mirrored here
7
+ * fails the app's build.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.RavnApiError = void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ravnexchange/sdk",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Typed client for the RAVN integrator API (/api/v1): quote, execute, submit-signature, status.",
5
5
  "keywords": ["ravn", "cross-chain", "swap", "swap-api", "dex-aggregator", "bitcoin", "native-btc", "solana", "evm", "crypto", "defi", "typescript", "sdk", "api-client"],
6
6
  "main": "./dist/index.js",