@piprail/sdk 2.16.2 → 3.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +448 -0
  2. package/README.md +1 -0
  3. package/dist/{algorand-Q3TUQLPK.cjs → algorand-4FTTEV7X.cjs} +212 -51
  4. package/dist/{algorand-25FMBCT3.js → algorand-KJ5XHSMT.js} +164 -3
  5. package/dist/{aptos-VBJONBFY.cjs → aptos-5QBXJ6NV.cjs} +255 -39
  6. package/dist/{aptos-SBV6SGDP.js → aptos-H5VLH2QL.js} +217 -1
  7. package/dist/{chunk-QONQSZHJ.cjs → chunk-6XTNI2OQ.cjs} +44 -44
  8. package/dist/{chunk-OXEFPLZA.cjs → chunk-6ZRAIQXF.cjs} +4 -4
  9. package/dist/chunk-GVCGUSTE.js +30 -0
  10. package/dist/{chunk-V2IJ5HUW.cjs → chunk-MZAJQYM3.cjs} +1 -0
  11. package/dist/chunk-MZXVXC3C.cjs +30 -0
  12. package/dist/{chunk-2CX7XRZK.js → chunk-TZDVZCTC.js} +1 -0
  13. package/dist/{chunk-C52H5TYB.js → chunk-YXBQKBDH.js} +2 -2
  14. package/dist/index.cjs +2906 -1262
  15. package/dist/index.d.cts +679 -21
  16. package/dist/index.d.ts +679 -21
  17. package/dist/index.js +2678 -1034
  18. package/dist/{ledger-Crc1bZox.d.cts → ledger-DkHUORUe.d.cts} +7 -0
  19. package/dist/{ledger-Crc1bZox.d.ts → ledger-DkHUORUe.d.ts} +7 -0
  20. package/dist/{near-OLKCMTBI.js → near-5X2CQGML.js} +197 -1
  21. package/dist/{near-5LTTDU6G.cjs → near-XSQXEIHT.cjs} +242 -46
  22. package/dist/node.d.cts +2 -2
  23. package/dist/node.d.ts +2 -2
  24. package/dist/{solana-AI2G7V33.cjs → solana-TIEJV742.cjs} +218 -53
  25. package/dist/{solana-HTKDRTD3.js → solana-WRXL54MR.js} +174 -9
  26. package/dist/{stellar-E2KWEV2E.cjs → stellar-5GMZJBTA.cjs} +200 -30
  27. package/dist/{stellar-EUFZLX6J.js → stellar-YQLOIFDD.js} +172 -2
  28. package/dist/{sui-KCIITCYH.js → sui-JFQSDNSZ.js} +165 -3
  29. package/dist/{sui-Q3NJOJZS.cjs → sui-WIZEAO7E.cjs} +185 -23
  30. package/dist/{ton-J7TQWRN4.cjs → ton-AGTKLQA5.cjs} +264 -22
  31. package/dist/{ton-WH2JVQOO.js → ton-OZKFNRLT.js} +244 -2
  32. package/dist/{tron-FXBXDNEY.js → tron-HG3IOOCG.js} +283 -1
  33. package/dist/{tron-HIPMOX7S.cjs → tron-S4WX7OHY.cjs} +323 -41
  34. package/dist/{xrpl-RUOB37QH.js → xrpl-5K444RGX.js} +238 -6
  35. package/dist/{xrpl-SVVS445B.cjs → xrpl-G2FKFXRI.cjs} +289 -57
  36. package/package.json +12 -2
  37. 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
