@ravnexchange/sdk 0.1.14 → 0.1.15
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/execute-and-track.d.ts +72 -9
- package/dist/execute-and-track.js +98 -13
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/types.d.ts +46 -18
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RavnClient } from "./client";
|
|
2
|
-
import type { ApprovalDTO, ExecuteParams, ExecutionDTO, StatusDTO } from "./types";
|
|
2
|
+
import type { ApprovalDTO, DepositFeeDTO, ExecuteParams, ExecutionDTO, StatusDTO } from "./types";
|
|
3
3
|
type TxLike = {
|
|
4
4
|
to?: string;
|
|
5
5
|
data?: string;
|
|
@@ -8,14 +8,28 @@ type TxLike = {
|
|
|
8
8
|
serialized?: string;
|
|
9
9
|
};
|
|
10
10
|
export interface ExecuteAndTrackHandlers {
|
|
11
|
-
/** Broadcast a transaction (an approval,
|
|
11
|
+
/** Broadcast a transaction (an approval, the main swap tx, or RAVN's fee) and return its hash. */
|
|
12
12
|
sendTransaction(tx: TxLike): Promise<string>;
|
|
13
13
|
/**
|
|
14
14
|
* Wait for a transaction hash to confirm. Called on the approval before the main tx is ever
|
|
15
15
|
* sent: sending both back-to-back races the allowance and is the most common integration bug
|
|
16
|
-
* this helper exists to prevent.
|
|
16
|
+
* this helper exists to prevent. Also called on the swap before RAVN's fee is sent on its own
|
|
17
|
+
* (`fee.transaction`): resolve to the receipt itself (viem's `waitForTransactionReceipt`,
|
|
18
|
+
* ethers' `wait()`), as the fee is only sent when it says success AND is this hash's own (a
|
|
19
|
+
* cancelled or replaced swap resolves with another transaction's). Resolving to nothing, or
|
|
20
|
+
* anything else, sends no fee: a fee on a swap that didn't run is the user's money lost.
|
|
17
21
|
*/
|
|
18
|
-
waitForReceipt(hash: string, chainId?: number): Promise<
|
|
22
|
+
waitForReceipt(hash: string, chainId?: number): Promise<unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional: send several calls in ONE wallet confirmation that succeeds or fails as a whole
|
|
25
|
+
* (EIP-5792 `wallet_sendCalls` with `atomicRequired: true`, a smart account) and resolve, once
|
|
26
|
+
* they have landed, to the on-chain hash of the transaction that carried each call, in order
|
|
27
|
+
* (the same hash repeated for one transaction). Not a batch id or a 4337 userOpHash: RAVN
|
|
28
|
+
* proves its fee from that transaction. When given, a token-paid RAVN fee rides in the swap's
|
|
29
|
+
* own confirmation; a native-coin fee is always a plain transaction of its own. Reject only when
|
|
30
|
+
* nothing was sent: a rejection loses the swap's hash.
|
|
31
|
+
*/
|
|
32
|
+
sendCalls?(txs: TxLike[]): Promise<string[]>;
|
|
19
33
|
/** Sign an EIP-712 typed-data payload. Only called for SIGNATURE executions. */
|
|
20
34
|
signTypedData?(typedData: Record<string, unknown>): Promise<`0x${string}`>;
|
|
21
35
|
/**
|
|
@@ -34,7 +48,8 @@ export interface ExecuteAndTrackHandlers {
|
|
|
34
48
|
hasAllowance?(approval: ApprovalDTO): Promise<boolean>;
|
|
35
49
|
}
|
|
36
50
|
export interface ExecuteAndTrackOptions {
|
|
37
|
-
/** Default true. Set false to get a ref back
|
|
51
|
+
/** Default true. Set false to get a ref back once the swap (and RAVN's fee, when one is sent) is
|
|
52
|
+
* out, and poll getStatus yourself with `statusTxHash`. */
|
|
38
53
|
pollUntilTerminal?: boolean;
|
|
39
54
|
pollIntervalMs?: number;
|
|
40
55
|
}
|
|
@@ -48,14 +63,62 @@ export interface ExecuteAndTrackResult {
|
|
|
48
63
|
/** Pass to client.getStatus(quoteToken, statusRef). For TRANSACTION, the execution's own
|
|
49
64
|
* statusRef when it has one (compose, Garden, Relay), else txHash: not always a tx hash. */
|
|
50
65
|
statusRef?: string;
|
|
66
|
+
/** Pass as getStatus's third argument (`txHash`) on every poll you make yourself, from the first
|
|
67
|
+
* one until a terminal status and once more after a success (RAVN's node may be a block behind
|
|
68
|
+
* yours): the fee payment's transaction when one was sent (already confirmed by the time this
|
|
69
|
+
* returns), else, with a statusRef, the swap's own tx (a two-hop route's hop 1 proves its fee;
|
|
70
|
+
* ignored elsewhere). It's how RAVN proves the fee your share is paid from: the venue's own
|
|
71
|
+
* tracker saying "delivered" doesn't book it. */
|
|
72
|
+
statusTxHash?: string;
|
|
73
|
+
/** The transaction that carried RAVN's fee (`execution.fee.transaction`), once sent. Sent isn't
|
|
74
|
+
* paid (a batch can revert): RAVN's status polls are what prove it. */
|
|
75
|
+
feeTxHash?: string;
|
|
76
|
+
/** Why RAVN's fee wasn't sent (or its receipt not seen): the swap still runs and is tracked, but
|
|
77
|
+
* no fee is owed to you on it unless `feeTxHash` is set and it landed. */
|
|
78
|
+
feeError?: unknown;
|
|
79
|
+
/** DEPOSIT only: the fee payment to make beside the deposit (see depositFeePayment). */
|
|
80
|
+
feePayment?: DepositFeePayment;
|
|
51
81
|
/** Set once pollUntilTerminal reaches a terminal status. Absent for DEPOSIT (see below) or when polling is turned off. */
|
|
52
82
|
finalStatus?: StatusDTO;
|
|
53
83
|
}
|
|
84
|
+
/** How to pay a DEPOSIT's `fee`, so it's proven against this swap. See DepositFeeDTO. Either way,
|
|
85
|
+
* poll RAVN's getStatus until a terminal status even when the venue's own tracker (e.g. Rift's API)
|
|
86
|
+
* already says delivered: RAVN books the fee on its own status polls. */
|
|
87
|
+
export type DepositFeePayment =
|
|
88
|
+
/** EVM: send `transaction` exactly as given once the deposit has confirmed, then pass its
|
|
89
|
+
* on-chain hash as `txHash` on every getStatus poll; at least one must come after it confirmed,
|
|
90
|
+
* or nothing is owed. A token fee (`value` "0") may instead ride in the deposit's own atomic
|
|
91
|
+
* wallet batch: pass the hash of the transaction that carried it (not a batch id or userOpHash).
|
|
92
|
+
* A native-coin fee: a plain transaction of its own. */
|
|
93
|
+
{
|
|
94
|
+
kind: "transaction";
|
|
95
|
+
transaction: NonNullable<DepositFeeDTO["transaction"]>;
|
|
96
|
+
}
|
|
97
|
+
/** Bitcoin: an extra output paying `amount` sats to `address` in the SAME transaction that pays
|
|
98
|
+
* the deposit. One deposit per transaction: a fee output proves one swap. */
|
|
99
|
+
| {
|
|
100
|
+
kind: "bitcoin_output";
|
|
101
|
+
address: string;
|
|
102
|
+
amount: string;
|
|
103
|
+
}
|
|
104
|
+
/** Solana: a transfer of `amount` to `address` in the SAME transaction that pays the deposit
|
|
105
|
+
* exactly `deposit.amount` (SOL as lamports, not wrapped). SOL: a System transfer of `amount`
|
|
106
|
+
* lamports to `address`. A token: `createAssociatedTokenAccountIdempotent` for `address`'s
|
|
107
|
+
* associated token account for the input mint (under the mint's token program), then
|
|
108
|
+
* `transferChecked` of `amount` to it. Sent in a transaction of its own, it isn't found. */
|
|
109
|
+
| {
|
|
110
|
+
kind: "solana_transfer";
|
|
111
|
+
address: string;
|
|
112
|
+
amount: string;
|
|
113
|
+
};
|
|
114
|
+
/** The fee payment a DEPOSIT execution asks for beside its deposit; undefined when it has none. */
|
|
115
|
+
export declare function depositFeePayment(execution: ExecutionDTO): DepositFeePayment | undefined;
|
|
54
116
|
/**
|
|
55
|
-
* Sequences execute() → approval (if any) → wait for its receipt → main tx/signature →
|
|
56
|
-
* polling, using caller-supplied signing/sending functions. The SDK
|
|
57
|
-
* RPC dependency); this just gets the ORDER right, which quickstart's
|
|
58
|
-
* most common integration failure: sending the main tx before the approval
|
|
117
|
+
* Sequences execute() → approval (if any) → wait for its receipt → main tx/signature → RAVN's fee
|
|
118
|
+
* payment (if any) → status polling, using caller-supplied signing/sending functions. The SDK
|
|
119
|
+
* stays wallet-agnostic (no RPC dependency); this just gets the ORDER right, which quickstart's
|
|
120
|
+
* own docs flag as the most common integration failure: sending the main tx before the approval
|
|
121
|
+
* has confirmed.
|
|
59
122
|
*/
|
|
60
123
|
export declare function executeAndTrack(client: RavnClient, params: ExecuteParams, handlers: ExecuteAndTrackHandlers, options?: ExecuteAndTrackOptions): Promise<ExecuteAndTrackResult>;
|
|
61
124
|
export {};
|
|
@@ -1,24 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.depositFeePayment = depositFeePayment;
|
|
3
4
|
exports.executeAndTrack = executeAndTrack;
|
|
4
5
|
const polling_1 = require("./polling");
|
|
6
|
+
const BITCOIN_CHAIN_ID = -1;
|
|
7
|
+
const SOLANA_CHAIN_ID = -2;
|
|
8
|
+
const EVM_TX_HASH = /^0x[0-9a-fA-F]{64}$/;
|
|
9
|
+
/** The fee payment a DEPOSIT execution asks for beside its deposit; undefined when it has none. */
|
|
10
|
+
function depositFeePayment(execution) {
|
|
11
|
+
if (execution.executionType !== "DEPOSIT" || !execution.fee)
|
|
12
|
+
return undefined;
|
|
13
|
+
const { transaction, address, amount, chainId } = execution.fee;
|
|
14
|
+
if (transaction)
|
|
15
|
+
return { kind: "transaction", transaction };
|
|
16
|
+
if (chainId === BITCOIN_CHAIN_ID)
|
|
17
|
+
return { kind: "bitcoin_output", address, amount };
|
|
18
|
+
if (chainId === SOLANA_CHAIN_ID)
|
|
19
|
+
return { kind: "solana_transfer", address, amount };
|
|
20
|
+
throw new Error(`depositFeePayment: no known way to pay a fee on chain ${chainId}`);
|
|
21
|
+
}
|
|
22
|
+
// Only a receipt that says success (viem "success", ethers 1; web3.js 1n/true, so == on purpose) and
|
|
23
|
+
// is `hash`'s own (viem/ethers v5 transactionHash, ethers v6 hash): viem resolves a cancelled swap
|
|
24
|
+
// with the replacement's successful receipt.
|
|
25
|
+
const receiptSucceeded = (receipt, hash) => {
|
|
26
|
+
const r = receipt;
|
|
27
|
+
const own = r?.transactionHash ?? r?.hash;
|
|
28
|
+
return (r?.status === "success" || r?.status == 1) && (typeof own !== "string" || own.toLowerCase() === hash.toLowerCase());
|
|
29
|
+
};
|
|
5
30
|
/**
|
|
6
|
-
* Sequences execute() → approval (if any) → wait for its receipt → main tx/signature →
|
|
7
|
-
* polling, using caller-supplied signing/sending functions. The SDK
|
|
8
|
-
* RPC dependency); this just gets the ORDER right, which quickstart's
|
|
9
|
-
* most common integration failure: sending the main tx before the approval
|
|
31
|
+
* Sequences execute() → approval (if any) → wait for its receipt → main tx/signature → RAVN's fee
|
|
32
|
+
* payment (if any) → status polling, using caller-supplied signing/sending functions. The SDK
|
|
33
|
+
* stays wallet-agnostic (no RPC dependency); this just gets the ORDER right, which quickstart's
|
|
34
|
+
* own docs flag as the most common integration failure: sending the main tx before the approval
|
|
35
|
+
* has confirmed.
|
|
10
36
|
*/
|
|
11
37
|
async function executeAndTrack(client, params, handlers, options = {}) {
|
|
12
38
|
const { pollUntilTerminal = true, pollIntervalMs = 4000 } = options;
|
|
13
39
|
const execution = await client.execute(params);
|
|
14
40
|
const { quoteToken } = execution;
|
|
15
|
-
const pollStatus = async (ref) => {
|
|
41
|
+
const pollStatus = async (ref, txHash, feeSent = false) => {
|
|
16
42
|
if (!pollUntilTerminal)
|
|
17
43
|
return undefined;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
44
|
+
// A success answered before RAVN's node sees the fee tx proves nothing, and the row is then
|
|
45
|
+
// left to a cron that books no fee: one more poll after it.
|
|
46
|
+
// ponytail: one re-poll covers a block of lag; the real fix is /v1/status staying non-terminal
|
|
47
|
+
// while a given fee tx is unproven.
|
|
48
|
+
for (let recheck = feeSent;;) {
|
|
49
|
+
const status = await client.getStatus(quoteToken, ref, txHash);
|
|
50
|
+
if ((0, polling_1.isPollingTerminal)(status.status)) {
|
|
51
|
+
if (!recheck || status.status !== "success")
|
|
52
|
+
return status;
|
|
53
|
+
recheck = false;
|
|
54
|
+
}
|
|
22
55
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
23
56
|
}
|
|
24
57
|
};
|
|
@@ -49,9 +82,53 @@ async function executeAndTrack(client, params, handlers, options = {}) {
|
|
|
49
82
|
}
|
|
50
83
|
if (execution.executionType === "TRANSACTION") {
|
|
51
84
|
const approvalTxHash = await maybeSendApproval(execution.approval);
|
|
52
|
-
|
|
85
|
+
// RAVN's fee, when the route has none of its own (Eco, Layerswap, Mayan plain MCTP). From
|
|
86
|
+
// Solana there's nothing to send: it's a transfer inside transaction.serialized.
|
|
87
|
+
const feeTx = execution.fee?.transaction;
|
|
88
|
+
let txHash;
|
|
89
|
+
let feeTxHash;
|
|
90
|
+
let feeError;
|
|
91
|
+
if (feeTx && BigInt(feeTx.value) === 0n && handlers.sendCalls) {
|
|
92
|
+
// A token fee may ride in the swap's own confirmation: atomic, so it never outlives a swap
|
|
93
|
+
// that reverted. One hash back means one transaction carried both.
|
|
94
|
+
const [swapHash, feeHash = swapHash] = await handlers.sendCalls([execution.transaction, feeTx]);
|
|
95
|
+
if (!swapHash)
|
|
96
|
+
throw new Error("executeAndTrack: sendCalls returned no transaction hash");
|
|
97
|
+
txHash = swapHash;
|
|
98
|
+
feeTxHash = feeHash;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
txHash = await handlers.sendTransaction(execution.transaction);
|
|
102
|
+
if (feeTx) {
|
|
103
|
+
// On its own, only once the swap has confirmed: a reverted, dropped or replaced one pays
|
|
104
|
+
// no fee. Declined or failed, the swap still runs and is tracked; no fee is owed on it.
|
|
105
|
+
try {
|
|
106
|
+
if (!receiptSucceeded(await handlers.waitForReceipt(txHash, execution.transaction.chainId), txHash)) {
|
|
107
|
+
throw new Error("executeAndTrack: no successful receipt for the swap transaction itself, so RAVN's fee was not sent");
|
|
108
|
+
}
|
|
109
|
+
feeTxHash = await handlers.sendTransaction(feeTx);
|
|
110
|
+
// Confirmed before polling starts: a swap that fills first would otherwise end the
|
|
111
|
+
// polling on the one poll that had to prove the fee.
|
|
112
|
+
await handlers.waitForReceipt(feeTxHash, feeTx.chainId);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
feeError = err;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
53
119
|
const statusRef = execution.statusRef ?? txHash;
|
|
54
|
-
|
|
120
|
+
// What proves the fee, from the first poll on: its own transaction, else (a statusRef: a
|
|
121
|
+
// two-hop route) hop 1's. Only an EVM tx hash: /v1/status refuses anything else (a Solana
|
|
122
|
+
// signature, a batch id) on every poll.
|
|
123
|
+
const proof = feeTxHash ?? (execution.statusRef ? txHash : undefined);
|
|
124
|
+
const statusTxHash = proof && EVM_TX_HASH.test(proof) ? proof : undefined;
|
|
125
|
+
if (feeTxHash && !statusTxHash) {
|
|
126
|
+
feeError ?? (feeError = new Error(`executeAndTrack: ${feeTxHash} is not an on-chain transaction hash, so RAVN can't prove the fee`));
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
execution, quoteToken, approvalTxHash, txHash, statusRef, statusTxHash, feeTxHash, feeError,
|
|
130
|
+
finalStatus: await pollStatus(statusRef, statusTxHash, !!feeTxHash && !!statusTxHash),
|
|
131
|
+
};
|
|
55
132
|
}
|
|
56
133
|
if (execution.executionType === "SIGNATURE") {
|
|
57
134
|
if (!handlers.signTypedData) {
|
|
@@ -75,6 +152,14 @@ async function executeAndTrack(client, params, handlers, options = {}) {
|
|
|
75
152
|
}
|
|
76
153
|
// DEPOSIT: nothing to sign or send from here; the user moves funds to execution.deposit.address
|
|
77
154
|
// out-of-band, and this helper has no way to know when that happens. Returned without polling;
|
|
78
|
-
// start polling yourself (getStatus / useRavnStatus) once the deposit is actually sent.
|
|
79
|
-
|
|
155
|
+
// start polling yourself (getStatus / useRavnStatus) once the deposit is actually sent. Pay
|
|
156
|
+
// `feePayment` as it says, pass an EVM fee transaction's hash as getStatus's `txHash`, and poll
|
|
157
|
+
// RAVN to a terminal status even if the venue's own tracker says delivered first.
|
|
158
|
+
// A fee it can't describe never stops the deposit, which fills without it.
|
|
159
|
+
try {
|
|
160
|
+
return { execution, quoteToken, statusRef: execution.statusRef, feePayment: depositFeePayment(execution) };
|
|
161
|
+
}
|
|
162
|
+
catch (feeError) {
|
|
163
|
+
return { execution, quoteToken, statusRef: execution.statusRef, feeError };
|
|
164
|
+
}
|
|
80
165
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export { RavnClient } from "./client";
|
|
|
2
2
|
export type { RavnClientConfig } from "./client";
|
|
3
3
|
export * from "./types";
|
|
4
4
|
export { isPollingTerminal } from "./polling";
|
|
5
|
-
export { executeAndTrack } from "./execute-and-track";
|
|
6
|
-
export type { ExecuteAndTrackHandlers, ExecuteAndTrackOptions, ExecuteAndTrackResult, } from "./execute-and-track";
|
|
5
|
+
export { depositFeePayment, executeAndTrack } from "./execute-and-track";
|
|
6
|
+
export type { ExecuteAndTrackHandlers, ExecuteAndTrackOptions, ExecuteAndTrackResult, DepositFeePayment, } from "./execute-and-track";
|
package/dist/index.js
CHANGED
|
@@ -14,11 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.executeAndTrack = exports.isPollingTerminal = exports.RavnClient = void 0;
|
|
17
|
+
exports.executeAndTrack = exports.depositFeePayment = exports.isPollingTerminal = exports.RavnClient = void 0;
|
|
18
18
|
var client_1 = require("./client");
|
|
19
19
|
Object.defineProperty(exports, "RavnClient", { enumerable: true, get: function () { return client_1.RavnClient; } });
|
|
20
20
|
__exportStar(require("./types"), exports);
|
|
21
21
|
var polling_1 = require("./polling");
|
|
22
22
|
Object.defineProperty(exports, "isPollingTerminal", { enumerable: true, get: function () { return polling_1.isPollingTerminal; } });
|
|
23
23
|
var execute_and_track_1 = require("./execute-and-track");
|
|
24
|
+
Object.defineProperty(exports, "depositFeePayment", { enumerable: true, get: function () { return execute_and_track_1.depositFeePayment; } });
|
|
24
25
|
Object.defineProperty(exports, "executeAndTrack", { enumerable: true, get: function () { return execute_and_track_1.executeAndTrack; } });
|
package/dist/types.d.ts
CHANGED
|
@@ -156,15 +156,18 @@ export type ExecutionDTO = {
|
|
|
156
156
|
};
|
|
157
157
|
/**
|
|
158
158
|
* Only when your key sets a fee and the route has no fee of its own (Eco, Layerswap, Mayan's
|
|
159
|
-
* routes paying no referrer): RAVN's fee, a transfer of the input token to
|
|
160
|
-
* `transaction` already leaves it out.
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
159
|
+
* routes paying no referrer) from an EVM chain: RAVN's fee, a transfer of the input token to
|
|
160
|
+
* RAVN; `transaction` already leaves it out. From Solana there is none to send: the fee is a
|
|
161
|
+
* transfer inside `transaction.serialized`. Skip it and the swap still fills; no fee is owed to
|
|
162
|
+
* you. A wallet that batches (EIP-5792 `wallet_sendCalls`) or relays (smart account, 7702,
|
|
163
|
+
* 4337) may send `fee.transaction` with `transaction` in one confirmation (one fee-bearing swap
|
|
164
|
+
* per transaction: a second fee in it isn't proven), for an ERC-20 sell
|
|
165
|
+
* (a native-coin fee must be a plain transaction of its own, so a contract wallet that can't
|
|
166
|
+
* send one — a Safe, a 4337 account — can't pay it). Pass the on-chain hash of the transaction
|
|
167
|
+
* that carried the fee (not an EIP-5792 batch id or a 4337 userOpHash) as `txHash` to getStatus
|
|
168
|
+
* — not needed with no `statusRef` here, when the fee rode in the swap's own transaction. Sent
|
|
169
|
+
* on its own, send it once the swap has confirmed. A fee paid on a swap the venue refunds
|
|
170
|
+
* stays with RAVN.
|
|
168
171
|
*/
|
|
169
172
|
fee?: DepositFeeDTO;
|
|
170
173
|
} | {
|
|
@@ -194,9 +197,9 @@ export type ExecutionDTO = {
|
|
|
194
197
|
/** Poll getStatus with this, not `deposit.address`. */
|
|
195
198
|
statusRef: string;
|
|
196
199
|
/** Only when your key sets a fee and the venue has no fee of its own (Rift; private swaps from
|
|
197
|
-
* an EVM chain or
|
|
198
|
-
* owed to you. A fee paid on a swap the venue then refunds stays with RAVN and nothing
|
|
199
|
-
* on it, so send an EVM fee payment once the deposit has confirmed. */
|
|
200
|
+
* an EVM chain, Bitcoin or Solana). Skip it and the swap still fills on `deposit.amount`; no
|
|
201
|
+
* fee is owed to you. A fee paid on a swap the venue then refunds stays with RAVN and nothing
|
|
202
|
+
* is owed on it, so send an EVM fee payment once the deposit has confirmed. */
|
|
200
203
|
fee?: DepositFeeDTO;
|
|
201
204
|
};
|
|
202
205
|
/** RAVN's integrator fee beside a deposit (or a transaction), in the input token, paid by your user
|
|
@@ -207,12 +210,28 @@ export interface DepositFeeDTO {
|
|
|
207
210
|
/** RAVN's fee address on the input chain. */
|
|
208
211
|
address: string;
|
|
209
212
|
chainId: number;
|
|
210
|
-
/** EVM: send this transaction too, exactly as given
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
213
|
+
/** EVM: send this transaction too, exactly as given (it carries a tag naming this swap): on its
|
|
214
|
+
* own, or in the same wallet batch or relay as the deposit or swap (EIP-5792, smart account, 7702,
|
|
215
|
+
* 4337) — an ERC-20 fee anywhere; a native-coin fee only beside a NEAR Intents deposit on
|
|
216
|
+
* Ethereum, Base or Polygon (proven from those chains' internal transfers). Any other native-coin
|
|
217
|
+
* fee must be a plain transaction of its own (a contract wallet that can't send one can't pay it).
|
|
218
|
+
* Then pass the on-chain hash of the transaction that carried it (not a batch id or a userOpHash)
|
|
219
|
+
* as `txHash` to getStatus once it has confirmed (simplest: on every poll). One fee-bearing swap
|
|
220
|
+
* per transaction: a batch carrying two fees, or a fee beside another fee-bearing swap, proves only
|
|
221
|
+
* one. Batch a token deposit, or a native-coin deposit to NEAR Intents (it credits coin a smart
|
|
222
|
+
* account moves); send any other native-coin deposit as a plain transfer, as an exchange may not
|
|
223
|
+
* credit coin a contract moved. Absent on Bitcoin:
|
|
224
|
+
* pay `amount` to `address` as an extra output of the SAME transaction that pays the deposit;
|
|
225
|
+
* RAVN finds it there once that transaction confirms. One deposit per Bitcoin transaction: a fee
|
|
226
|
+
* output proves one swap. Absent on Solana too: add the fee to the SAME transaction that pays the
|
|
227
|
+
* deposit exactly `deposit.amount` (SOL as lamports to the deposit wallet, not wrapped) — SOL: a
|
|
228
|
+
* System transfer of `amount` lamports to `address`; a token: `transferChecked` of `amount` to
|
|
229
|
+
* `address`'s associated token account for the input mint (under the mint's token program), after
|
|
230
|
+
* `createAssociatedTokenAccountIdempotent` in case RAVN has none for that token yet (its rent,
|
|
231
|
+
* ~0.0015 SOL once per token, is normally in the quote's network cost). RAVN finds it there once
|
|
232
|
+
* that transaction is finalized, among the deposit address's first and latest transactions; a fee
|
|
233
|
+
* sent in a transaction of its own isn't found. One deposit per Solana transaction: a fee proves
|
|
234
|
+
* one swap. It can't be sent after the deposit, so on a swap the venue refunds it stays with RAVN. */
|
|
216
235
|
transaction?: {
|
|
217
236
|
to: string;
|
|
218
237
|
data: string;
|
|
@@ -251,6 +270,15 @@ export interface GetQuoteParams {
|
|
|
251
270
|
rankingMode?: "best_output" | "fastest";
|
|
252
271
|
/** Drop specific venues from this race, e.g. a risk objection to one of them. */
|
|
253
272
|
excludeVenues?: string[];
|
|
273
|
+
/** Race only these venues, e.g. ["bebop"] for an RFQ-only race. Every other venue is left
|
|
274
|
+
* out, including ones RAVN adds later; excludeVenues still applies on top. Matches the quote's
|
|
275
|
+
* venue.id, the venue you deal with, not every venue funds pass through: RAVN's multi-step
|
|
276
|
+
* routes (compose, relay quotes with hops) and venues such as Rift, Across (swapping before or
|
|
277
|
+
* after bridging) and Mayan (a Solana order starting in another token swaps through Jupiter
|
|
278
|
+
* first) route through others. An empty list is
|
|
279
|
+
* rejected (INVALID_REQUEST); if none of them can quote, NO_LIQUIDITY lists every left-out
|
|
280
|
+
* venue in error.details.excludedVenues. */
|
|
281
|
+
onlyVenues?: string[];
|
|
254
282
|
/** Settle privately: the race narrows to NEAR Intents (Confidential Intents) and Houdini Swap,
|
|
255
283
|
* and NO_LIQUIDITY replaces a public fill if neither can quote. Houdini is sent the request's IP,
|
|
256
284
|
* user-agent and clientTimezone for compliance screening; its terms bar US persons and
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ravnexchange/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
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",
|