@payai/x402-evm 2.3.6 → 2.4.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/cjs/exact/client/index.d.ts +3 -2
- package/dist/cjs/exact/client/index.js +173 -194
- package/dist/cjs/exact/client/index.js.map +1 -1
- package/dist/cjs/exact/facilitator/index.js +220 -187
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +14 -21
- package/dist/cjs/exact/server/index.js +109 -69
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/exact/v1/client/index.js +3 -1
- package/dist/cjs/exact/v1/client/index.js.map +1 -1
- package/dist/cjs/exact/v1/facilitator/index.js +3 -1
- package/dist/cjs/exact/v1/facilitator/index.js.map +1 -1
- package/dist/cjs/index.d.ts +38 -2
- package/dist/cjs/index.js +441 -191
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{permit2-U9Zolx3O.d.ts → permit2-CyZxwngN.d.ts} +278 -87
- package/dist/cjs/scheme-CXDF0D2A.d.ts +47 -0
- package/dist/cjs/upto/client/index.d.ts +32 -0
- package/dist/cjs/upto/client/index.js +507 -0
- package/dist/cjs/upto/client/index.js.map +1 -0
- package/dist/cjs/upto/facilitator/index.d.ts +52 -0
- package/dist/cjs/upto/facilitator/index.js +1233 -0
- package/dist/cjs/upto/facilitator/index.js.map +1 -0
- package/dist/cjs/upto/server/index.d.ts +69 -0
- package/dist/cjs/upto/server/index.js +239 -0
- package/dist/cjs/upto/server/index.js.map +1 -0
- package/dist/cjs/v1/index.d.ts +2 -0
- package/dist/cjs/v1/index.js +3 -1
- package/dist/cjs/v1/index.js.map +1 -1
- package/dist/esm/chunk-C4ZQMS77.mjs +629 -0
- package/dist/esm/chunk-C4ZQMS77.mjs.map +1 -0
- package/dist/esm/chunk-CRT6YNY5.mjs +529 -0
- package/dist/esm/chunk-CRT6YNY5.mjs.map +1 -0
- package/dist/esm/{chunk-PCJKIY5G.mjs → chunk-ERK2ZPOY.mjs} +49 -501
- package/dist/esm/chunk-ERK2ZPOY.mjs.map +1 -0
- package/dist/esm/chunk-F3OOHBAW.mjs +89 -0
- package/dist/esm/chunk-F3OOHBAW.mjs.map +1 -0
- package/dist/esm/chunk-FQJR4RCF.mjs +158 -0
- package/dist/esm/chunk-FQJR4RCF.mjs.map +1 -0
- package/dist/esm/chunk-GJ57SZGI.mjs +121 -0
- package/dist/esm/chunk-GJ57SZGI.mjs.map +1 -0
- package/dist/esm/chunk-JII456TS.mjs +34 -0
- package/dist/esm/chunk-JII456TS.mjs.map +1 -0
- package/dist/esm/chunk-WKBC5YMI.mjs +291 -0
- package/dist/esm/chunk-WKBC5YMI.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +3 -2
- package/dist/esm/exact/client/index.mjs +8 -5
- package/dist/esm/exact/facilitator/index.mjs +87 -432
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +14 -21
- package/dist/esm/exact/server/index.mjs +26 -69
- package/dist/esm/exact/server/index.mjs.map +1 -1
- package/dist/esm/exact/v1/client/index.mjs +2 -1
- package/dist/esm/exact/v1/facilitator/index.mjs +2 -1
- package/dist/esm/index.d.mts +38 -2
- package/dist/esm/index.mjs +21 -8
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/{permit2-Bbh3a8_h.d.mts → permit2-CyZxwngN.d.mts} +278 -87
- package/dist/esm/scheme-DCR7hsa3.d.mts +47 -0
- package/dist/esm/upto/client/index.d.mts +32 -0
- package/dist/esm/upto/client/index.mjs +18 -0
- package/dist/esm/upto/client/index.mjs.map +1 -0
- package/dist/esm/upto/facilitator/index.d.mts +52 -0
- package/dist/esm/upto/facilitator/index.mjs +473 -0
- package/dist/esm/upto/facilitator/index.mjs.map +1 -0
- package/dist/esm/upto/server/index.d.mts +69 -0
- package/dist/esm/upto/server/index.mjs +129 -0
- package/dist/esm/upto/server/index.mjs.map +1 -0
- package/dist/esm/v1/index.d.mts +2 -0
- package/dist/esm/v1/index.mjs +2 -1
- package/package.json +31 -1
- package/dist/esm/chunk-GD4MKCN7.mjs +0 -57
- package/dist/esm/chunk-GD4MKCN7.mjs.map +0 -1
- package/dist/esm/chunk-LWO35IGS.mjs +0 -518
- package/dist/esm/chunk-LWO35IGS.mjs.map +0 -1
- package/dist/esm/chunk-PCJKIY5G.mjs.map +0 -1
- package/dist/esm/chunk-TKN5V2BV.mjs +0 -13
- package/dist/esm/chunk-TKN5V2BV.mjs.map +0 -1
|
@@ -150,8 +150,6 @@ var erc20AllowanceAbi = [
|
|
|
150
150
|
stateMutability: "view"
|
|
151
151
|
}
|
|
152
152
|
];
|
|
153
|
-
var ERC20_APPROVE_GAS_LIMIT = 70000n;
|
|
154
|
-
var DEFAULT_MAX_FEE_PER_GAS = 1000000000n;
|
|
155
153
|
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
156
154
|
var x402ExactPermit2ProxyAddress = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
157
155
|
var permit2WitnessABIComponents = [
|
|
@@ -319,7 +317,6 @@ var ErrPermit2InvalidOwner = "permit2_invalid_owner";
|
|
|
319
317
|
var ErrPermit2PaymentTooEarly = "permit2_payment_too_early";
|
|
320
318
|
var ErrPermit2InvalidNonce = "permit2_invalid_nonce";
|
|
321
319
|
var ErrPermit2612AmountMismatch = "permit2_2612_amount_mismatch";
|
|
322
|
-
var ErrErc20ApprovalInsufficientEthForGas = "erc20_approval_insufficient_eth_for_gas";
|
|
323
320
|
var ErrErc20ApprovalInvalidFormat = "invalid_erc20_approval_extension_format";
|
|
324
321
|
var ErrErc20ApprovalFromMismatch = "erc20_approval_from_mismatch";
|
|
325
322
|
var ErrErc20ApprovalAssetMismatch = "erc20_approval_asset_mismatch";
|
|
@@ -346,15 +343,6 @@ var import_viem3 = require("viem");
|
|
|
346
343
|
// src/multicall.ts
|
|
347
344
|
var import_viem2 = require("viem");
|
|
348
345
|
var MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
349
|
-
var multicall3GetEthBalanceAbi = [
|
|
350
|
-
{
|
|
351
|
-
name: "getEthBalance",
|
|
352
|
-
inputs: [{ name: "addr", type: "address" }],
|
|
353
|
-
outputs: [{ name: "balance", type: "uint256" }],
|
|
354
|
-
stateMutability: "view",
|
|
355
|
-
type: "function"
|
|
356
|
-
}
|
|
357
|
-
];
|
|
358
346
|
var multicall3ABI = [
|
|
359
347
|
{
|
|
360
348
|
inputs: [
|
|
@@ -547,6 +535,25 @@ async function diagnoseEip3009SimulationFailure(signer, erc20Address, payload, r
|
|
|
547
535
|
}
|
|
548
536
|
return { isValid: false, invalidReason: ErrEip3009SimulationFailed, payer };
|
|
549
537
|
}
|
|
538
|
+
function parseEip3009TransferError(error) {
|
|
539
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
540
|
+
if (/authorization.*(expired|valid before)/i.test(msg) || /AuthorizationExpired/i.test(msg)) {
|
|
541
|
+
return ErrValidBeforeExpired;
|
|
542
|
+
}
|
|
543
|
+
if (/authorization.*not.*valid|AuthorizationNotYetValid/i.test(msg)) {
|
|
544
|
+
return ErrValidAfterInFuture;
|
|
545
|
+
}
|
|
546
|
+
if (/authorization.*used|AuthorizationAlreadyUsed|AuthorizationUsedOrCanceled/i.test(msg)) {
|
|
547
|
+
return ErrEip3009NonceAlreadyUsed;
|
|
548
|
+
}
|
|
549
|
+
if (/transfer.*exceeds.*balance|insufficient.*balance|ERC20InsufficientBalance/i.test(msg)) {
|
|
550
|
+
return ErrEip3009InsufficientBalance;
|
|
551
|
+
}
|
|
552
|
+
if (/invalid.*signature|SignerMismatch|InvalidSignatureV|InvalidSignatureS/i.test(msg)) {
|
|
553
|
+
return ErrInvalidSignature;
|
|
554
|
+
}
|
|
555
|
+
return ErrTransactionFailed;
|
|
556
|
+
}
|
|
550
557
|
async function executeTransferWithAuthorization(signer, erc20Address, payload) {
|
|
551
558
|
const { signature } = (0, import_viem3.parseErc6492Signature)(payload.signature);
|
|
552
559
|
const signatureLength = signature.startsWith("0x") ? signature.length - 2 : signature.length;
|
|
@@ -767,10 +774,10 @@ async function settleEIP3009(signer, payload, requirements, eip3009Payload, conf
|
|
|
767
774
|
network: payload.accepted.network,
|
|
768
775
|
payer
|
|
769
776
|
};
|
|
770
|
-
} catch {
|
|
777
|
+
} catch (error) {
|
|
771
778
|
return {
|
|
772
779
|
success: false,
|
|
773
|
-
errorReason:
|
|
780
|
+
errorReason: parseEip3009TransferError(error),
|
|
774
781
|
transaction: "",
|
|
775
782
|
network: payload.accepted.network,
|
|
776
783
|
payer
|
|
@@ -826,7 +833,7 @@ function resolveErc20ApprovalExtensionSigner(extension, network) {
|
|
|
826
833
|
// src/exact/facilitator/permit2.ts
|
|
827
834
|
var import_viem7 = require("viem");
|
|
828
835
|
|
|
829
|
-
// src/
|
|
836
|
+
// src/shared/erc20approval.ts
|
|
830
837
|
var import_viem5 = require("viem");
|
|
831
838
|
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
832
839
|
async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
@@ -924,64 +931,106 @@ async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
|
924
931
|
return { isValid: true };
|
|
925
932
|
}
|
|
926
933
|
|
|
927
|
-
// src/
|
|
934
|
+
// src/shared/permit2.ts
|
|
928
935
|
var import_viem6 = require("viem");
|
|
929
|
-
|
|
936
|
+
|
|
937
|
+
// src/upto/facilitator/errors.ts
|
|
938
|
+
var ErrUptoAmountExceedsPermitted = "upto_amount_exceeds_permitted";
|
|
939
|
+
var ErrUptoUnauthorizedFacilitator = "upto_unauthorized_facilitator";
|
|
940
|
+
|
|
941
|
+
// src/shared/permit2.ts
|
|
942
|
+
async function waitAndReturnSettleResponse(signer, tx, payload, payer) {
|
|
943
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
944
|
+
if (receipt.status !== "success") {
|
|
945
|
+
return {
|
|
946
|
+
success: false,
|
|
947
|
+
errorReason: ErrInvalidTransactionState,
|
|
948
|
+
transaction: tx,
|
|
949
|
+
network: payload.accepted.network,
|
|
950
|
+
payer
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
return {
|
|
954
|
+
success: true,
|
|
955
|
+
transaction: tx,
|
|
956
|
+
network: payload.accepted.network,
|
|
957
|
+
payer
|
|
958
|
+
};
|
|
959
|
+
}
|
|
960
|
+
function mapSettleError(error, payload, payer) {
|
|
961
|
+
let errorReason = ErrTransactionFailed;
|
|
962
|
+
if (error instanceof Error) {
|
|
963
|
+
const message = error.message;
|
|
964
|
+
if (message.includes("Permit2612AmountMismatch")) {
|
|
965
|
+
errorReason = ErrPermit2612AmountMismatch;
|
|
966
|
+
} else if (message.includes("InvalidAmount")) {
|
|
967
|
+
errorReason = ErrPermit2InvalidAmount;
|
|
968
|
+
} else if (message.includes("InvalidDestination")) {
|
|
969
|
+
errorReason = ErrPermit2InvalidDestination;
|
|
970
|
+
} else if (message.includes("InvalidOwner")) {
|
|
971
|
+
errorReason = ErrPermit2InvalidOwner;
|
|
972
|
+
} else if (message.includes("PaymentTooEarly")) {
|
|
973
|
+
errorReason = ErrPermit2PaymentTooEarly;
|
|
974
|
+
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
975
|
+
errorReason = ErrPermit2InvalidSignature;
|
|
976
|
+
} else if (message.includes("InvalidNonce")) {
|
|
977
|
+
errorReason = ErrPermit2InvalidNonce;
|
|
978
|
+
} else if (message.includes("erc20_approval_tx_failed")) {
|
|
979
|
+
errorReason = ErrErc20ApprovalTxFailed;
|
|
980
|
+
} else if (message.includes("AmountExceedsPermitted")) {
|
|
981
|
+
errorReason = ErrUptoAmountExceedsPermitted;
|
|
982
|
+
} else if (message.includes("UnauthorizedFacilitator")) {
|
|
983
|
+
errorReason = ErrUptoUnauthorizedFacilitator;
|
|
984
|
+
} else {
|
|
985
|
+
errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
return {
|
|
989
|
+
success: false,
|
|
990
|
+
errorReason,
|
|
991
|
+
transaction: "",
|
|
992
|
+
network: payload.accepted.network,
|
|
993
|
+
payer
|
|
994
|
+
};
|
|
995
|
+
}
|
|
996
|
+
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
997
|
+
if (!validateEip2612GasSponsoringInfo(info)) {
|
|
998
|
+
return { isValid: false, invalidReason: ErrInvalidEip2612ExtensionFormat };
|
|
999
|
+
}
|
|
1000
|
+
if ((0, import_viem6.getAddress)(info.from) !== (0, import_viem6.getAddress)(payer)) {
|
|
1001
|
+
return { isValid: false, invalidReason: ErrEip2612FromMismatch };
|
|
1002
|
+
}
|
|
1003
|
+
if ((0, import_viem6.getAddress)(info.asset) !== tokenAddress) {
|
|
1004
|
+
return { isValid: false, invalidReason: ErrEip2612AssetMismatch };
|
|
1005
|
+
}
|
|
1006
|
+
if ((0, import_viem6.getAddress)(info.spender) !== (0, import_viem6.getAddress)(PERMIT2_ADDRESS)) {
|
|
1007
|
+
return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };
|
|
1008
|
+
}
|
|
1009
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1010
|
+
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
1011
|
+
return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };
|
|
1012
|
+
}
|
|
1013
|
+
return { isValid: true };
|
|
1014
|
+
}
|
|
1015
|
+
async function simulatePermit2Settle(config, signer, settleArgs) {
|
|
930
1016
|
try {
|
|
931
1017
|
await signer.readContract({
|
|
932
|
-
address:
|
|
933
|
-
abi:
|
|
1018
|
+
address: config.proxyAddress,
|
|
1019
|
+
abi: config.proxyABI,
|
|
934
1020
|
functionName: "settle",
|
|
935
|
-
args:
|
|
1021
|
+
args: settleArgs
|
|
936
1022
|
});
|
|
937
1023
|
return true;
|
|
938
1024
|
} catch {
|
|
939
1025
|
return false;
|
|
940
1026
|
}
|
|
941
1027
|
}
|
|
942
|
-
function
|
|
943
|
-
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
944
|
-
if (sig.length !== 130) {
|
|
945
|
-
throw new Error(
|
|
946
|
-
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
947
|
-
);
|
|
948
|
-
}
|
|
949
|
-
const r = `0x${sig.slice(0, 64)}`;
|
|
950
|
-
const s = `0x${sig.slice(64, 128)}`;
|
|
951
|
-
const v = parseInt(sig.slice(128, 130), 16);
|
|
952
|
-
return { v, r, s };
|
|
953
|
-
}
|
|
954
|
-
function buildPermit2SettleArgs(permit2Payload) {
|
|
955
|
-
return [
|
|
956
|
-
{
|
|
957
|
-
permitted: {
|
|
958
|
-
token: (0, import_viem6.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
959
|
-
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
960
|
-
},
|
|
961
|
-
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
962
|
-
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
963
|
-
},
|
|
964
|
-
(0, import_viem6.getAddress)(permit2Payload.permit2Authorization.from),
|
|
965
|
-
{
|
|
966
|
-
to: (0, import_viem6.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
967
|
-
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
968
|
-
},
|
|
969
|
-
permit2Payload.signature
|
|
970
|
-
];
|
|
971
|
-
}
|
|
972
|
-
function encodePermit2SettleCalldata(permit2Payload) {
|
|
973
|
-
return (0, import_viem6.encodeFunctionData)({
|
|
974
|
-
abi: x402ExactPermit2ProxyABI,
|
|
975
|
-
functionName: "settle",
|
|
976
|
-
args: buildPermit2SettleArgs(permit2Payload)
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
async function simulatePermit2SettleWithPermit(signer, permit2Payload, eip2612Info) {
|
|
1028
|
+
async function simulatePermit2SettleWithPermit(config, signer, settleArgs, eip2612Info) {
|
|
980
1029
|
try {
|
|
981
1030
|
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
982
1031
|
await signer.readContract({
|
|
983
|
-
address:
|
|
984
|
-
abi:
|
|
1032
|
+
address: config.proxyAddress,
|
|
1033
|
+
abi: config.proxyABI,
|
|
985
1034
|
functionName: "settleWithPermit",
|
|
986
1035
|
args: [
|
|
987
1036
|
{
|
|
@@ -991,7 +1040,7 @@ async function simulatePermit2SettleWithPermit(signer, permit2Payload, eip2612In
|
|
|
991
1040
|
s,
|
|
992
1041
|
v
|
|
993
1042
|
},
|
|
994
|
-
...
|
|
1043
|
+
...settleArgs
|
|
995
1044
|
]
|
|
996
1045
|
});
|
|
997
1046
|
return true;
|
|
@@ -999,12 +1048,30 @@ async function simulatePermit2SettleWithPermit(signer, permit2Payload, eip2612In
|
|
|
999
1048
|
return false;
|
|
1000
1049
|
}
|
|
1001
1050
|
}
|
|
1002
|
-
async function
|
|
1051
|
+
async function simulatePermit2SettleWithErc20Approval(config, extensionSigner, settleArgs, erc20Info) {
|
|
1052
|
+
if (!extensionSigner.simulateTransactions) {
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
try {
|
|
1056
|
+
const settleData = (0, import_viem6.encodeFunctionData)({
|
|
1057
|
+
abi: config.proxyABI,
|
|
1058
|
+
functionName: "settle",
|
|
1059
|
+
args: settleArgs
|
|
1060
|
+
});
|
|
1061
|
+
return await extensionSigner.simulateTransactions([
|
|
1062
|
+
erc20Info.signedTransaction,
|
|
1063
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1064
|
+
]);
|
|
1065
|
+
} catch {
|
|
1066
|
+
return false;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
async function diagnosePermit2SimulationFailure(config, signer, tokenAddress, permit2Payload, amountRequired) {
|
|
1003
1070
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1004
1071
|
const diagnosticCalls = [
|
|
1005
1072
|
{
|
|
1006
|
-
address:
|
|
1007
|
-
abi:
|
|
1073
|
+
address: config.proxyAddress,
|
|
1074
|
+
abi: config.proxyABI,
|
|
1008
1075
|
functionName: "PERMIT2"
|
|
1009
1076
|
},
|
|
1010
1077
|
{
|
|
@@ -1042,11 +1109,11 @@ async function diagnosePermit2SimulationFailure(signer, tokenAddress, permit2Pay
|
|
|
1042
1109
|
}
|
|
1043
1110
|
return { isValid: false, invalidReason: ErrPermit2SimulationFailed, payer };
|
|
1044
1111
|
}
|
|
1045
|
-
async function checkPermit2Prerequisites(signer, tokenAddress, payer, amountRequired) {
|
|
1112
|
+
async function checkPermit2Prerequisites(config, signer, tokenAddress, payer, amountRequired) {
|
|
1046
1113
|
const diagnosticCalls = [
|
|
1047
1114
|
{
|
|
1048
|
-
address:
|
|
1049
|
-
abi:
|
|
1115
|
+
address: config.proxyAddress,
|
|
1116
|
+
abi: config.proxyABI,
|
|
1050
1117
|
functionName: "PERMIT2"
|
|
1051
1118
|
},
|
|
1052
1119
|
{
|
|
@@ -1054,17 +1121,11 @@ async function checkPermit2Prerequisites(signer, tokenAddress, payer, amountRequ
|
|
|
1054
1121
|
abi: eip3009ABI,
|
|
1055
1122
|
functionName: "balanceOf",
|
|
1056
1123
|
args: [payer]
|
|
1057
|
-
},
|
|
1058
|
-
{
|
|
1059
|
-
address: MULTICALL3_ADDRESS,
|
|
1060
|
-
abi: multicall3GetEthBalanceAbi,
|
|
1061
|
-
functionName: "getEthBalance",
|
|
1062
|
-
args: [payer]
|
|
1063
1124
|
}
|
|
1064
1125
|
];
|
|
1065
1126
|
try {
|
|
1066
1127
|
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
1067
|
-
const [proxyResult, balanceResult
|
|
1128
|
+
const [proxyResult, balanceResult] = results;
|
|
1068
1129
|
if (proxyResult.status === "failure") {
|
|
1069
1130
|
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
1070
1131
|
}
|
|
@@ -1074,106 +1135,46 @@ async function checkPermit2Prerequisites(signer, tokenAddress, payer, amountRequ
|
|
|
1074
1135
|
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
1075
1136
|
}
|
|
1076
1137
|
}
|
|
1077
|
-
if (ethBalanceResult.status === "success") {
|
|
1078
|
-
const minEthForApprovalGas = ERC20_APPROVE_GAS_LIMIT * DEFAULT_MAX_FEE_PER_GAS;
|
|
1079
|
-
const ethBalance = ethBalanceResult.result;
|
|
1080
|
-
if (ethBalance < minEthForApprovalGas) {
|
|
1081
|
-
return {
|
|
1082
|
-
isValid: false,
|
|
1083
|
-
invalidReason: ErrErc20ApprovalInsufficientEthForGas,
|
|
1084
|
-
payer
|
|
1085
|
-
};
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
1138
|
} catch {
|
|
1089
1139
|
}
|
|
1090
1140
|
return { isValid: true, invalidReason: void 0, payer };
|
|
1091
1141
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
return {
|
|
1110
|
-
success: false,
|
|
1111
|
-
errorReason: ErrInvalidTransactionState,
|
|
1112
|
-
transaction: tx,
|
|
1113
|
-
network: payload.accepted.network,
|
|
1114
|
-
payer
|
|
1115
|
-
};
|
|
1116
|
-
}
|
|
1117
|
-
return {
|
|
1118
|
-
success: true,
|
|
1119
|
-
transaction: tx,
|
|
1120
|
-
network: payload.accepted.network,
|
|
1121
|
-
payer
|
|
1122
|
-
};
|
|
1123
|
-
}
|
|
1124
|
-
function mapSettleError(error, payload, payer) {
|
|
1125
|
-
let errorReason = ErrTransactionFailed;
|
|
1126
|
-
if (error instanceof Error) {
|
|
1127
|
-
const message = error.message;
|
|
1128
|
-
if (message.includes("Permit2612AmountMismatch")) {
|
|
1129
|
-
errorReason = ErrPermit2612AmountMismatch;
|
|
1130
|
-
} else if (message.includes("InvalidAmount")) {
|
|
1131
|
-
errorReason = ErrPermit2InvalidAmount;
|
|
1132
|
-
} else if (message.includes("InvalidDestination")) {
|
|
1133
|
-
errorReason = ErrPermit2InvalidDestination;
|
|
1134
|
-
} else if (message.includes("InvalidOwner")) {
|
|
1135
|
-
errorReason = ErrPermit2InvalidOwner;
|
|
1136
|
-
} else if (message.includes("PaymentTooEarly")) {
|
|
1137
|
-
errorReason = ErrPermit2PaymentTooEarly;
|
|
1138
|
-
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
1139
|
-
errorReason = ErrPermit2InvalidSignature;
|
|
1140
|
-
} else if (message.includes("InvalidNonce")) {
|
|
1141
|
-
errorReason = ErrPermit2InvalidNonce;
|
|
1142
|
-
} else if (message.includes("erc20_approval_tx_failed")) {
|
|
1143
|
-
errorReason = ErrErc20ApprovalTxFailed;
|
|
1144
|
-
} else {
|
|
1145
|
-
errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
return {
|
|
1149
|
-
success: false,
|
|
1150
|
-
errorReason,
|
|
1151
|
-
transaction: "",
|
|
1152
|
-
network: payload.accepted.network,
|
|
1153
|
-
payer
|
|
1154
|
-
};
|
|
1142
|
+
function buildExactPermit2SettleArgs(permit2Payload) {
|
|
1143
|
+
return [
|
|
1144
|
+
{
|
|
1145
|
+
permitted: {
|
|
1146
|
+
token: (0, import_viem6.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
1147
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
1148
|
+
},
|
|
1149
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
1150
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
1151
|
+
},
|
|
1152
|
+
(0, import_viem6.getAddress)(permit2Payload.permit2Authorization.from),
|
|
1153
|
+
{
|
|
1154
|
+
to: (0, import_viem6.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
1155
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
1156
|
+
},
|
|
1157
|
+
permit2Payload.signature
|
|
1158
|
+
];
|
|
1155
1159
|
}
|
|
1156
|
-
function
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
}
|
|
1163
|
-
if ((0, import_viem6.getAddress)(info.asset) !== tokenAddress) {
|
|
1164
|
-
return { isValid: false, invalidReason: ErrEip2612AssetMismatch };
|
|
1165
|
-
}
|
|
1166
|
-
if ((0, import_viem6.getAddress)(info.spender) !== (0, import_viem6.getAddress)(PERMIT2_ADDRESS)) {
|
|
1167
|
-
return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };
|
|
1168
|
-
}
|
|
1169
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
1170
|
-
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
1171
|
-
return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };
|
|
1160
|
+
function splitEip2612Signature(signature) {
|
|
1161
|
+
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
1162
|
+
if (sig.length !== 130) {
|
|
1163
|
+
throw new Error(
|
|
1164
|
+
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
1165
|
+
);
|
|
1172
1166
|
}
|
|
1173
|
-
|
|
1167
|
+
const r = `0x${sig.slice(0, 64)}`;
|
|
1168
|
+
const s = `0x${sig.slice(64, 128)}`;
|
|
1169
|
+
const v = parseInt(sig.slice(128, 130), 16);
|
|
1170
|
+
return { v, r, s };
|
|
1174
1171
|
}
|
|
1175
1172
|
|
|
1176
1173
|
// src/exact/facilitator/permit2.ts
|
|
1174
|
+
var exactProxyConfig = {
|
|
1175
|
+
proxyAddress: x402ExactPermit2ProxyAddress,
|
|
1176
|
+
proxyABI: x402ExactPermit2ProxyABI
|
|
1177
|
+
};
|
|
1177
1178
|
async function verifyPermit2(signer, payload, requirements, permit2Payload, context, options) {
|
|
1178
1179
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1179
1180
|
if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
@@ -1287,9 +1288,16 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1287
1288
|
if (!fieldResult.isValid) {
|
|
1288
1289
|
return { isValid: false, invalidReason: fieldResult.invalidReason, payer };
|
|
1289
1290
|
}
|
|
1290
|
-
const
|
|
1291
|
+
const exactSettleArgs = buildExactPermit2SettleArgs(permit2Payload);
|
|
1292
|
+
const simOk2 = await simulatePermit2SettleWithPermit(
|
|
1293
|
+
exactProxyConfig,
|
|
1294
|
+
signer,
|
|
1295
|
+
exactSettleArgs,
|
|
1296
|
+
eip2612Info
|
|
1297
|
+
);
|
|
1291
1298
|
if (!simOk2) {
|
|
1292
1299
|
return diagnosePermit2SimulationFailure(
|
|
1300
|
+
exactProxyConfig,
|
|
1293
1301
|
signer,
|
|
1294
1302
|
tokenAddress,
|
|
1295
1303
|
permit2Payload,
|
|
@@ -1314,12 +1322,14 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1314
1322
|
);
|
|
1315
1323
|
if (extensionSigner?.simulateTransactions) {
|
|
1316
1324
|
const simOk2 = await simulatePermit2SettleWithErc20Approval(
|
|
1325
|
+
exactProxyConfig,
|
|
1317
1326
|
extensionSigner,
|
|
1318
|
-
permit2Payload,
|
|
1327
|
+
buildExactPermit2SettleArgs(permit2Payload),
|
|
1319
1328
|
erc20Info
|
|
1320
1329
|
);
|
|
1321
1330
|
if (!simOk2) {
|
|
1322
1331
|
return diagnosePermit2SimulationFailure(
|
|
1332
|
+
exactProxyConfig,
|
|
1323
1333
|
signer,
|
|
1324
1334
|
tokenAddress,
|
|
1325
1335
|
permit2Payload,
|
|
@@ -1328,12 +1338,23 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1328
1338
|
}
|
|
1329
1339
|
return { isValid: true, invalidReason: void 0, payer };
|
|
1330
1340
|
}
|
|
1331
|
-
return checkPermit2Prerequisites(
|
|
1341
|
+
return checkPermit2Prerequisites(
|
|
1342
|
+
exactProxyConfig,
|
|
1343
|
+
signer,
|
|
1344
|
+
tokenAddress,
|
|
1345
|
+
payer,
|
|
1346
|
+
requirements.amount
|
|
1347
|
+
);
|
|
1332
1348
|
}
|
|
1333
1349
|
}
|
|
1334
|
-
const simOk = await simulatePermit2Settle(
|
|
1350
|
+
const simOk = await simulatePermit2Settle(
|
|
1351
|
+
exactProxyConfig,
|
|
1352
|
+
signer,
|
|
1353
|
+
buildExactPermit2SettleArgs(permit2Payload)
|
|
1354
|
+
);
|
|
1335
1355
|
if (!simOk) {
|
|
1336
1356
|
return diagnosePermit2SimulationFailure(
|
|
1357
|
+
exactProxyConfig,
|
|
1337
1358
|
signer,
|
|
1338
1359
|
tokenAddress,
|
|
1339
1360
|
permit2Payload,
|
|
@@ -1358,7 +1379,7 @@ async function settlePermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1358
1379
|
}
|
|
1359
1380
|
const eip2612Info = extractEip2612GasSponsoringInfo(payload);
|
|
1360
1381
|
if (eip2612Info) {
|
|
1361
|
-
return
|
|
1382
|
+
return settlePermit2WithEIP2612(exactProxyConfig, signer, payload, permit2Payload, eip2612Info);
|
|
1362
1383
|
}
|
|
1363
1384
|
const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);
|
|
1364
1385
|
if (erc20Info) {
|
|
@@ -1370,18 +1391,24 @@ async function settlePermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1370
1391
|
payload.accepted.network
|
|
1371
1392
|
);
|
|
1372
1393
|
if (extensionSigner) {
|
|
1373
|
-
return
|
|
1394
|
+
return settlePermit2WithERC20Approval(
|
|
1395
|
+
exactProxyConfig,
|
|
1396
|
+
extensionSigner,
|
|
1397
|
+
payload,
|
|
1398
|
+
permit2Payload,
|
|
1399
|
+
erc20Info
|
|
1400
|
+
);
|
|
1374
1401
|
}
|
|
1375
1402
|
}
|
|
1376
|
-
return
|
|
1403
|
+
return settlePermit2Direct(exactProxyConfig, signer, payload, permit2Payload);
|
|
1377
1404
|
}
|
|
1378
|
-
async function
|
|
1405
|
+
async function settlePermit2WithEIP2612(config, signer, payload, permit2Payload, eip2612Info) {
|
|
1379
1406
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1380
1407
|
try {
|
|
1381
1408
|
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
1382
1409
|
const tx = await signer.writeContract({
|
|
1383
|
-
address:
|
|
1384
|
-
abi:
|
|
1410
|
+
address: config.proxyAddress,
|
|
1411
|
+
abi: config.proxyABI,
|
|
1385
1412
|
functionName: "settleWithPermit",
|
|
1386
1413
|
args: [
|
|
1387
1414
|
{
|
|
@@ -1391,38 +1418,42 @@ async function _settlePermit2WithEIP2612(signer, payload, permit2Payload, eip261
|
|
|
1391
1418
|
s,
|
|
1392
1419
|
v
|
|
1393
1420
|
},
|
|
1394
|
-
...
|
|
1421
|
+
...buildExactPermit2SettleArgs(permit2Payload)
|
|
1395
1422
|
]
|
|
1396
1423
|
});
|
|
1397
|
-
return
|
|
1424
|
+
return waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1398
1425
|
} catch (error) {
|
|
1399
1426
|
return mapSettleError(error, payload, payer);
|
|
1400
1427
|
}
|
|
1401
1428
|
}
|
|
1402
|
-
async function
|
|
1429
|
+
async function settlePermit2WithERC20Approval(config, extensionSigner, payload, permit2Payload, erc20Info) {
|
|
1403
1430
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1404
1431
|
try {
|
|
1405
|
-
const settleData =
|
|
1432
|
+
const settleData = (0, import_viem7.encodeFunctionData)({
|
|
1433
|
+
abi: config.proxyABI,
|
|
1434
|
+
functionName: "settle",
|
|
1435
|
+
args: buildExactPermit2SettleArgs(permit2Payload)
|
|
1436
|
+
});
|
|
1406
1437
|
const txHashes = await extensionSigner.sendTransactions([
|
|
1407
1438
|
erc20Info.signedTransaction,
|
|
1408
|
-
{ to:
|
|
1439
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1409
1440
|
]);
|
|
1410
1441
|
const settleTxHash = txHashes[txHashes.length - 1];
|
|
1411
|
-
return
|
|
1442
|
+
return waitAndReturnSettleResponse(extensionSigner, settleTxHash, payload, payer);
|
|
1412
1443
|
} catch (error) {
|
|
1413
1444
|
return mapSettleError(error, payload, payer);
|
|
1414
1445
|
}
|
|
1415
1446
|
}
|
|
1416
|
-
async function
|
|
1447
|
+
async function settlePermit2Direct(config, signer, payload, permit2Payload) {
|
|
1417
1448
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1418
1449
|
try {
|
|
1419
1450
|
const tx = await signer.writeContract({
|
|
1420
|
-
address:
|
|
1421
|
-
abi:
|
|
1451
|
+
address: config.proxyAddress,
|
|
1452
|
+
abi: config.proxyABI,
|
|
1422
1453
|
functionName: "settle",
|
|
1423
|
-
args:
|
|
1454
|
+
args: buildExactPermit2SettleArgs(permit2Payload)
|
|
1424
1455
|
});
|
|
1425
|
-
return
|
|
1456
|
+
return waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1426
1457
|
} catch (error) {
|
|
1427
1458
|
return mapSettleError(error, payload, payer);
|
|
1428
1459
|
}
|
|
@@ -1529,7 +1560,9 @@ var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
|
1529
1560
|
megaeth: 4326,
|
|
1530
1561
|
monad: 143,
|
|
1531
1562
|
kiteai: 2366,
|
|
1532
|
-
"kiteai-testnet": 2368
|
|
1563
|
+
"kiteai-testnet": 2368,
|
|
1564
|
+
stable: 988,
|
|
1565
|
+
"stable-testnet": 2201
|
|
1533
1566
|
};
|
|
1534
1567
|
var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
|
|
1535
1568
|
function getEvmChainIdV1(network) {
|