@t2000/sdk 9.2.0 → 9.3.1
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/browser.cjs +126 -8
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +126 -9
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +128 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +128 -9
- package/dist/index.js.map +1 -1
- package/dist/{send-CUUOLK_H.d.cts → send-DEK6aOGe.d.cts} +14 -1
- package/dist/{send-CUUOLK_H.d.ts → send-DEK6aOGe.d.ts} +14 -1
- package/package.json +3 -2
package/dist/browser.cjs
CHANGED
|
@@ -447,6 +447,13 @@ var ZkLoginSigner = class {
|
|
|
447
447
|
// src/wallet/pay.ts
|
|
448
448
|
init_errors();
|
|
449
449
|
|
|
450
|
+
// src/mpp-cost.ts
|
|
451
|
+
function parseChallengeAmount(challenge) {
|
|
452
|
+
const raw = challenge?.request?.amount;
|
|
453
|
+
const n = typeof raw === "string" ? Number(raw) : typeof raw === "number" ? raw : Number.NaN;
|
|
454
|
+
return Number.isFinite(n) ? n : void 0;
|
|
455
|
+
}
|
|
456
|
+
|
|
450
457
|
// src/wallet/executeTx.ts
|
|
451
458
|
async function executeTx(client, signer, buildTx, options = {}) {
|
|
452
459
|
const tx = await buildTx();
|
|
@@ -459,7 +466,11 @@ async function executeTx(client, signer, buildTx, options = {}) {
|
|
|
459
466
|
include: { effects: true }
|
|
460
467
|
});
|
|
461
468
|
const txn = result.$kind === "Transaction" ? result.Transaction : result.FailedTransaction;
|
|
462
|
-
|
|
469
|
+
try {
|
|
470
|
+
await client.core.waitForTransaction({ digest: txn.digest });
|
|
471
|
+
} catch (err) {
|
|
472
|
+
if (!txn.effects) throw err;
|
|
473
|
+
}
|
|
463
474
|
const effects = txn.effects ?? void 0;
|
|
464
475
|
const gasUsed = effects?.gasUsed;
|
|
465
476
|
let gasCostSui = 0;
|
|
@@ -520,11 +531,18 @@ function preflightPay(input) {
|
|
|
520
531
|
return PREFLIGHT_OK;
|
|
521
532
|
}
|
|
522
533
|
async function payWithMpp(args) {
|
|
523
|
-
const { signer, client
|
|
534
|
+
const { signer, client } = args;
|
|
535
|
+
let options = args.options;
|
|
524
536
|
const pf = preflightPay({ url: options.url, maxPrice: options.maxPrice });
|
|
525
537
|
if (!pf.valid) throw new exports.T2000Error(pf.code, pf.error);
|
|
526
538
|
const method = (options.method ?? "GET").toUpperCase();
|
|
527
539
|
const canHaveBody = method !== "GET" && method !== "HEAD";
|
|
540
|
+
if (canHaveBody && typeof options.body === "string" && isJsonText(options.body) && !hasContentType(options.headers)) {
|
|
541
|
+
options = {
|
|
542
|
+
...options,
|
|
543
|
+
headers: { ...options.headers ?? {}, "content-type": "application/json" }
|
|
544
|
+
};
|
|
545
|
+
}
|
|
528
546
|
const reqInit = {
|
|
529
547
|
method,
|
|
530
548
|
headers: options.headers,
|
|
@@ -535,13 +553,35 @@ async function payWithMpp(args) {
|
|
|
535
553
|
return finalize(probe, { paid: false });
|
|
536
554
|
}
|
|
537
555
|
const requirements = await pickSuiExactRequirements(probe, client.network);
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
556
|
+
if (requirements) {
|
|
557
|
+
return payViaX402({ signer, client, options, reqInit, requirements });
|
|
558
|
+
}
|
|
559
|
+
const headerChallenge = await parseMppSuiChallenge(probe);
|
|
560
|
+
if (headerChallenge) {
|
|
561
|
+
return payViaMppHeader({ signer, client, options });
|
|
562
|
+
}
|
|
563
|
+
throw new exports.T2000Error(
|
|
564
|
+
"FACILITATOR_REJECTION",
|
|
565
|
+
`Endpoint returned 402 without an x402 'exact' / sui:${client.network} requirement in the body or an MPP 'sui' challenge in WWW-Authenticate. Nothing this SDK can pay.`
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
async function parseMppSuiChallenge(response) {
|
|
569
|
+
try {
|
|
570
|
+
const { Challenge } = await import('mppx');
|
|
571
|
+
const challenges = Challenge.fromResponseList(response);
|
|
572
|
+
const suiChallenge = challenges.find((c) => c.method === "sui" && c.intent === "charge");
|
|
573
|
+
if (!suiChallenge) return void 0;
|
|
574
|
+
const req = suiChallenge.request;
|
|
575
|
+
if (typeof req?.amount !== "string" || typeof req?.recipient !== "string") return void 0;
|
|
576
|
+
return {
|
|
577
|
+
amount: req.amount,
|
|
578
|
+
currency: typeof req.currency === "string" ? req.currency : "",
|
|
579
|
+
recipient: req.recipient,
|
|
580
|
+
description: suiChallenge.description
|
|
581
|
+
};
|
|
582
|
+
} catch {
|
|
583
|
+
return void 0;
|
|
543
584
|
}
|
|
544
|
-
return payViaX402({ signer, client, options, reqInit, requirements });
|
|
545
585
|
}
|
|
546
586
|
async function pickSuiExactRequirements(response, network) {
|
|
547
587
|
try {
|
|
@@ -556,6 +596,7 @@ async function payViaX402(args) {
|
|
|
556
596
|
const { signer, client, options, reqInit, requirements } = args;
|
|
557
597
|
const { buildX402SignedPayment, X402_PAYMENT_HEADER, X402_PAYMENT_RESPONSE_HEADER } = await import('@suimpp/mpp/x402');
|
|
558
598
|
const amountRaw = BigInt(requirements.maxAmountRequired);
|
|
599
|
+
assertWithinMaxPrice(atomicToHuman(amountRaw, await assetDecimals(requirements.asset)), options.maxPrice);
|
|
559
600
|
const migrationGasSui = await ensureAddressBalanceCovers({
|
|
560
601
|
signer,
|
|
561
602
|
client,
|
|
@@ -591,6 +632,70 @@ async function payViaX402(args) {
|
|
|
591
632
|
receipt: digest ? { reference: digest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : result.receipt
|
|
592
633
|
};
|
|
593
634
|
}
|
|
635
|
+
async function payViaMppHeader(args) {
|
|
636
|
+
const { signer, client, options } = args;
|
|
637
|
+
const { Mppx } = await import('mppx/client');
|
|
638
|
+
const { sui, USDC, USDC_TESTNET } = await import('@suimpp/mpp/client');
|
|
639
|
+
const signerAddress = signer.getAddress();
|
|
640
|
+
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
641
|
+
const grpcClient = await makeGrpcBuildClient(client);
|
|
642
|
+
let paymentDigest;
|
|
643
|
+
let gasCostSui = 0;
|
|
644
|
+
let chargedAmount;
|
|
645
|
+
const mppx = Mppx.create({
|
|
646
|
+
polyfill: false,
|
|
647
|
+
onChallenge: async (challenge) => {
|
|
648
|
+
const parsed = parseChallengeAmount(challenge);
|
|
649
|
+
if (parsed !== void 0) {
|
|
650
|
+
chargedAmount = parsed;
|
|
651
|
+
assertWithinMaxPrice(parsed, options.maxPrice);
|
|
652
|
+
}
|
|
653
|
+
return void 0;
|
|
654
|
+
},
|
|
655
|
+
methods: [
|
|
656
|
+
sui({
|
|
657
|
+
client,
|
|
658
|
+
currency: network === "testnet" ? USDC_TESTNET : USDC,
|
|
659
|
+
signer: {
|
|
660
|
+
toSuiAddress: () => signerAddress,
|
|
661
|
+
signPersonalMessage: (bytes) => signer.signPersonalMessage(bytes)
|
|
662
|
+
},
|
|
663
|
+
execute: async (tx) => {
|
|
664
|
+
const result2 = await executeTx(client, signer, () => tx, { buildClient: grpcClient });
|
|
665
|
+
paymentDigest = result2.digest;
|
|
666
|
+
gasCostSui = result2.gasCostSui;
|
|
667
|
+
return { digest: result2.digest };
|
|
668
|
+
}
|
|
669
|
+
})
|
|
670
|
+
]
|
|
671
|
+
});
|
|
672
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
673
|
+
const canHaveBody = method !== "GET" && method !== "HEAD";
|
|
674
|
+
const response = await mppx.fetch(options.url, {
|
|
675
|
+
method,
|
|
676
|
+
headers: options.headers,
|
|
677
|
+
body: canHaveBody ? options.body : void 0
|
|
678
|
+
});
|
|
679
|
+
const paid = !!paymentDigest;
|
|
680
|
+
const result = await finalize(response, { paid });
|
|
681
|
+
if (!paid) return { ...result, dialect: "legacy" };
|
|
682
|
+
return {
|
|
683
|
+
...result,
|
|
684
|
+
dialect: "legacy",
|
|
685
|
+
cost: chargedAmount ?? options.maxPrice ?? void 0,
|
|
686
|
+
gasCostSui,
|
|
687
|
+
receipt: paymentDigest ? { reference: paymentDigest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : void 0
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function assertWithinMaxPrice(price, maxPrice) {
|
|
691
|
+
if (maxPrice !== void 0 && price > maxPrice) {
|
|
692
|
+
throw new exports.T2000Error(
|
|
693
|
+
"PRICE_EXCEEDS_LIMIT",
|
|
694
|
+
`Service price $${price} exceeds maxPrice ceiling $${maxPrice}`,
|
|
695
|
+
{ price, maxPrice }
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
594
699
|
async function ensureAddressBalanceCovers(args) {
|
|
595
700
|
const { signer, client, asset, amountRaw } = args;
|
|
596
701
|
const owner = signer.getAddress();
|
|
@@ -624,6 +729,18 @@ async function ensureAddressBalanceCovers(args) {
|
|
|
624
729
|
const migration = await executeTx(client, signer, () => tx, { buildClient: grpcClient });
|
|
625
730
|
return migration.gasCostSui;
|
|
626
731
|
}
|
|
732
|
+
function isJsonText(text) {
|
|
733
|
+
try {
|
|
734
|
+
JSON.parse(text);
|
|
735
|
+
return true;
|
|
736
|
+
} catch {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
function hasContentType(headers) {
|
|
741
|
+
if (!headers) return false;
|
|
742
|
+
return Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
|
|
743
|
+
}
|
|
627
744
|
async function finalize(response, opts) {
|
|
628
745
|
const contentType = response.headers.get("content-type") ?? "";
|
|
629
746
|
let body;
|
|
@@ -1211,6 +1328,7 @@ exports.getDecimalsForCoinType = getDecimalsForCoinType;
|
|
|
1211
1328
|
exports.mapMoveAbortCode = mapMoveAbortCode;
|
|
1212
1329
|
exports.mapWalletError = mapWalletError;
|
|
1213
1330
|
exports.mistToSui = mistToSui;
|
|
1331
|
+
exports.parseMppSuiChallenge = parseMppSuiChallenge;
|
|
1214
1332
|
exports.parseSuiRpcTx = parseSuiRpcTx;
|
|
1215
1333
|
exports.payWithMpp = payWithMpp;
|
|
1216
1334
|
exports.preflightFail = preflightFail;
|