- var _chunkQONQSZHJcjs = require('./chunk-QONQSZHJ.cjs');
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 (e2) {
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', _ => _.uiTokenAmount, 'access', _2 => _2.amount]), () => ( "0")));
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', _3 => _3.extra, 'optionalAccess', _4 => _4.tokenProgram]) === "token-2022" ? _spltoken.TOKEN_2022_PROGRAM_ID : _spltoken.TOKEN_PROGRAM_ID;
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', _5 => _5.data]);
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 (e3) {
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', _6 => _6.getRandomValues])) {
250
- throw new (0, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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', _7 => _7.extra, 'optionalAccess', _8 => _8.memo]) !== void 0) {
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)("SVM exact rail must advertise extra.feePayer (the merchant sponsor key).");
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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 (e4) {
466
+ } catch (e6) {
320
467
  destInfo = "unknown";
321
468
  }
322
469
  if (destInfo === null) {
323
- throw new (0, _chunkQONQSZHJcjs.UnsupportedSchemeError)(
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)("SVM exact: could not locate the buyer signer slot.");
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, _chunkQONQSZHJcjs.UnsupportedSchemeError)("SVM exact: the wallet did not produce a buyer signature.");
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', _9 => _9.extra, 'optionalAccess', _10 => _10.feePayer])) throw new Error("rail is missing extra.feePayer");
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, _chunkQONQSZHJcjs.SettlementError)(`SVM exact: rail has a bad payTo/asset/feePayer (${err instanceof Error ? err.message : String(err)}).`);
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, _chunkQONQSZHJcjs.SettlementError)(
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, _chunkQONQSZHJcjs.SettlementError)("SVM exact: the fee payer must differ from payTo \u2014 misconfigured rail.");
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 (e5) {
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', _11 => _11.get, 'call', _12 => _12(i), 'optionalAccess', _13 => _13.equals, 'call', _14 => _14(feePayerKey)])) {
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 (e6) {
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', _15 => _15.extra, 'optionalAccess', _16 => _16.decimals]) !== void 0 && decoded.data.decimals !== accept.extra.decimals) {
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, _chunkQONQSZHJcjs.SettlementError)(
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, _chunkQONQSZHJcjs.SettlementError)(
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 (e7) {
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, _chunkQONQSZHJcjs.WrongFamilyError)(
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
- _chunkQONQSZHJcjs.assertNoLegacyWalletKey.call(void 0, wallet, "Solana");
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, _chunkQONQSZHJcjs.WrongFamilyError)(
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,17 +752,18 @@ 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, _chunkQONQSZHJcjs.WrongFamilyError)(
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, _chunkQONQSZHJcjs.WrongFamilyError)(
760
+ throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
614
761
  `chain ${network} is Solana; wallet must be { key } (base58 secret) or { signer }.`
615
762
  );
616
763
  }
617
764
 
618
765
  // src/drivers/solana/index.ts
766
+ var RENT_EXEMPT_MIN_LAMPORTS = 890880n;
619
767
  var solanaDriver = {
620
768
  family: "solana",
621
769
  resolve(opts) {
@@ -639,15 +787,15 @@ function makeSolanaNetwork(preset, rpcUrl) {
639
787
  const info = preset.tokens[token.toUpperCase()];
640
788
  if (!info) {
641
789
  const known = Object.keys(preset.tokens).join(", ") || "(none built in)";
642
- throw new (0, _chunkQONQSZHJcjs.UnknownTokenError)(
790
+ throw new (0, _chunk6XTNI2OQcjs.UnknownTokenError)(
643
791
  `token "${token}" isn't built in for Solana (known: ${known}). Pass { mint, decimals } instead, or use 'native'.`
644
792
  );
645
793
  }
646
794
  return { asset: info.mint, decimals: info.decimals, symbol: info.symbol };
647
795
  }
648
- _chunkQONQSZHJcjs.rejectForeignToken.call(void 0, token, "solana", network);
796
+ _chunk6XTNI2OQcjs.rejectForeignToken.call(void 0, token, "solana", network);
649
797
  if (!("mint" in token)) {
650
- throw new (0, _chunkQONQSZHJcjs.WrongFamilyError)(
798
+ throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
651
799
  `chain ${network} is Solana; a custom token must be { mint, decimals }.`
652
800
  );
653
801
  }
@@ -666,14 +814,14 @@ function makeSolanaNetwork(preset, rpcUrl) {
666
814
  },
667
815
  assertValidPayTo(payTo) {
668
816
  if (payTo.startsWith("0x")) {
669
- throw new (0, _chunkQONQSZHJcjs.WrongFamilyError)(
817
+ throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
670
818
  `chain ${network} is Solana, but payTo "${payTo}" looks like an EVM address.`
671
819
  );
672
820
  }
673
821
  try {
674
822
  new (0, _web3js.PublicKey)(payTo);
675
- } catch (e8) {
676
- throw new (0, _chunkQONQSZHJcjs.WrongFamilyError)(
823
+ } catch (e10) {
824
+ throw new (0, _chunk6XTNI2OQcjs.WrongFamilyError)(
677
825
  `chain ${network} is Solana, but payTo "${payTo}" is not a base58 address.`
678
826
  );
679
827
  }
@@ -685,7 +833,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
685
833
  try {
686
834
  return await paySolana({ connection, keypair: wallet._native, accept });
687
835
  } catch (err) {
688
- throw _nullishCoalesce(_chunkQONQSZHJcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
836
+ throw _nullishCoalesce(_chunk6XTNI2OQcjs.toInsufficientFundsError.call(void 0, err), () => ( err));
689
837
  }
690
838
  },
691
839
  async confirm(ref) {
@@ -696,19 +844,19 @@ function makeSolanaNetwork(preset, rpcUrl) {
696
844
  });
697
845
  info = value[0];
698
846
  } catch (err) {
699
- throw new (0, _chunkQONQSZHJcjs.ConfirmationTimeoutError)(
847
+ throw new (0, _chunk6XTNI2OQcjs.ConfirmationTimeoutError)(
700
848
  `Solana payment ${ref} could not be confirmed (RPC read failed).`,
701
849
  { cause: err }
702
850
  );
703
851
  }
704
852
  if (!info || info.err || info.confirmationStatus !== "confirmed" && info.confirmationStatus !== "finalized") {
705
- throw new (0, _chunkQONQSZHJcjs.ConfirmationTimeoutError)(`Solana payment ${ref} did not confirm in time.`);
853
+ throw new (0, _chunk6XTNI2OQcjs.ConfirmationTimeoutError)(`Solana payment ${ref} did not confirm in time.`);
706
854
  }
707
855
  return { height: String(info.slot) };
708
856
  },
709
857
  async estimateCost(accept) {
710
858
  if (accept.scheme === "exact") {
711
- return _chunkQONQSZHJcjs.nativeCost.call(void 0, {
859
+ return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
712
860
  symbol: "SOL",
713
861
  decimals: SOL_DECIMALS,
714
862
  fee: 0n,
@@ -718,7 +866,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
718
866
  }
719
867
  const base = 5000n;
720
868
  if (accept.asset === "native") {
721
- return _chunkQONQSZHJcjs.nativeCost.call(void 0, {
869
+ return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
722
870
  symbol: "SOL",
723
871
  decimals: SOL_DECIMALS,
724
872
  fee: base,
@@ -727,7 +875,7 @@ function makeSolanaNetwork(preset, rpcUrl) {
727
875
  });
728
876
  }
729
877
  const ataRent = 2039280n;
730
- return _chunkQONQSZHJcjs.nativeCost.call(void 0, {
878
+ return _chunk6XTNI2OQcjs.nativeCost.call(void 0, {
731
879
  symbol: "SOL",
732
880
  decimals: SOL_DECIMALS,
733
881
  fee: base + ataRent,
@@ -735,15 +883,25 @@ function makeSolanaNetwork(preset, rpcUrl) {
735
883
  detail: "1 signature + recipient token-account rent (~0.00204 SOL, if not already created)"
736
884
  });
737
885
  },
886
+ /** The bound wallet's own address — where THIS wallet gets paid. Derived from the key
887
+ * material only: no RPC, nothing moved. See {@link ResolvedNetwork.addressOf}. */
888
+ async addressOf(wallet) {
889
+ return wallet._native.publicKey.toBase58();
890
+ },
738
891
  async balanceOf(wallet, asset) {
739
892
  const owner = wallet._native.publicKey;
740
893
  const native = await connection.getBalance(owner).then((n) => BigInt(n)).catch(() => null);
741
- if (asset === "native") return { token: native, native };
894
+ if (asset === "native") {
895
+ if (native === null) return { token: null, native };
896
+ const reserve = await connection.getMinimumBalanceForRentExemption(0).then((n) => BigInt(n)).catch(() => RENT_EXEMPT_MIN_LAMPORTS);
897
+ const spendable = native > reserve ? native - reserve : 0n;
898
+ return { token: spendable, native };
899
+ }
742
900
  let token;
743
901
  try {
744
902
  const mint = new (0, _web3js.PublicKey)(asset);
745
903
  const info = await connection.getAccountInfo(mint);
746
- const programId = _optionalChain([info, 'optionalAccess', _17 => _17.owner, 'access', _18 => _18.equals, 'call', _19 => _19(_spltoken.TOKEN_2022_PROGRAM_ID)]) ? _spltoken.TOKEN_2022_PROGRAM_ID : _spltoken.TOKEN_PROGRAM_ID;
904
+ 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
905
  const ata = _spltoken.getAssociatedTokenAddressSync.call(void 0, mint, owner, false, programId);
748
906
  token = (await _spltoken.getAccount.call(void 0, connection, ata, "confirmed", programId)).amount;
749
907
  } catch (e) {
@@ -764,6 +922,13 @@ function makeSolanaNetwork(preset, rpcUrl) {
764
922
  async recipientReady() {
765
923
  return { ready: "n/a" };
766
924
  },
925
+ /* ---- swap (OPTIONAL, opt-in): via Jupiter, keyless + no platform fee. See ./swap.ts ---- */
926
+ async quoteSwap({ from, to, wantAmount, slippageBps }) {
927
+ return quoteSolanaSwap({ network, from, to, wantAmount, slippageBps });
928
+ },
929
+ async swap(wallet, quote) {
930
+ return swapSolana({ connection, keypair: wallet._native, quote });
931
+ },
767
932
  async verify(ref, accept) {
768
933
  return verifySolana({ connection, signature: ref, accept });
769
934
  },
@@ -801,14 +966,14 @@ function makeSolanaNetwork(preset, rpcUrl) {
801
966
  if (!fp) return null;
802
967
  try {
803
968
  new (0, _web3js.PublicKey)(fp);
804
- } catch (e9) {
969
+ } catch (e11) {
805
970
  return null;
806
971
  }
807
972
  let tokenProgram = "spl-token";
808
973
  try {
809
974
  const info = await connection.getAccountInfo(new (0, _web3js.PublicKey)(asset));
810
- if (_optionalChain([info, 'optionalAccess', _20 => _20.owner, 'access', _21 => _21.equals, 'call', _22 => _22(_spltoken.TOKEN_2022_PROGRAM_ID)])) tokenProgram = "token-2022";
811
- } catch (e10) {
975
+ if (_optionalChain([info, 'optionalAccess', _26 => _26.owner, 'access', _27 => _27.equals, 'call', _28 => _28(_spltoken.TOKEN_2022_PROGRAM_ID)])) tokenProgram = "token-2022";
976
+ } catch (e12) {
812
977
  }
813
978
  return { method: "svm", extra: { feePayer: fp, tokenProgram } };
814
979
  }