@piprail/sdk 2.16.2 → 3.0.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/CHANGELOG.md +343 -0
- package/README.md +1 -0
- package/dist/{algorand-25FMBCT3.js → algorand-HL57PQHE.js} +157 -2
- package/dist/{algorand-Q3TUQLPK.cjs → algorand-W776EEM2.cjs} +205 -50
- package/dist/{aptos-VBJONBFY.cjs → aptos-5QBXJ6NV.cjs} +255 -39
- package/dist/{aptos-SBV6SGDP.js → aptos-H5VLH2QL.js} +217 -1
- package/dist/{chunk-QONQSZHJ.cjs → chunk-6XTNI2OQ.cjs} +44 -44
- package/dist/{chunk-OXEFPLZA.cjs → chunk-6ZRAIQXF.cjs} +4 -4
- package/dist/chunk-GVCGUSTE.js +30 -0
- package/dist/{chunk-V2IJ5HUW.cjs → chunk-MZAJQYM3.cjs} +1 -0
- package/dist/chunk-MZXVXC3C.cjs +30 -0
- package/dist/{chunk-2CX7XRZK.js → chunk-TZDVZCTC.js} +1 -0
- package/dist/{chunk-C52H5TYB.js → chunk-YXBQKBDH.js} +2 -2
- package/dist/index.cjs +2929 -1444
- package/dist/index.d.cts +625 -13
- package/dist/index.d.ts +625 -13
- package/dist/index.js +2506 -1021
- package/dist/{near-OLKCMTBI.js → near-5X2CQGML.js} +197 -1
- package/dist/{near-5LTTDU6G.cjs → near-XSQXEIHT.cjs} +242 -46
- package/dist/{solana-AI2G7V33.cjs → solana-EBV6PUCU.cjs} +211 -52
- package/dist/{solana-HTKDRTD3.js → solana-O6Q6QILH.js} +167 -8
- package/dist/{stellar-E2KWEV2E.cjs → stellar-5C7FQLPS.cjs} +191 -29
- package/dist/{stellar-EUFZLX6J.js → stellar-YF5LOJEM.js} +163 -1
- package/dist/{sui-KCIITCYH.js → sui-JFQSDNSZ.js} +165 -3
- package/dist/{sui-Q3NJOJZS.cjs → sui-WIZEAO7E.cjs} +185 -23
- package/dist/{ton-J7TQWRN4.cjs → ton-AGTKLQA5.cjs} +264 -22
- package/dist/{ton-WH2JVQOO.js → ton-OZKFNRLT.js} +244 -2
- package/dist/{tron-FXBXDNEY.js → tron-HG3IOOCG.js} +283 -1
- package/dist/{tron-HIPMOX7S.cjs → tron-S4WX7OHY.cjs} +323 -41
- package/dist/{xrpl-RUOB37QH.js → xrpl-GOVHMYYK.js} +222 -5
- package/dist/{xrpl-SVVS445B.cjs → xrpl-YS3IXPLV.cjs} +273 -56
- package/package.json +12 -2
- package/dist/{chunk-QU25LSVS.js → chunk-5GRBEMCA.js} +44 -44
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
|
+
var _chunkMZXVXC3Ccjs = require('./chunk-MZXVXC3C.cjs');
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
|
|
@@ -8,7 +9,11 @@
|
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
var _chunk6XTNI2OQcjs = require('./chunk-6XTNI2OQ.cjs');
|
|
12
17
|
|
|
13
18
|
// src/drivers/solana/index.ts
|
|
14
19
|
var _web3js = require('@solana/web3.js');
|
|
@@ -102,6 +107,148 @@ async function paySolana(params) {
|
|
|
102
107
|
return signature;
|
|
103
108
|
}
|
|
104
109
|
|
|
110
|
+
// src/drivers/solana/swap.ts
|
|
111
|
+
|
|
112
|
+
var JUPITER_API = "https://lite-api.jup.ag/swap/v1";
|
|
113
|
+
var WSOL_MINT = "So11111111111111111111111111111111111111112";
|
|
114
|
+
function sourceFor(platformFee) {
|
|
115
|
+
const charged = platformFee != null && !(typeof platformFee === "object" && Object.keys(platformFee).length === 0);
|
|
116
|
+
return {
|
|
117
|
+
kind: "provider",
|
|
118
|
+
name: "Jupiter",
|
|
119
|
+
note: "Third-party Solana DEX aggregator (lite-api.jup.ag), used keyless. It routes and builds the transaction; your own key signs it and Jupiter never holds your funds. " + (charged ? `\u26A0\uFE0F THIS QUOTE CARRIES A PLATFORM FEE: ${JSON.stringify(platformFee)}. PipRail did not set one.` : "This quote carries no platform fee, and PipRail adds none.")
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function mintFor(t) {
|
|
123
|
+
return t.asset === "native" ? WSOL_MINT : t.asset;
|
|
124
|
+
}
|
|
125
|
+
function side(t, amount) {
|
|
126
|
+
const decimals = t.asset === "native" ? SOL_DECIMALS : t.decimals;
|
|
127
|
+
return {
|
|
128
|
+
asset: t.asset,
|
|
129
|
+
symbol: _nullishCoalesce(t.symbol, () => ( (t.asset === "native" ? "SOL" : t.asset))),
|
|
130
|
+
decimals,
|
|
131
|
+
amount: amount.toString(),
|
|
132
|
+
amountFormatted: _chunk6XTNI2OQcjs.formatUnits.call(void 0, amount, decimals)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
async function getJson(url, init) {
|
|
136
|
+
const ctrl = new AbortController();
|
|
137
|
+
const timer = setTimeout(() => ctrl.abort(), 1e4);
|
|
138
|
+
try {
|
|
139
|
+
const res = await fetch(url, { ..._nullishCoalesce(init, () => ( {})), signal: ctrl.signal });
|
|
140
|
+
if (!res.ok) return null;
|
|
141
|
+
return await res.json();
|
|
142
|
+
} catch (e2) {
|
|
143
|
+
return null;
|
|
144
|
+
} finally {
|
|
145
|
+
clearTimeout(timer);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function quoteSolanaSwap(p) {
|
|
149
|
+
if (p.wantAmount <= 0n) return null;
|
|
150
|
+
const inputMint = mintFor(p.from);
|
|
151
|
+
const outputMint = mintFor(p.to);
|
|
152
|
+
if (inputMint === outputMint) return null;
|
|
153
|
+
const url = `${JUPITER_API}/quote?inputMint=${inputMint}&outputMint=${outputMint}&amount=${p.wantAmount.toString()}&swapMode=ExactOut&slippageBps=${p.slippageBps}`;
|
|
154
|
+
const q = await getJson(url);
|
|
155
|
+
if (!_optionalChain([q, 'optionalAccess', _ => _.otherAmountThreshold]) || !q.inAmount) return null;
|
|
156
|
+
if (q.swapMode !== "ExactOut") return null;
|
|
157
|
+
if (q.outAmount !== p.wantAmount.toString()) return null;
|
|
158
|
+
let spend;
|
|
159
|
+
let maxSpend;
|
|
160
|
+
try {
|
|
161
|
+
spend = BigInt(q.inAmount);
|
|
162
|
+
const jupCap = BigInt(q.otherAmountThreshold);
|
|
163
|
+
const ourCap = _chunkMZXVXC3Ccjs.applySlippage.call(void 0, spend, p.slippageBps);
|
|
164
|
+
maxSpend = jupCap > ourCap ? jupCap : ourCap;
|
|
165
|
+
} catch (e3) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
if (spend <= 0n) return null;
|
|
169
|
+
const fromDecimals = p.from.asset === "native" ? SOL_DECIMALS : p.from.decimals;
|
|
170
|
+
return {
|
|
171
|
+
source: sourceFor(q.platformFee),
|
|
172
|
+
network: p.network,
|
|
173
|
+
from: side(p.from, spend),
|
|
174
|
+
to: side(p.to, p.wantAmount),
|
|
175
|
+
maxSpend: maxSpend.toString(),
|
|
176
|
+
maxSpendFormatted: _chunk6XTNI2OQcjs.formatUnits.call(void 0, maxSpend, fromDecimals),
|
|
177
|
+
slippageBps: p.slippageBps,
|
|
178
|
+
// Jupiter needs its own quote object back verbatim to build the transaction.
|
|
179
|
+
route: q
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async function swapSolana(p) {
|
|
183
|
+
const { connection, keypair, quote } = p;
|
|
184
|
+
const jupQuote = quote.route;
|
|
185
|
+
if (!_optionalChain([jupQuote, 'optionalAccess', _2 => _2.otherAmountThreshold])) {
|
|
186
|
+
throw new Error("Solana: swap quote is missing its Jupiter routing data \u2014 re-quote before swapping.");
|
|
187
|
+
}
|
|
188
|
+
const built = await getJson(`${JUPITER_API}/swap`, {
|
|
189
|
+
method: "POST",
|
|
190
|
+
headers: { "content-type": "application/json" },
|
|
191
|
+
body: JSON.stringify({
|
|
192
|
+
quoteResponse: jupQuote,
|
|
193
|
+
userPublicKey: keypair.publicKey.toBase58(),
|
|
194
|
+
// Let Jupiter create + close the wrapped-SOL account in the same transaction,
|
|
195
|
+
// so a SOL leg needs no separate setup step from the caller.
|
|
196
|
+
wrapAndUnwrapSol: true,
|
|
197
|
+
dynamicComputeUnitLimit: true
|
|
198
|
+
})
|
|
199
|
+
});
|
|
200
|
+
if (!_optionalChain([built, 'optionalAccess', _3 => _3.swapTransaction])) {
|
|
201
|
+
throw new (0, _chunk6XTNI2OQcjs.InsufficientFundsError)(
|
|
202
|
+
"Jupiter could not build this swap transaction (no route, or the market moved). Nothing was spent \u2014 re-quote and retry."
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
let tx;
|
|
206
|
+
try {
|
|
207
|
+
tx = _web3js.VersionedTransaction.deserialize(Buffer.from(built.swapTransaction, "base64"));
|
|
208
|
+
} catch (cause) {
|
|
209
|
+
throw new Error("Solana: Jupiter returned a transaction this SDK could not decode.", { cause });
|
|
210
|
+
}
|
|
211
|
+
tx.sign([keypair]);
|
|
212
|
+
try {
|
|
213
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
|
|
214
|
+
const sig = await connection.sendRawTransaction(tx.serialize(), {
|
|
215
|
+
skipPreflight: false,
|
|
216
|
+
maxRetries: 3
|
|
217
|
+
});
|
|
218
|
+
const conf = await connection.confirmTransaction(
|
|
219
|
+
{ signature: sig, blockhash, lastValidBlockHeight },
|
|
220
|
+
"confirmed"
|
|
221
|
+
);
|
|
222
|
+
if (_optionalChain([conf, 'optionalAccess', _4 => _4.value, 'optionalAccess', _5 => _5.err])) {
|
|
223
|
+
throw new (0, _chunk6XTNI2OQcjs.InsufficientFundsError)(
|
|
224
|
+
`Solana swap failed on-chain (tx ${sig}): ${JSON.stringify(conf.value.err)}. Nothing was swapped. The usual cause is slippage \u2014 re-quote and retry.`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
transaction: sig,
|
|
229
|
+
network: quote.network,
|
|
230
|
+
source: quote.source,
|
|
231
|
+
from: quote.from,
|
|
232
|
+
to: quote.to
|
|
233
|
+
};
|
|
234
|
+
} catch (err) {
|
|
235
|
+
const msg = String(_nullishCoalesce(_optionalChain([err, 'optionalAccess', _6 => _6.message]), () => ( err)));
|
|
236
|
+
if (/insufficient|0x1\b/i.test(msg)) {
|
|
237
|
+
throw new (0, _chunk6XTNI2OQcjs.InsufficientFundsError)(
|
|
238
|
+
`Solana swap failed: the wallet can't cover it (token balance, or SOL for fees and rent). (${msg.slice(0, 160)})`,
|
|
239
|
+
{ cause: err }
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
if (/slippage|0x1771/i.test(msg)) {
|
|
243
|
+
throw new (0, _chunk6XTNI2OQcjs.InsufficientFundsError)(
|
|
244
|
+
"Solana swap refused: the price moved past your slippage cap, so nothing was spent. Re-quote and retry, or raise slippageBps.",
|
|
245
|
+
{ cause: err }
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
105
252
|
// src/drivers/solana/verify.ts
|
|
106
253
|
async function verifySolana(params) {
|
|
107
254
|
const { connection, signature, accept } = params;
|
|
@@ -112,7 +259,7 @@ async function verifySolana(params) {
|
|
|
112
259
|
commitment: "confirmed",
|
|
113
260
|
maxSupportedTransactionVersion: 0
|
|
114
261
|
});
|
|
115
|
-
} catch (
|
|
262
|
+
} catch (e4) {
|
|
116
263
|
return notFound(signature);
|
|
117
264
|
}
|
|
118
265
|
if (!tx) return notFound(signature);
|
|
@@ -171,7 +318,7 @@ async function verifySolana(params) {
|
|
|
171
318
|
for (const p of post) {
|
|
172
319
|
if (p.mint !== mint || p.owner !== accept.payTo) continue;
|
|
173
320
|
const before = pre.find((x) => x.accountIndex === p.accountIndex);
|
|
174
|
-
delta += BigInt(p.uiTokenAmount.amount) - BigInt(_nullishCoalesce(_optionalChain([before, 'optionalAccess',
|
|
321
|
+
delta += BigInt(p.uiTokenAmount.amount) - BigInt(_nullishCoalesce(_optionalChain([before, 'optionalAccess', _7 => _7.uiTokenAmount, 'access', _8 => _8.amount]), () => ( "0")));
|
|
175
322
|
}
|
|
176
323
|
if (delta < required) {
|
|
177
324
|
return {
|
|
@@ -229,15 +376,15 @@ var MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 100000n;
|
|
|
229
376
|
var CB_SET_UNIT_LIMIT = 2;
|
|
230
377
|
var CB_SET_UNIT_PRICE = 3;
|
|
231
378
|
function tokenProgramFor(accept) {
|
|
232
|
-
return _optionalChain([accept, 'access',
|
|
379
|
+
return _optionalChain([accept, 'access', _9 => _9.extra, 'optionalAccess', _10 => _10.tokenProgram]) === "token-2022" ? _spltoken.TOKEN_2022_PROGRAM_ID : _spltoken.TOKEN_PROGRAM_ID;
|
|
233
380
|
}
|
|
234
381
|
async function readMintDecimals(connection, mint) {
|
|
235
382
|
try {
|
|
236
383
|
const info = await connection.getAccountInfo(mint);
|
|
237
|
-
const data = _optionalChain([info, 'optionalAccess',
|
|
384
|
+
const data = _optionalChain([info, 'optionalAccess', _11 => _11.data]);
|
|
238
385
|
if (!data || data.length < 45) return void 0;
|
|
239
386
|
return data[44];
|
|
240
|
-
} catch (
|
|
387
|
+
} catch (e5) {
|
|
241
388
|
return void 0;
|
|
242
389
|
}
|
|
243
390
|
}
|
|
@@ -246,8 +393,8 @@ function isEmptySig(sig) {
|
|
|
246
393
|
}
|
|
247
394
|
function memoRandomNonce() {
|
|
248
395
|
const g = globalThis.crypto;
|
|
249
|
-
if (!_optionalChain([g, 'optionalAccess',
|
|
250
|
-
throw new (0,
|
|
396
|
+
if (!_optionalChain([g, 'optionalAccess', _12 => _12.getRandomValues])) {
|
|
397
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
251
398
|
"this runtime lacks Web Crypto (globalThis.crypto.getRandomValues); SVM exact needs a CSPRNG nonce."
|
|
252
399
|
);
|
|
253
400
|
}
|
|
@@ -256,10 +403,10 @@ function memoRandomNonce() {
|
|
|
256
403
|
return Buffer.from([...raw].map((b) => b.toString(16).padStart(2, "0")).join(""), "utf8");
|
|
257
404
|
}
|
|
258
405
|
function memoDataFor(accept) {
|
|
259
|
-
if (_optionalChain([accept, 'access',
|
|
406
|
+
if (_optionalChain([accept, 'access', _13 => _13.extra, 'optionalAccess', _14 => _14.memo]) !== void 0) {
|
|
260
407
|
const bytes = Buffer.from(accept.extra.memo, "utf8");
|
|
261
408
|
if (bytes.length > MAX_MEMO_BYTES) {
|
|
262
|
-
throw new (0,
|
|
409
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
263
410
|
`SVM exact: extra.memo is ${bytes.length} bytes; the scheme caps it at ${MAX_MEMO_BYTES}.`
|
|
264
411
|
);
|
|
265
412
|
}
|
|
@@ -273,13 +420,13 @@ function memoInstruction(accept) {
|
|
|
273
420
|
async function payExactSolana(input) {
|
|
274
421
|
const { connection, keypair, accept } = input;
|
|
275
422
|
if (accept.asset === "native") {
|
|
276
|
-
throw new (0,
|
|
423
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
277
424
|
"SVM exact is SPL-token only (TransferChecked); native SOL is not exact-payable. Pay via onchain-proof."
|
|
278
425
|
);
|
|
279
426
|
}
|
|
280
427
|
const extra = _nullishCoalesce(accept.extra, () => ( {}));
|
|
281
428
|
if (!extra.feePayer) {
|
|
282
|
-
throw new (0,
|
|
429
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)("SVM exact rail must advertise extra.feePayer (the merchant sponsor key).");
|
|
283
430
|
}
|
|
284
431
|
let feePayer;
|
|
285
432
|
let mint;
|
|
@@ -289,24 +436,24 @@ async function payExactSolana(input) {
|
|
|
289
436
|
mint = new (0, _web3js.PublicKey)(accept.asset);
|
|
290
437
|
payTo = new (0, _web3js.PublicKey)(accept.payTo);
|
|
291
438
|
} catch (err) {
|
|
292
|
-
throw new (0,
|
|
439
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
293
440
|
`SVM exact: bad feePayer/asset/payTo (${err instanceof Error ? err.message : String(err)}).`
|
|
294
441
|
);
|
|
295
442
|
}
|
|
296
443
|
const onChainDecimals = await readMintDecimals(connection, mint);
|
|
297
444
|
const decimals = _nullishCoalesce(onChainDecimals, () => ( extra.decimals));
|
|
298
445
|
if (decimals === void 0) {
|
|
299
|
-
throw new (0,
|
|
446
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
300
447
|
`SVM exact: couldn't read the decimals of mint ${accept.asset} on-chain, and the rail states none. Retry with a reliable rpcUrl \u2014 TransferChecked cannot be built without them.`
|
|
301
448
|
);
|
|
302
449
|
}
|
|
303
450
|
if (onChainDecimals !== void 0 && extra.decimals !== void 0 && extra.decimals !== onChainDecimals) {
|
|
304
|
-
throw new (0,
|
|
451
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
305
452
|
`SVM exact: the rail states ${extra.decimals} decimals for ${accept.asset} but the mint says ${onChainDecimals} \u2014 refusing to sign (a mismatch this size misprices the transfer).`
|
|
306
453
|
);
|
|
307
454
|
}
|
|
308
455
|
if (feePayer.equals(payTo)) {
|
|
309
|
-
throw new (0,
|
|
456
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
310
457
|
"SVM exact: the fee payer must differ from payTo \u2014 payTo appears in the transfer instruction, which the fee payer must not (a scheme MUST-rule). Use a separate relayer key for the gate."
|
|
311
458
|
);
|
|
312
459
|
}
|
|
@@ -316,11 +463,11 @@ async function payExactSolana(input) {
|
|
|
316
463
|
let destInfo = "unknown";
|
|
317
464
|
try {
|
|
318
465
|
destInfo = await input.connection.getAccountInfo(dest);
|
|
319
|
-
} catch (
|
|
466
|
+
} catch (e6) {
|
|
320
467
|
destInfo = "unknown";
|
|
321
468
|
}
|
|
322
469
|
if (destInfo === null) {
|
|
323
|
-
throw new (0,
|
|
470
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)(
|
|
324
471
|
`SVM exact: the recipient's token account for ${mint.toBase58()} doesn't exist yet \u2014 the exact rail can't create it. Pay via onchain-proof (which creates it), or have ${payTo.toBase58()} create its associated token account first.`
|
|
325
472
|
);
|
|
326
473
|
}
|
|
@@ -352,11 +499,11 @@ async function payExactSolana(input) {
|
|
|
352
499
|
tx.sign([keypair]);
|
|
353
500
|
const buyerIndex = message.staticAccountKeys.findIndex((k) => k.equals(keypair.publicKey));
|
|
354
501
|
if (buyerIndex < 1 || buyerIndex >= message.header.numRequiredSignatures) {
|
|
355
|
-
throw new (0,
|
|
502
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)("SVM exact: could not locate the buyer signer slot.");
|
|
356
503
|
}
|
|
357
504
|
const buyerSig = tx.signatures[buyerIndex];
|
|
358
505
|
if (!buyerSig || isEmptySig(buyerSig)) {
|
|
359
|
-
throw new (0,
|
|
506
|
+
throw new (0, _chunk6XTNI2OQcjs.UnsupportedSchemeError)("SVM exact: the wallet did not produce a buyer signature.");
|
|
360
507
|
}
|
|
361
508
|
const transaction = Buffer.from(tx.serialize()).toString("base64");
|
|
362
509
|
return {
|
|
@@ -380,18 +527,18 @@ async function verifyAndSettleExactSolana(input) {
|
|
|
380
527
|
try {
|
|
381
528
|
payTo = new (0, _web3js.PublicKey)(accept.payTo);
|
|
382
529
|
mint = new (0, _web3js.PublicKey)(accept.asset);
|
|
383
|
-
if (!_optionalChain([accept, 'access',
|
|
530
|
+
if (!_optionalChain([accept, 'access', _15 => _15.extra, 'optionalAccess', _16 => _16.feePayer])) throw new Error("rail is missing extra.feePayer");
|
|
384
531
|
railFeePayer = new (0, _web3js.PublicKey)(accept.extra.feePayer);
|
|
385
532
|
} catch (err) {
|
|
386
|
-
throw new (0,
|
|
533
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(`SVM exact: rail has a bad payTo/asset/feePayer (${err instanceof Error ? err.message : String(err)}).`);
|
|
387
534
|
}
|
|
388
535
|
if (!railFeePayer.equals(feePayerKeypair.publicKey)) {
|
|
389
|
-
throw new (0,
|
|
536
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(
|
|
390
537
|
"SVM exact: the gate relayer key does not match the rail extra.feePayer \u2014 misconfigured rail."
|
|
391
538
|
);
|
|
392
539
|
}
|
|
393
540
|
if (feePayerKeypair.publicKey.equals(payTo)) {
|
|
394
|
-
throw new (0,
|
|
541
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)("SVM exact: the fee payer must differ from payTo \u2014 misconfigured rail.");
|
|
395
542
|
}
|
|
396
543
|
const program = tokenProgramFor(accept);
|
|
397
544
|
let tx;
|
|
@@ -410,7 +557,7 @@ async function verifyAndSettleExactSolana(input) {
|
|
|
410
557
|
try {
|
|
411
558
|
;
|
|
412
559
|
({ value } = await connection.getAddressLookupTable(lookup.accountKey));
|
|
413
|
-
} catch (
|
|
560
|
+
} catch (e7) {
|
|
414
561
|
return fail("tx_not_found", `Could not read lookup table ${lookup.accountKey.toBase58()} (transient RPC) \u2014 retry.`);
|
|
415
562
|
}
|
|
416
563
|
if (!value) {
|
|
@@ -432,7 +579,7 @@ async function verifyAndSettleExactSolana(input) {
|
|
|
432
579
|
return fail("signature_invalid", "The fee payer is invoked as a program.");
|
|
433
580
|
}
|
|
434
581
|
for (const i of ix.accountKeyIndexes) {
|
|
435
|
-
if (_optionalChain([keys, 'access',
|
|
582
|
+
if (_optionalChain([keys, 'access', _17 => _17.get, 'call', _18 => _18(i), 'optionalAccess', _19 => _19.equals, 'call', _20 => _20(feePayerKey)])) {
|
|
436
583
|
return fail("signature_invalid", "The fee payer appears in an instruction account list (would risk a fund drain).");
|
|
437
584
|
}
|
|
438
585
|
}
|
|
@@ -481,14 +628,14 @@ async function verifyAndSettleExactSolana(input) {
|
|
|
481
628
|
}),
|
|
482
629
|
program
|
|
483
630
|
);
|
|
484
|
-
} catch (
|
|
631
|
+
} catch (e8) {
|
|
485
632
|
continue;
|
|
486
633
|
}
|
|
487
634
|
if (!decoded.keys.mint.pubkey.equals(mint)) continue;
|
|
488
635
|
if (!decoded.keys.destination.pubkey.equals(expectedDest)) {
|
|
489
636
|
return fail("wrong_recipient", `A transfer pays ${decoded.keys.destination.pubkey.toBase58()}, not payTo's ATA ${expectedDest.toBase58()}.`);
|
|
490
637
|
}
|
|
491
|
-
if (_optionalChain([accept, 'access',
|
|
638
|
+
if (_optionalChain([accept, 'access', _21 => _21.extra, 'optionalAccess', _22 => _22.decimals]) !== void 0 && decoded.data.decimals !== accept.extra.decimals) {
|
|
492
639
|
return fail("transfer_not_found", `Transfer decimals ${decoded.data.decimals} \u2260 rail decimals ${accept.extra.decimals}.`);
|
|
493
640
|
}
|
|
494
641
|
sawTransferToPayTo = true;
|
|
@@ -533,7 +680,7 @@ async function verifyAndSettleExactSolana(input) {
|
|
|
533
680
|
} catch (err) {
|
|
534
681
|
const msg = err instanceof Error ? err.message : String(err);
|
|
535
682
|
if (/blockhash|block height|expired/i.test(msg)) return fail("payment_expired", `Settle broadcast rejected \u2014 blockhash expired: ${shorten(msg)}.`);
|
|
536
|
-
throw new (0,
|
|
683
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(
|
|
537
684
|
`SVM exact settle: the merchant fee payer failed to broadcast (${shorten(msg)}). The buyer's signed transaction is still valid \u2014 fund/fix the fee payer and the buyer can re-present it.`,
|
|
538
685
|
{ cause: err }
|
|
539
686
|
);
|
|
@@ -543,7 +690,7 @@ async function verifyAndSettleExactSolana(input) {
|
|
|
543
690
|
return fail("tx_reverted", `Settle tx ${txid} reverted on-chain (a post-simulate race).`);
|
|
544
691
|
}
|
|
545
692
|
if (confirmed === "timeout") {
|
|
546
|
-
throw new (0,
|
|
693
|
+
throw new (0, _chunk6XTNI2OQcjs.SettlementError)(
|
|
547
694
|
`SVM exact settle: broadcast ${txid} but it did not confirm in time. It likely landed \u2014 re-verify by signature before re-presenting; do NOT re-pay.`
|
|
548
695
|
);
|
|
549
696
|
}
|
|
@@ -569,7 +716,7 @@ async function pollConfirmed(connection, signature) {
|
|
|
569
716
|
try {
|
|
570
717
|
const { value } = await connection.getSignatureStatuses([signature], { searchTransactionHistory: true });
|
|
571
718
|
info = value[0];
|
|
572
|
-
} catch (
|
|
719
|
+
} catch (e9) {
|
|
573
720
|
info = null;
|
|
574
721
|
}
|
|
575
722
|
if (info) {
|
|
@@ -586,18 +733,18 @@ async function pollConfirmed(connection, signature) {
|
|
|
586
733
|
|
|
587
734
|
function toKeypair(wallet, network) {
|
|
588
735
|
if (typeof wallet !== "object" || wallet === null) {
|
|
589
|
-
throw new (0,
|
|
736
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
590
737
|
`chain ${network} is Solana; wallet must be { key } (base58 secret) or { signer }.`
|
|
591
738
|
);
|
|
592
739
|
}
|
|
593
|
-
|
|
740
|
+
_chunk6XTNI2OQcjs.assertNoLegacyWalletKey.call(void 0, wallet, "Solana");
|
|
594
741
|
if ("signer" in wallet) {
|
|
595
742
|
return wallet.signer;
|
|
596
743
|
}
|
|
597
744
|
if ("key" in wallet) {
|
|
598
745
|
const sk = wallet.key;
|
|
599
746
|
if (typeof sk === "string" && sk.startsWith("0x")) {
|
|
600
|
-
throw new (0,
|
|
747
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
601
748
|
`chain ${network} is Solana, but the wallet { key } is a 0x\u2026 hex key \u2014 that's an EVM key. A Solana key is a base58 secret string (or a 64-byte Uint8Array).`
|
|
602
749
|
);
|
|
603
750
|
}
|
|
@@ -605,12 +752,12 @@ function toKeypair(wallet, network) {
|
|
|
605
752
|
const bytes = typeof sk === "string" ? _bs582.default.decode(sk) : sk;
|
|
606
753
|
return _web3js.Keypair.fromSecretKey(bytes);
|
|
607
754
|
} catch (err) {
|
|
608
|
-
throw new (0,
|
|
755
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
609
756
|
`chain ${network} is Solana; the wallet { key } isn't a valid Solana secret (expected a base58 secret string or a 64-byte Uint8Array): ${err instanceof Error ? err.message : String(err)}.`
|
|
610
757
|
);
|
|
611
758
|
}
|
|
612
759
|
}
|
|
613
|
-
throw new (0,
|
|
760
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
614
761
|
`chain ${network} is Solana; wallet must be { key } (base58 secret) or { signer }.`
|
|
615
762
|
);
|
|
616
763
|
}
|
|
@@ -639,15 +786,15 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
639
786
|
const info = preset.tokens[token.toUpperCase()];
|
|
640
787
|
if (!info) {
|
|
641
788
|
const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
|
|
642
|
-
throw new (0,
|
|
789
|
+
throw new (0, _chunk6XTNI2OQcjs.UnknownTokenError)(
|
|
643
790
|
`token "${token}" isn't built in for Solana (known: ${known}). Pass { mint, decimals } instead, or use 'native'.`
|
|
644
791
|
);
|
|
645
792
|
}
|
|
646
793
|
return { asset: info.mint, decimals: info.decimals, symbol: info.symbol };
|
|
647
794
|
}
|
|
648
|
-
|
|
795
|
+
_chunk6XTNI2OQcjs.rejectForeignToken.call(void 0, token, "solana", network);
|
|
649
796
|
if (!("mint" in token)) {
|
|
650
|
-
throw new (0,
|
|
797
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
651
798
|
`chain ${network} is Solana; a custom token must be { mint, decimals }.`
|
|
652
799
|
);
|
|
653
800
|
}
|
|
@@ -666,14 +813,14 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
666
813
|
},
|
|
667
814
|
assertValidPayTo(payTo) {
|
|
668
815
|
if (payTo.startsWith("0x")) {
|
|
669
|
-
throw new (0,
|
|
816
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
670
817
|
`chain ${network} is Solana, but payTo "${payTo}" looks like an EVM address.`
|
|
671
818
|
);
|
|
672
819
|
}
|
|
673
820
|
try {
|
|
674
821
|
new (0, _web3js.PublicKey)(payTo);
|
|
675
|
-
} catch (
|
|
676
|
-
throw new (0,
|
|
822
|
+
} catch (e10) {
|
|
823
|
+
throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
|
|
677
824
|
`chain ${network} is Solana, but payTo "${payTo}" is not a base58 address.`
|
|
678
825
|
);
|
|
679
826
|
}
|
|
@@ -685,7 +832,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
685
832
|
try {
|
|
686
833
|
return await paySolana({ connection, keypair: wallet._native, accept });
|
|
687
834
|
} catch (err) {
|
|
688
|
-
throw _nullishCoalesce(
|
|
835
|
+
throw _nullishCoalesce(_chunk6XTNI2OQcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
|
|
689
836
|
}
|
|
690
837
|
},
|
|
691
838
|
async confirm(ref) {
|
|
@@ -696,19 +843,19 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
696
843
|
});
|
|
697
844
|
info = value[0];
|
|
698
845
|
} catch (err) {
|
|
699
|
-
throw new (0,
|
|
846
|
+
throw new (0, _chunk6XTNI2OQcjs.ConfirmationTimeoutError)(
|
|
700
847
|
`Solana payment ${ref} could not be confirmed (RPC read failed).`,
|
|
701
848
|
{ cause: err }
|
|
702
849
|
);
|
|
703
850
|
}
|
|
704
851
|
if (!info || info.err || info.confirmationStatus !== "confirmed" && info.confirmationStatus !== "finalized") {
|
|
705
|
-
throw new (0,
|
|
852
|
+
throw new (0, _chunk6XTNI2OQcjs.ConfirmationTimeoutError)(`Solana payment ${ref} did not confirm in time.`);
|
|
706
853
|
}
|
|
707
854
|
return { height: String(info.slot) };
|
|
708
855
|
},
|
|
709
856
|
async estimateCost(accept) {
|
|
710
857
|
if (accept.scheme === "exact") {
|
|
711
|
-
return
|
|
858
|
+
return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
|
|
712
859
|
symbol: "SOL",
|
|
713
860
|
decimals: SOL_DECIMALS,
|
|
714
861
|
fee: 0n,
|
|
@@ -718,7 +865,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
718
865
|
}
|
|
719
866
|
const base = 5000n;
|
|
720
867
|
if (accept.asset === "native") {
|
|
721
|
-
return
|
|
868
|
+
return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
|
|
722
869
|
symbol: "SOL",
|
|
723
870
|
decimals: SOL_DECIMALS,
|
|
724
871
|
fee: base,
|
|
@@ -727,7 +874,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
727
874
|
});
|
|
728
875
|
}
|
|
729
876
|
const ataRent = 2039280n;
|
|
730
|
-
return
|
|
877
|
+
return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
|
|
731
878
|
symbol: "SOL",
|
|
732
879
|
decimals: SOL_DECIMALS,
|
|
733
880
|
fee: base + ataRent,
|
|
@@ -735,6 +882,11 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
735
882
|
detail: "1 signature + recipient token-account rent (~0.00204 SOL, if not already created)"
|
|
736
883
|
});
|
|
737
884
|
},
|
|
885
|
+
/** The bound wallet's own address — where THIS wallet gets paid. Derived from the key
|
|
886
|
+
* material only: no RPC, nothing moved. See {@link ResolvedNetwork.addressOf}. */
|
|
887
|
+
async addressOf(wallet) {
|
|
888
|
+
return wallet._native.publicKey.toBase58();
|
|
889
|
+
},
|
|
738
890
|
async balanceOf(wallet, asset) {
|
|
739
891
|
const owner = wallet._native.publicKey;
|
|
740
892
|
const native = await connection.getBalance(owner).then((n) => BigInt(n)).catch(() => null);
|
|
@@ -743,7 +895,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
743
895
|
try {
|
|
744
896
|
const mint = new (0, _web3js.PublicKey)(asset);
|
|
745
897
|
const info = await connection.getAccountInfo(mint);
|
|
746
|
-
const programId = _optionalChain([info, 'optionalAccess',
|
|
898
|
+
const programId = _optionalChain([info, 'optionalAccess', _23 => _23.owner, 'access', _24 => _24.equals, 'call', _25 => _25(_spltoken.TOKEN_2022_PROGRAM_ID)]) ? _spltoken.TOKEN_2022_PROGRAM_ID : _spltoken.TOKEN_PROGRAM_ID;
|
|
747
899
|
const ata = _spltoken.getAssociatedTokenAddressSync.call(void 0, mint, owner, false, programId);
|
|
748
900
|
token = (await _spltoken.getAccount.call(void 0, connection, ata, "confirmed", programId)).amount;
|
|
749
901
|
} catch (e) {
|
|
@@ -764,6 +916,13 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
764
916
|
async recipientReady() {
|
|
765
917
|
return { ready: "n/a" };
|
|
766
918
|
},
|
|
919
|
+
/* ---- swap (OPTIONAL, opt-in): via Jupiter, keyless + no platform fee. See ./swap.ts ---- */
|
|
920
|
+
async quoteSwap({ from, to, wantAmount, slippageBps }) {
|
|
921
|
+
return quoteSolanaSwap({ network, from, to, wantAmount, slippageBps });
|
|
922
|
+
},
|
|
923
|
+
async swap(wallet, quote) {
|
|
924
|
+
return swapSolana({ connection, keypair: wallet._native, quote });
|
|
925
|
+
},
|
|
767
926
|
async verify(ref, accept) {
|
|
768
927
|
return verifySolana({ connection, signature: ref, accept });
|
|
769
928
|
},
|
|
@@ -801,14 +960,14 @@ function makeSolanaNetwork(preset, rpcUrl) {
|
|
|
801
960
|
if (!fp) return null;
|
|
802
961
|
try {
|
|
803
962
|
new (0, _web3js.PublicKey)(fp);
|
|
804
|
-
} catch (
|
|
963
|
+
} catch (e11) {
|
|
805
964
|
return null;
|
|
806
965
|
}
|
|
807
966
|
let tokenProgram = "spl-token";
|
|
808
967
|
try {
|
|
809
968
|
const info = await connection.getAccountInfo(new (0, _web3js.PublicKey)(asset));
|
|
810
|
-
if (_optionalChain([info, 'optionalAccess',
|
|
811
|
-
} catch (
|
|
969
|
+
if (_optionalChain([info, 'optionalAccess', _26 => _26.owner, 'access', _27 => _27.equals, 'call', _28 => _28(_spltoken.TOKEN_2022_PROGRAM_ID)])) tokenProgram = "token-2022";
|
|
970
|
+
} catch (e12) {
|
|
812
971
|
}
|
|
813
972
|
return { method: "svm", extra: { feePayer: fp, tokenProgram } };
|
|
814
973
|
}
|