@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,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applySlippage
|
|
3
|
+
} from "./chunk-GVCGUSTE.js";
|
|
1
4
|
import {
|
|
2
5
|
ConfirmationTimeoutError,
|
|
3
6
|
InsufficientFundsError,
|
|
@@ -6,10 +9,11 @@ import {
|
|
|
6
9
|
UnsupportedSchemeError,
|
|
7
10
|
WrongFamilyError,
|
|
8
11
|
assertNoLegacyWalletKey,
|
|
12
|
+
formatUnits,
|
|
9
13
|
nativeCost,
|
|
10
14
|
rejectForeignToken,
|
|
11
15
|
toInsufficientFundsError
|
|
12
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-5GRBEMCA.js";
|
|
13
17
|
|
|
14
18
|
// src/drivers/aptos/index.ts
|
|
15
19
|
import { Aptos, AptosConfig, Network, AccountAddress as AccountAddress2 } from "@aptos-labs/ts-sdk";
|
|
@@ -368,6 +372,183 @@ function txNotFound(hash) {
|
|
|
368
372
|
};
|
|
369
373
|
}
|
|
370
374
|
|
|
375
|
+
// src/drivers/aptos/swap.ts
|
|
376
|
+
var HYPERION = "0x8b4a2c4bb53857c718a04c020b98f8c2e1f99a68b0f57389a8bf5434cd22e05c";
|
|
377
|
+
var FEE_TIERS = [0, 1, 2, 3, 4];
|
|
378
|
+
var DEADLINE_SECONDS = 120;
|
|
379
|
+
var MAX_GAS_AMOUNT2 = 8e4;
|
|
380
|
+
var MIN_SQRT_PRICE = 4295048016n;
|
|
381
|
+
var MAX_SQRT_PRICE = 79226673515401279992447579055n;
|
|
382
|
+
function sourceFor(feeRate) {
|
|
383
|
+
const pct = feeRate > 0n ? `${(Number(feeRate) / 1e4).toFixed(4)}%` : "the pool fee";
|
|
384
|
+
return {
|
|
385
|
+
kind: "provider",
|
|
386
|
+
name: "Hyperion",
|
|
387
|
+
note: `Third-party Aptos DEX (Hyperion), called contract-to-contract with no API and no API key: the quote is an on-chain view and the swap is an entry function your own account signs. Cost on this route: ${pct}, which is the pool's own fee. PipRail adds nothing, and the entry function has no fee parameter to add.`
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function sameAddress(a, b) {
|
|
391
|
+
return padAddress(a) === padAddress(b);
|
|
392
|
+
}
|
|
393
|
+
function padAddress(x) {
|
|
394
|
+
return x.replace(/^0x/i, "").padStart(64, "0").toLowerCase();
|
|
395
|
+
}
|
|
396
|
+
function sellingToken0(from, to) {
|
|
397
|
+
return BigInt("0x" + padAddress(from)) < BigInt("0x" + padAddress(to));
|
|
398
|
+
}
|
|
399
|
+
function metadataFor(t) {
|
|
400
|
+
return t.asset === "native" ? APT_FA_METADATA : t.asset;
|
|
401
|
+
}
|
|
402
|
+
function side(t, amount) {
|
|
403
|
+
const decimals = t.asset === "native" ? APT_DECIMALS : t.decimals;
|
|
404
|
+
return {
|
|
405
|
+
asset: t.asset,
|
|
406
|
+
symbol: t.symbol ?? (t.asset === "native" ? APT_SYMBOL : t.asset),
|
|
407
|
+
decimals,
|
|
408
|
+
amount: amount.toString(),
|
|
409
|
+
amountFormatted: formatUnits(amount, decimals)
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function u64(v) {
|
|
413
|
+
try {
|
|
414
|
+
const n = BigInt(String(v));
|
|
415
|
+
return n >= 0n ? n : null;
|
|
416
|
+
} catch {
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async function quoteAptosSwap(p) {
|
|
421
|
+
if (p.wantAmount <= 0n) return null;
|
|
422
|
+
const fromMeta = metadataFor(p.from);
|
|
423
|
+
const toMeta = metadataFor(p.to);
|
|
424
|
+
if (sameAddress(fromMeta, toMeta)) return null;
|
|
425
|
+
const candidates = [];
|
|
426
|
+
for (const feeTier of FEE_TIERS) {
|
|
427
|
+
let pool;
|
|
428
|
+
let feeRate = 0n;
|
|
429
|
+
try {
|
|
430
|
+
const [info] = await p.client.view({
|
|
431
|
+
payload: {
|
|
432
|
+
function: `${HYPERION}::pool_v3::liquidity_pool_info_both_fa`,
|
|
433
|
+
functionArguments: [fromMeta, toMeta, feeTier]
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
pool = String(info?.[4] ?? "");
|
|
437
|
+
const liquidity = u64(info?.[7]) ?? 0n;
|
|
438
|
+
feeRate = u64(info?.[9]) ?? 0n;
|
|
439
|
+
if (!pool || liquidity === 0n) continue;
|
|
440
|
+
} catch {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
const [inRaw] = await p.client.view({
|
|
445
|
+
payload: {
|
|
446
|
+
function: `${HYPERION}::router_v3::get_batch_amount_in`,
|
|
447
|
+
functionArguments: [[pool], p.wantAmount.toString(), fromMeta, toMeta]
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
const amountIn = u64(inRaw);
|
|
451
|
+
if (amountIn === null || amountIn === 0n) continue;
|
|
452
|
+
candidates.push({ feeTier, pool, amountIn, feeRate, fromIsToken0: sellingToken0(fromMeta, toMeta) });
|
|
453
|
+
} catch {
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (!candidates.length) return null;
|
|
458
|
+
const best = candidates.reduce((a, b) => b.amountIn < a.amountIn ? b : a);
|
|
459
|
+
const maxSpend = applySlippage(best.amountIn, p.slippageBps);
|
|
460
|
+
return {
|
|
461
|
+
source: sourceFor(best.feeRate),
|
|
462
|
+
network: p.network,
|
|
463
|
+
from: side(p.from, best.amountIn),
|
|
464
|
+
to: side(p.to, p.wantAmount),
|
|
465
|
+
maxSpend: maxSpend.toString(),
|
|
466
|
+
maxSpendFormatted: formatUnits(maxSpend, p.from.asset === "native" ? APT_DECIMALS : p.from.decimals),
|
|
467
|
+
slippageBps: p.slippageBps,
|
|
468
|
+
route: {
|
|
469
|
+
feeTier: best.feeTier,
|
|
470
|
+
pool: best.pool,
|
|
471
|
+
fromMetadata: fromMeta,
|
|
472
|
+
toMetadata: toMeta,
|
|
473
|
+
recipient: p.owner,
|
|
474
|
+
fromIsToken0: best.fromIsToken0
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
async function swapAptos(p) {
|
|
479
|
+
const route = p.quote.route;
|
|
480
|
+
if (!route?.pool || !route.fromMetadata || !route.toMetadata) {
|
|
481
|
+
throw new Error("Aptos: swap quote is missing its Hyperion routing data \u2014 re-quote before swapping.");
|
|
482
|
+
}
|
|
483
|
+
const amountOut = BigInt(p.quote.to.amount);
|
|
484
|
+
const amountInMax = BigInt(p.quote.maxSpend);
|
|
485
|
+
const deadline = Math.floor(Date.now() / 1e3) + DEADLINE_SECONDS;
|
|
486
|
+
let hash;
|
|
487
|
+
try {
|
|
488
|
+
const transaction = await p.client.build({
|
|
489
|
+
sender: p.sender,
|
|
490
|
+
data: {
|
|
491
|
+
function: `${HYPERION}::router_v3::exact_output_swap_entry`,
|
|
492
|
+
/*
|
|
493
|
+
* 🔴 Argument order: (fee_tier, FROM amount, TO amount, …). Both the exact-input and
|
|
494
|
+
* exact-output entry functions share one signature, and the two amount slots are
|
|
495
|
+
* "what leaves" then "what arrives" — NOT "the exact one" then "the limit". So here
|
|
496
|
+
* p2 is the input CAP and p3 is the exact output, which is the opposite of what the
|
|
497
|
+
* names suggest. Getting it backwards aborts with `fungible_asset::EINSUFFICIENT_BALANCE`,
|
|
498
|
+
* which reads like a funding problem and is not one. Established by simulating every
|
|
499
|
+
* candidate ordering against mainnet rather than by guessing.
|
|
500
|
+
*/
|
|
501
|
+
functionArguments: [
|
|
502
|
+
route.feeTier,
|
|
503
|
+
amountInMax.toString(),
|
|
504
|
+
// ← the on-chain slippage cap; the trade aborts above it
|
|
505
|
+
amountOut.toString(),
|
|
506
|
+
// ← the exact amount we require to arrive
|
|
507
|
+
// Selling token0 pushes the price DOWN, so bound it below; otherwise bound above.
|
|
508
|
+
(route.fromIsToken0 ? MIN_SQRT_PRICE + 1n : MAX_SQRT_PRICE - 1n).toString(),
|
|
509
|
+
route.fromMetadata,
|
|
510
|
+
route.toMetadata,
|
|
511
|
+
/*
|
|
512
|
+
* 🔴 The SIGNER receives, always. `route.recipient` records who quoted, and is not
|
|
513
|
+
* used here: it was captured at quote time, so a quote carried across wallets (or
|
|
514
|
+
* simply held while the client rebound) would have paid the output to whoever asked
|
|
515
|
+
* for the price rather than whoever signed. Every other family already derives this
|
|
516
|
+
* from the signing wallet at swap time; this one did not, and the comment claiming
|
|
517
|
+
* "the funds never leave the wallet" was only true by luck of them matching.
|
|
518
|
+
*/
|
|
519
|
+
p.sender,
|
|
520
|
+
deadline.toString()
|
|
521
|
+
]
|
|
522
|
+
},
|
|
523
|
+
options: { maxGasAmount: MAX_GAS_AMOUNT2 }
|
|
524
|
+
});
|
|
525
|
+
const res = await p.client.signSubmit({ signer: p.signer, transaction });
|
|
526
|
+
hash = res.hash;
|
|
527
|
+
} catch (err) {
|
|
528
|
+
const msg = String(err?.message ?? err);
|
|
529
|
+
if (/EINSUFFICIENT|insufficient|balance/i.test(msg)) {
|
|
530
|
+
throw new InsufficientFundsError(
|
|
531
|
+
`Aptos swap could not be submitted: the account cannot cover it (token balance or APT gas). (${msg.slice(0, 160)})`,
|
|
532
|
+
{ cause: err }
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
throw err;
|
|
536
|
+
}
|
|
537
|
+
const out = await p.client.waitFor({ hash });
|
|
538
|
+
if (out?.success === false) {
|
|
539
|
+
throw new InsufficientFundsError(
|
|
540
|
+
`Aptos swap failed on-chain (tx ${hash}): ${out.vm_status ?? "unknown status"}. Nothing was swapped. The usual cause is the price moving past the input cap \u2014 re-quote and retry.`
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
transaction: hash,
|
|
545
|
+
network: p.quote.network,
|
|
546
|
+
source: p.quote.source,
|
|
547
|
+
from: p.quote.from,
|
|
548
|
+
to: p.quote.to
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
|
|
371
552
|
// src/drivers/aptos/wallet.ts
|
|
372
553
|
import { Account, Ed25519PrivateKey } from "@aptos-labs/ts-sdk";
|
|
373
554
|
function assertAptosWallet(wallet, network) {
|
|
@@ -442,6 +623,22 @@ function makeAptosNetwork(preset, rpcUrl) {
|
|
|
442
623
|
return norm(String(addr));
|
|
443
624
|
}
|
|
444
625
|
};
|
|
626
|
+
const swapClient = {
|
|
627
|
+
view: (input) => aptos.view(input),
|
|
628
|
+
build: (input) => aptos.transaction.build.simple({
|
|
629
|
+
sender: input.sender,
|
|
630
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
631
|
+
data: input.data,
|
|
632
|
+
...input.options ? { options: input.options } : {}
|
|
633
|
+
}),
|
|
634
|
+
signSubmit: (input) => aptos.signAndSubmitTransaction({
|
|
635
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
636
|
+
signer: input.signer,
|
|
637
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
638
|
+
transaction: input.transaction
|
|
639
|
+
}),
|
|
640
|
+
waitFor: async ({ hash }) => await aptos.waitForTransaction({ transactionHash: hash })
|
|
641
|
+
};
|
|
445
642
|
const payClient = {
|
|
446
643
|
build: (input) => aptos.transaction.build.simple({
|
|
447
644
|
sender: input.sender,
|
|
@@ -548,6 +745,11 @@ function makeAptosNetwork(preset, rpcUrl) {
|
|
|
548
745
|
detail: "\u22480.001 APT (a simple Fungible-Asset transfer; Aptos gas is sub-cent)"
|
|
549
746
|
});
|
|
550
747
|
},
|
|
748
|
+
/** The bound wallet's own address — where THIS wallet gets paid. Derived from the key
|
|
749
|
+
* material only: no RPC, nothing moved. See {@link ResolvedNetwork.addressOf}. */
|
|
750
|
+
async addressOf(wallet) {
|
|
751
|
+
return resolveAptosAccount(wallet._native).accountAddress.toString();
|
|
752
|
+
},
|
|
551
753
|
async balanceOf(wallet, asset) {
|
|
552
754
|
let owner;
|
|
553
755
|
try {
|
|
@@ -576,6 +778,20 @@ function makeAptosNetwork(preset, rpcUrl) {
|
|
|
576
778
|
async recipientReady() {
|
|
577
779
|
return { ready: "n/a" };
|
|
578
780
|
},
|
|
781
|
+
/* ---- swap (OPTIONAL, opt-in): via Hyperion, no API, no key, no added fee. See ./swap.ts ---- */
|
|
782
|
+
async quoteSwap({ from, to, wantAmount, slippageBps, wallet }) {
|
|
783
|
+
const owner = resolveAptosAccount(wallet._native).accountAddress.toString();
|
|
784
|
+
return quoteAptosSwap({ client: swapClient, network, from, to, wantAmount, slippageBps, owner });
|
|
785
|
+
},
|
|
786
|
+
async swap(wallet, quote) {
|
|
787
|
+
const account = resolveAptosAccount(wallet._native);
|
|
788
|
+
return swapAptos({
|
|
789
|
+
client: swapClient,
|
|
790
|
+
signer: account,
|
|
791
|
+
sender: account.accountAddress.toString(),
|
|
792
|
+
quote
|
|
793
|
+
});
|
|
794
|
+
},
|
|
579
795
|
async verify(ref, accept) {
|
|
580
796
|
return verifyAptos({ reader, hash: ref, accept });
|
|
581
797
|
},
|
|
@@ -99,49 +99,6 @@ var UnsupportedNetworkError = (_class18 = class extends PipRailError {constructo
|
|
|
99
99
|
__init18() {this.code = "UNSUPPORTED_NETWORK"}
|
|
100
100
|
}, _class18);
|
|
101
101
|
|
|
102
|
-
// src/drivers/shared.ts
|
|
103
|
-
var FAMILY_LABEL = {
|
|
104
|
-
evm: "EVM",
|
|
105
|
-
solana: "Solana",
|
|
106
|
-
ton: "TON",
|
|
107
|
-
stellar: "Stellar",
|
|
108
|
-
xrpl: "XRPL",
|
|
109
|
-
tron: "Tron",
|
|
110
|
-
sui: "Sui",
|
|
111
|
-
near: "NEAR",
|
|
112
|
-
aptos: "Aptos",
|
|
113
|
-
algorand: "Algorand"
|
|
114
|
-
};
|
|
115
|
-
var FAMILY_TOKEN = {
|
|
116
|
-
evm: { key: "address", shape: "{ address }", hint: "{ address, decimals }" },
|
|
117
|
-
solana: { key: "mint", shape: "{ mint }", hint: "{ mint, decimals }" },
|
|
118
|
-
ton: { key: "master", shape: "{ master }", hint: "{ master, decimals }" },
|
|
119
|
-
stellar: { key: "code", shape: "{ issuer, code }", hint: "{ issuer, code, decimals }" },
|
|
120
|
-
xrpl: { key: "currencyHex", shape: "{ issuer, currencyHex }", hint: "{ issuer, currencyHex, decimals }" },
|
|
121
|
-
tron: { key: "address", shape: "{ address }", hint: "{ address, decimals }" },
|
|
122
|
-
sui: { key: "coinType", shape: "{ coinType }", hint: "{ coinType, decimals }" },
|
|
123
|
-
near: { key: "contractId", shape: "{ contractId }", hint: "{ contractId, decimals }" },
|
|
124
|
-
aptos: { key: "metadata", shape: "{ metadata }", hint: "{ metadata, decimals }" },
|
|
125
|
-
algorand: { key: "assetId", shape: "{ assetId }", hint: "{ assetId, decimals }" }
|
|
126
|
-
};
|
|
127
|
-
function rejectForeignToken(token, family, network) {
|
|
128
|
-
const own = FAMILY_TOKEN[family];
|
|
129
|
-
if (typeof token !== "object" || token === null) {
|
|
130
|
-
throw new InvalidConfigError(
|
|
131
|
-
`token must be the string 'native', a built-in symbol, or an object (${own.shape} \u2014 pass ${own.hint}); got ${token === null ? "null" : typeof token}.`
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
for (const fam of Object.keys(FAMILY_TOKEN)) {
|
|
135
|
-
if (fam === family) continue;
|
|
136
|
-
if (FAMILY_TOKEN[fam].key === own.key) continue;
|
|
137
|
-
if (FAMILY_TOKEN[fam].key in token) {
|
|
138
|
-
throw new WrongFamilyError(
|
|
139
|
-
`chain ${network} is ${FAMILY_LABEL[family]}; a ${FAMILY_LABEL[fam]} ${FAMILY_TOKEN[fam].shape} token can't be used \u2014 pass ${own.hint}.`
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
102
|
// src/util/units.ts
|
|
146
103
|
var MAX_DECIMALS = 100;
|
|
147
104
|
function assertValidDecimals(decimals, fn) {
|
|
@@ -205,6 +162,49 @@ function formatUnits(value, decimals) {
|
|
|
205
162
|
return `${negative ? "-" : ""}${whole}${frac ? `.${frac}` : ""}`;
|
|
206
163
|
}
|
|
207
164
|
|
|
165
|
+
// src/drivers/shared.ts
|
|
166
|
+
var FAMILY_LABEL = {
|
|
167
|
+
evm: "EVM",
|
|
168
|
+
solana: "Solana",
|
|
169
|
+
ton: "TON",
|
|
170
|
+
stellar: "Stellar",
|
|
171
|
+
xrpl: "XRPL",
|
|
172
|
+
tron: "Tron",
|
|
173
|
+
sui: "Sui",
|
|
174
|
+
near: "NEAR",
|
|
175
|
+
aptos: "Aptos",
|
|
176
|
+
algorand: "Algorand"
|
|
177
|
+
};
|
|
178
|
+
var FAMILY_TOKEN = {
|
|
179
|
+
evm: { key: "address", shape: "{ address }", hint: "{ address, decimals }" },
|
|
180
|
+
solana: { key: "mint", shape: "{ mint }", hint: "{ mint, decimals }" },
|
|
181
|
+
ton: { key: "master", shape: "{ master }", hint: "{ master, decimals }" },
|
|
182
|
+
stellar: { key: "code", shape: "{ issuer, code }", hint: "{ issuer, code, decimals }" },
|
|
183
|
+
xrpl: { key: "currencyHex", shape: "{ issuer, currencyHex }", hint: "{ issuer, currencyHex, decimals }" },
|
|
184
|
+
tron: { key: "address", shape: "{ address }", hint: "{ address, decimals }" },
|
|
185
|
+
sui: { key: "coinType", shape: "{ coinType }", hint: "{ coinType, decimals }" },
|
|
186
|
+
near: { key: "contractId", shape: "{ contractId }", hint: "{ contractId, decimals }" },
|
|
187
|
+
aptos: { key: "metadata", shape: "{ metadata }", hint: "{ metadata, decimals }" },
|
|
188
|
+
algorand: { key: "assetId", shape: "{ assetId }", hint: "{ assetId, decimals }" }
|
|
189
|
+
};
|
|
190
|
+
function rejectForeignToken(token, family, network) {
|
|
191
|
+
const own = FAMILY_TOKEN[family];
|
|
192
|
+
if (typeof token !== "object" || token === null) {
|
|
193
|
+
throw new InvalidConfigError(
|
|
194
|
+
`token must be the string 'native', a built-in symbol, or an object (${own.shape} \u2014 pass ${own.hint}); got ${token === null ? "null" : typeof token}.`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
for (const fam of Object.keys(FAMILY_TOKEN)) {
|
|
198
|
+
if (fam === family) continue;
|
|
199
|
+
if (FAMILY_TOKEN[fam].key === own.key) continue;
|
|
200
|
+
if (FAMILY_TOKEN[fam].key in token) {
|
|
201
|
+
throw new WrongFamilyError(
|
|
202
|
+
`chain ${network} is ${FAMILY_LABEL[family]}; a ${FAMILY_LABEL[fam]} ${FAMILY_TOKEN[fam].shape} token can't be used \u2014 pass ${own.hint}.`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
208
|
// src/util/cost.ts
|
|
209
209
|
function nativeCost(opts) {
|
|
210
210
|
return {
|
|
@@ -257,4 +257,4 @@ function assertNoLegacyWalletKey(wallet, family) {
|
|
|
257
257
|
|
|
258
258
|
|
|
259
259
|
|
|
260
|
-
exports.PipRailError = PipRailError; exports.InsufficientFundsError = InsufficientFundsError; exports.RecipientNotReadyError = RecipientNotReadyError; exports.toInsufficientFundsError = toInsufficientFundsError; exports.WrongChainError = WrongChainError; exports.PaymentTimeoutError = PaymentTimeoutError; exports.MaxRetriesExceededError = MaxRetriesExceededError; exports.PaymentDeclinedError = PaymentDeclinedError; exports.ConfirmationTimeoutError = ConfirmationTimeoutError; exports.SettlementError = SettlementError; exports.InvalidEnvelopeError = InvalidEnvelopeError; exports.InvalidConfigError = InvalidConfigError; exports.NoCompatibleAcceptError = NoCompatibleAcceptError; exports.UnsupportedSchemeError = UnsupportedSchemeError; exports.NonReplayableBodyError = NonReplayableBodyError; exports.WalletRequiredError = WalletRequiredError; exports.WrongFamilyError = WrongFamilyError; exports.UnknownTokenError = UnknownTokenError; exports.MissingDriverError = MissingDriverError; exports.UnsupportedNetworkError = UnsupportedNetworkError; exports.assertNoLegacyWalletKey = assertNoLegacyWalletKey; exports.
|
|
260
|
+
exports.PipRailError = PipRailError; exports.InsufficientFundsError = InsufficientFundsError; exports.RecipientNotReadyError = RecipientNotReadyError; exports.toInsufficientFundsError = toInsufficientFundsError; exports.WrongChainError = WrongChainError; exports.PaymentTimeoutError = PaymentTimeoutError; exports.MaxRetriesExceededError = MaxRetriesExceededError; exports.PaymentDeclinedError = PaymentDeclinedError; exports.ConfirmationTimeoutError = ConfirmationTimeoutError; exports.SettlementError = SettlementError; exports.InvalidEnvelopeError = InvalidEnvelopeError; exports.InvalidConfigError = InvalidConfigError; exports.NoCompatibleAcceptError = NoCompatibleAcceptError; exports.UnsupportedSchemeError = UnsupportedSchemeError; exports.NonReplayableBodyError = NonReplayableBodyError; exports.WalletRequiredError = WalletRequiredError; exports.WrongFamilyError = WrongFamilyError; exports.UnknownTokenError = UnknownTokenError; exports.MissingDriverError = MissingDriverError; exports.UnsupportedNetworkError = UnsupportedNetworkError; exports.assertNoLegacyWalletKey = assertNoLegacyWalletKey; exports.MAX_DECIMALS = MAX_DECIMALS; exports.parseUnits = parseUnits; exports.floorUnits = floorUnits; exports.formatUnits = formatUnits; exports.rejectForeignToken = rejectForeignToken; exports.nativeCost = nativeCost;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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
|
|
3
|
+
var _chunkMZAJQYM3cjs = require('./chunk-MZAJQYM3.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunk6XTNI2OQcjs = require('./chunk-6XTNI2OQ.cjs');
|
|
7
7
|
|
|
8
8
|
// src/x402.ts
|
|
9
9
|
var DEFAULT_EXACT_TRANSFER_METHOD = "eip3009";
|
|
@@ -84,7 +84,7 @@ function toBase64Json(value) {
|
|
|
84
84
|
try {
|
|
85
85
|
json = JSON.stringify(value);
|
|
86
86
|
} catch (cause) {
|
|
87
|
-
throw new (0,
|
|
87
|
+
throw new (0, _chunk6XTNI2OQcjs.InvalidConfigError)(
|
|
88
88
|
`x402: this payload cannot be serialised to JSON (${cause.message}). Amounts must be decimal STRINGS, not BigInt \u2014 pass '50000', not 50000n.`,
|
|
89
89
|
{ cause }
|
|
90
90
|
);
|
|
@@ -398,7 +398,7 @@ function normalizeV1Challenge(body) {
|
|
|
398
398
|
out.amount = a.maxAmountRequired;
|
|
399
399
|
}
|
|
400
400
|
if (typeof a.network === "string") {
|
|
401
|
-
const canonical =
|
|
401
|
+
const canonical = _chunkMZAJQYM3cjs.normalizeNetwork.call(void 0, a.network);
|
|
402
402
|
if (canonical !== a.network) {
|
|
403
403
|
out.network = canonical;
|
|
404
404
|
out.wireNetwork = a.network;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/swap.ts
|
|
2
|
+
var DEFAULT_AGENT_MODE = "budgeted";
|
|
3
|
+
var AGENT_MODES = ["supervised", "budgeted", "sovereign"];
|
|
4
|
+
var DEFAULT_SLIPPAGE_BPS = 50;
|
|
5
|
+
var MAX_SLIPPAGE_BPS = 1e3;
|
|
6
|
+
function resolveSlippageBps(bps) {
|
|
7
|
+
if (bps === void 0) return DEFAULT_SLIPPAGE_BPS;
|
|
8
|
+
if (!Number.isInteger(bps) || bps < 0 || bps > MAX_SLIPPAGE_BPS) {
|
|
9
|
+
throw new RangeError(
|
|
10
|
+
`slippageBps must be an integer between 0 and ${MAX_SLIPPAGE_BPS} (got ${bps}).`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return bps;
|
|
14
|
+
}
|
|
15
|
+
function applySlippage(amount, bps) {
|
|
16
|
+
return (amount * BigInt(1e4 + bps) + 9999n) / 10000n;
|
|
17
|
+
}
|
|
18
|
+
function summarizeSwap(q) {
|
|
19
|
+
return `Swap ~${q.from.amountFormatted} ${q.from.symbol} \u2192 ${q.to.amountFormatted} ${q.to.symbol} (at most ${q.maxSpendFormatted} ${q.from.symbol}, ${q.slippageBps / 100}% slippage). Rate from ${q.source.name}.`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
DEFAULT_AGENT_MODE,
|
|
24
|
+
AGENT_MODES,
|
|
25
|
+
DEFAULT_SLIPPAGE_BPS,
|
|
26
|
+
MAX_SLIPPAGE_BPS,
|
|
27
|
+
resolveSlippageBps,
|
|
28
|
+
applySlippage,
|
|
29
|
+
summarizeSwap
|
|
30
|
+
};
|
|
@@ -72,6 +72,7 @@ var SLUG_TO_CAIP2 = {
|
|
|
72
72
|
hyperevm: "eip155:999",
|
|
73
73
|
monad: "eip155:143",
|
|
74
74
|
kaia: "eip155:8217",
|
|
75
|
+
robinhood: "eip155:4663",
|
|
75
76
|
// non-EVM families — values mirror each driver's bound caip2 exactly
|
|
76
77
|
solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
77
78
|
ton: "tvm:-239",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/swap.ts
|
|
2
|
+
var DEFAULT_AGENT_MODE = "budgeted";
|
|
3
|
+
var AGENT_MODES = ["supervised", "budgeted", "sovereign"];
|
|
4
|
+
var DEFAULT_SLIPPAGE_BPS = 50;
|
|
5
|
+
var MAX_SLIPPAGE_BPS = 1e3;
|
|
6
|
+
function resolveSlippageBps(bps) {
|
|
7
|
+
if (bps === void 0) return DEFAULT_SLIPPAGE_BPS;
|
|
8
|
+
if (!Number.isInteger(bps) || bps < 0 || bps > MAX_SLIPPAGE_BPS) {
|
|
9
|
+
throw new RangeError(
|
|
10
|
+
`slippageBps must be an integer between 0 and ${MAX_SLIPPAGE_BPS} (got ${bps}).`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
return bps;
|
|
14
|
+
}
|
|
15
|
+
function applySlippage(amount, bps) {
|
|
16
|
+
return (amount * BigInt(1e4 + bps) + 9999n) / 10000n;
|
|
17
|
+
}
|
|
18
|
+
function summarizeSwap(q) {
|
|
19
|
+
return `Swap ~${q.from.amountFormatted} ${q.from.symbol} \u2192 ${q.to.amountFormatted} ${q.to.symbol} (at most ${q.maxSpendFormatted} ${q.from.symbol}, ${q.slippageBps / 100}% slippage). Rate from ${q.source.name}.`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
exports.DEFAULT_AGENT_MODE = DEFAULT_AGENT_MODE; exports.AGENT_MODES = AGENT_MODES; exports.DEFAULT_SLIPPAGE_BPS = DEFAULT_SLIPPAGE_BPS; exports.MAX_SLIPPAGE_BPS = MAX_SLIPPAGE_BPS; exports.resolveSlippageBps = resolveSlippageBps; exports.applySlippage = applySlippage; exports.summarizeSwap = summarizeSwap;
|
|
@@ -72,6 +72,7 @@ var SLUG_TO_CAIP2 = {
|
|
|
72
72
|
hyperevm: "eip155:999",
|
|
73
73
|
monad: "eip155:143",
|
|
74
74
|
kaia: "eip155:8217",
|
|
75
|
+
robinhood: "eip155:4663",
|
|
75
76
|
// non-EVM families — values mirror each driver's bound caip2 exactly
|
|
76
77
|
solana: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
|
|
77
78
|
ton: "tvm:-239",
|