@x402/evm 2.8.0 → 2.9.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/README.md +2 -39
- 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 +199 -185
- package/dist/cjs/exact/facilitator/index.js.map +1 -1
- package/dist/cjs/exact/server/index.d.ts +18 -17
- package/dist/cjs/exact/server/index.js +100 -55
- 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 +77 -0
- package/dist/cjs/upto/server/index.js +246 -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-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-NSFLAANF.mjs +80 -0
- package/dist/esm/chunk-NSFLAANF.mjs.map +1 -0
- package/dist/esm/chunk-RN3WQM6A.mjs +158 -0
- package/dist/esm/chunk-RN3WQM6A.mjs.map +1 -0
- package/dist/esm/chunk-WKBC5YMI.mjs +291 -0
- package/dist/esm/chunk-WKBC5YMI.mjs.map +1 -0
- package/dist/esm/{chunk-IZEI7JTG.mjs → chunk-YUJQ7TLD.mjs} +29 -501
- package/dist/esm/chunk-YUJQ7TLD.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 +84 -430
- package/dist/esm/exact/facilitator/index.mjs.map +1 -1
- package/dist/esm/exact/server/index.d.mts +18 -17
- package/dist/esm/exact/server/index.mjs +28 -55
- 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 +77 -0
- package/dist/esm/upto/server/index.mjs +145 -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 +34 -4
- package/dist/esm/chunk-GD4MKCN7.mjs +0 -57
- package/dist/esm/chunk-GD4MKCN7.mjs.map +0 -1
- package/dist/esm/chunk-IZEI7JTG.mjs.map +0 -1
- package/dist/esm/chunk-TKN5V2BV.mjs +0 -13
- package/dist/esm/chunk-TKN5V2BV.mjs.map +0 -1
- package/dist/esm/chunk-WJWNS4G4.mjs +0 -518
- package/dist/esm/chunk-WJWNS4G4.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: [
|
|
@@ -826,7 +814,7 @@ function resolveErc20ApprovalExtensionSigner(extension, network) {
|
|
|
826
814
|
// src/exact/facilitator/permit2.ts
|
|
827
815
|
var import_viem7 = require("viem");
|
|
828
816
|
|
|
829
|
-
// src/
|
|
817
|
+
// src/shared/erc20approval.ts
|
|
830
818
|
var import_viem5 = require("viem");
|
|
831
819
|
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
832
820
|
async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
@@ -924,64 +912,106 @@ async function validateErc20ApprovalForPayment(info, payer, tokenAddress) {
|
|
|
924
912
|
return { isValid: true };
|
|
925
913
|
}
|
|
926
914
|
|
|
927
|
-
// src/
|
|
915
|
+
// src/shared/permit2.ts
|
|
928
916
|
var import_viem6 = require("viem");
|
|
929
|
-
|
|
917
|
+
|
|
918
|
+
// src/upto/facilitator/errors.ts
|
|
919
|
+
var ErrUptoAmountExceedsPermitted = "upto_amount_exceeds_permitted";
|
|
920
|
+
var ErrUptoUnauthorizedFacilitator = "upto_unauthorized_facilitator";
|
|
921
|
+
|
|
922
|
+
// src/shared/permit2.ts
|
|
923
|
+
async function waitAndReturnSettleResponse(signer, tx, payload, payer) {
|
|
924
|
+
const receipt = await signer.waitForTransactionReceipt({ hash: tx });
|
|
925
|
+
if (receipt.status !== "success") {
|
|
926
|
+
return {
|
|
927
|
+
success: false,
|
|
928
|
+
errorReason: ErrInvalidTransactionState,
|
|
929
|
+
transaction: tx,
|
|
930
|
+
network: payload.accepted.network,
|
|
931
|
+
payer
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
return {
|
|
935
|
+
success: true,
|
|
936
|
+
transaction: tx,
|
|
937
|
+
network: payload.accepted.network,
|
|
938
|
+
payer
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
function mapSettleError(error, payload, payer) {
|
|
942
|
+
let errorReason = ErrTransactionFailed;
|
|
943
|
+
if (error instanceof Error) {
|
|
944
|
+
const message = error.message;
|
|
945
|
+
if (message.includes("Permit2612AmountMismatch")) {
|
|
946
|
+
errorReason = ErrPermit2612AmountMismatch;
|
|
947
|
+
} else if (message.includes("InvalidAmount")) {
|
|
948
|
+
errorReason = ErrPermit2InvalidAmount;
|
|
949
|
+
} else if (message.includes("InvalidDestination")) {
|
|
950
|
+
errorReason = ErrPermit2InvalidDestination;
|
|
951
|
+
} else if (message.includes("InvalidOwner")) {
|
|
952
|
+
errorReason = ErrPermit2InvalidOwner;
|
|
953
|
+
} else if (message.includes("PaymentTooEarly")) {
|
|
954
|
+
errorReason = ErrPermit2PaymentTooEarly;
|
|
955
|
+
} else if (message.includes("InvalidSignature") || message.includes("SignatureExpired")) {
|
|
956
|
+
errorReason = ErrPermit2InvalidSignature;
|
|
957
|
+
} else if (message.includes("InvalidNonce")) {
|
|
958
|
+
errorReason = ErrPermit2InvalidNonce;
|
|
959
|
+
} else if (message.includes("erc20_approval_tx_failed")) {
|
|
960
|
+
errorReason = ErrErc20ApprovalTxFailed;
|
|
961
|
+
} else if (message.includes("AmountExceedsPermitted")) {
|
|
962
|
+
errorReason = ErrUptoAmountExceedsPermitted;
|
|
963
|
+
} else if (message.includes("UnauthorizedFacilitator")) {
|
|
964
|
+
errorReason = ErrUptoUnauthorizedFacilitator;
|
|
965
|
+
} else {
|
|
966
|
+
errorReason = `${ErrTransactionFailed}: ${message.slice(0, 500)}`;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
return {
|
|
970
|
+
success: false,
|
|
971
|
+
errorReason,
|
|
972
|
+
transaction: "",
|
|
973
|
+
network: payload.accepted.network,
|
|
974
|
+
payer
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
function validateEip2612PermitForPayment(info, payer, tokenAddress) {
|
|
978
|
+
if (!validateEip2612GasSponsoringInfo(info)) {
|
|
979
|
+
return { isValid: false, invalidReason: ErrInvalidEip2612ExtensionFormat };
|
|
980
|
+
}
|
|
981
|
+
if ((0, import_viem6.getAddress)(info.from) !== (0, import_viem6.getAddress)(payer)) {
|
|
982
|
+
return { isValid: false, invalidReason: ErrEip2612FromMismatch };
|
|
983
|
+
}
|
|
984
|
+
if ((0, import_viem6.getAddress)(info.asset) !== tokenAddress) {
|
|
985
|
+
return { isValid: false, invalidReason: ErrEip2612AssetMismatch };
|
|
986
|
+
}
|
|
987
|
+
if ((0, import_viem6.getAddress)(info.spender) !== (0, import_viem6.getAddress)(PERMIT2_ADDRESS)) {
|
|
988
|
+
return { isValid: false, invalidReason: ErrEip2612SpenderNotPermit2 };
|
|
989
|
+
}
|
|
990
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
991
|
+
if (BigInt(info.deadline) < BigInt(now + 6)) {
|
|
992
|
+
return { isValid: false, invalidReason: ErrEip2612DeadlineExpired };
|
|
993
|
+
}
|
|
994
|
+
return { isValid: true };
|
|
995
|
+
}
|
|
996
|
+
async function simulatePermit2Settle(config, signer, settleArgs) {
|
|
930
997
|
try {
|
|
931
998
|
await signer.readContract({
|
|
932
|
-
address:
|
|
933
|
-
abi:
|
|
999
|
+
address: config.proxyAddress,
|
|
1000
|
+
abi: config.proxyABI,
|
|
934
1001
|
functionName: "settle",
|
|
935
|
-
args:
|
|
1002
|
+
args: settleArgs
|
|
936
1003
|
});
|
|
937
1004
|
return true;
|
|
938
1005
|
} catch {
|
|
939
1006
|
return false;
|
|
940
1007
|
}
|
|
941
1008
|
}
|
|
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) {
|
|
1009
|
+
async function simulatePermit2SettleWithPermit(config, signer, settleArgs, eip2612Info) {
|
|
980
1010
|
try {
|
|
981
1011
|
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
982
1012
|
await signer.readContract({
|
|
983
|
-
address:
|
|
984
|
-
abi:
|
|
1013
|
+
address: config.proxyAddress,
|
|
1014
|
+
abi: config.proxyABI,
|
|
985
1015
|
functionName: "settleWithPermit",
|
|
986
1016
|
args: [
|
|
987
1017
|
{
|
|
@@ -991,7 +1021,7 @@ async function simulatePermit2SettleWithPermit(signer, permit2Payload, eip2612In
|
|
|
991
1021
|
s,
|
|
992
1022
|
v
|
|
993
1023
|
},
|
|
994
|
-
...
|
|
1024
|
+
...settleArgs
|
|
995
1025
|
]
|
|
996
1026
|
});
|
|
997
1027
|
return true;
|
|
@@ -999,12 +1029,30 @@ async function simulatePermit2SettleWithPermit(signer, permit2Payload, eip2612In
|
|
|
999
1029
|
return false;
|
|
1000
1030
|
}
|
|
1001
1031
|
}
|
|
1002
|
-
async function
|
|
1032
|
+
async function simulatePermit2SettleWithErc20Approval(config, extensionSigner, settleArgs, erc20Info) {
|
|
1033
|
+
if (!extensionSigner.simulateTransactions) {
|
|
1034
|
+
return false;
|
|
1035
|
+
}
|
|
1036
|
+
try {
|
|
1037
|
+
const settleData = (0, import_viem6.encodeFunctionData)({
|
|
1038
|
+
abi: config.proxyABI,
|
|
1039
|
+
functionName: "settle",
|
|
1040
|
+
args: settleArgs
|
|
1041
|
+
});
|
|
1042
|
+
return await extensionSigner.simulateTransactions([
|
|
1043
|
+
erc20Info.signedTransaction,
|
|
1044
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1045
|
+
]);
|
|
1046
|
+
} catch {
|
|
1047
|
+
return false;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
async function diagnosePermit2SimulationFailure(config, signer, tokenAddress, permit2Payload, amountRequired) {
|
|
1003
1051
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1004
1052
|
const diagnosticCalls = [
|
|
1005
1053
|
{
|
|
1006
|
-
address:
|
|
1007
|
-
abi:
|
|
1054
|
+
address: config.proxyAddress,
|
|
1055
|
+
abi: config.proxyABI,
|
|
1008
1056
|
functionName: "PERMIT2"
|
|
1009
1057
|
},
|
|
1010
1058
|
{
|
|
@@ -1042,11 +1090,11 @@ async function diagnosePermit2SimulationFailure(signer, tokenAddress, permit2Pay
|
|
|
1042
1090
|
}
|
|
1043
1091
|
return { isValid: false, invalidReason: ErrPermit2SimulationFailed, payer };
|
|
1044
1092
|
}
|
|
1045
|
-
async function checkPermit2Prerequisites(signer, tokenAddress, payer, amountRequired) {
|
|
1093
|
+
async function checkPermit2Prerequisites(config, signer, tokenAddress, payer, amountRequired) {
|
|
1046
1094
|
const diagnosticCalls = [
|
|
1047
1095
|
{
|
|
1048
|
-
address:
|
|
1049
|
-
abi:
|
|
1096
|
+
address: config.proxyAddress,
|
|
1097
|
+
abi: config.proxyABI,
|
|
1050
1098
|
functionName: "PERMIT2"
|
|
1051
1099
|
},
|
|
1052
1100
|
{
|
|
@@ -1054,17 +1102,11 @@ async function checkPermit2Prerequisites(signer, tokenAddress, payer, amountRequ
|
|
|
1054
1102
|
abi: eip3009ABI,
|
|
1055
1103
|
functionName: "balanceOf",
|
|
1056
1104
|
args: [payer]
|
|
1057
|
-
},
|
|
1058
|
-
{
|
|
1059
|
-
address: MULTICALL3_ADDRESS,
|
|
1060
|
-
abi: multicall3GetEthBalanceAbi,
|
|
1061
|
-
functionName: "getEthBalance",
|
|
1062
|
-
args: [payer]
|
|
1063
1105
|
}
|
|
1064
1106
|
];
|
|
1065
1107
|
try {
|
|
1066
1108
|
const results = await multicall(signer.readContract.bind(signer), diagnosticCalls);
|
|
1067
|
-
const [proxyResult, balanceResult
|
|
1109
|
+
const [proxyResult, balanceResult] = results;
|
|
1068
1110
|
if (proxyResult.status === "failure") {
|
|
1069
1111
|
return { isValid: false, invalidReason: ErrPermit2ProxyNotDeployed, payer };
|
|
1070
1112
|
}
|
|
@@ -1074,106 +1116,46 @@ async function checkPermit2Prerequisites(signer, tokenAddress, payer, amountRequ
|
|
|
1074
1116
|
return { isValid: false, invalidReason: ErrPermit2InsufficientBalance, payer };
|
|
1075
1117
|
}
|
|
1076
1118
|
}
|
|
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
1119
|
} catch {
|
|
1089
1120
|
}
|
|
1090
1121
|
return { isValid: true, invalidReason: void 0, payer };
|
|
1091
1122
|
}
|
|
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
|
-
};
|
|
1123
|
+
function buildExactPermit2SettleArgs(permit2Payload) {
|
|
1124
|
+
return [
|
|
1125
|
+
{
|
|
1126
|
+
permitted: {
|
|
1127
|
+
token: (0, import_viem6.getAddress)(permit2Payload.permit2Authorization.permitted.token),
|
|
1128
|
+
amount: BigInt(permit2Payload.permit2Authorization.permitted.amount)
|
|
1129
|
+
},
|
|
1130
|
+
nonce: BigInt(permit2Payload.permit2Authorization.nonce),
|
|
1131
|
+
deadline: BigInt(permit2Payload.permit2Authorization.deadline)
|
|
1132
|
+
},
|
|
1133
|
+
(0, import_viem6.getAddress)(permit2Payload.permit2Authorization.from),
|
|
1134
|
+
{
|
|
1135
|
+
to: (0, import_viem6.getAddress)(permit2Payload.permit2Authorization.witness.to),
|
|
1136
|
+
validAfter: BigInt(permit2Payload.permit2Authorization.witness.validAfter)
|
|
1137
|
+
},
|
|
1138
|
+
permit2Payload.signature
|
|
1139
|
+
];
|
|
1155
1140
|
}
|
|
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 };
|
|
1141
|
+
function splitEip2612Signature(signature) {
|
|
1142
|
+
const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
|
|
1143
|
+
if (sig.length !== 130) {
|
|
1144
|
+
throw new Error(
|
|
1145
|
+
`invalid EIP-2612 signature length: expected 65 bytes (130 hex chars), got ${sig.length / 2} bytes`
|
|
1146
|
+
);
|
|
1172
1147
|
}
|
|
1173
|
-
|
|
1148
|
+
const r = `0x${sig.slice(0, 64)}`;
|
|
1149
|
+
const s = `0x${sig.slice(64, 128)}`;
|
|
1150
|
+
const v = parseInt(sig.slice(128, 130), 16);
|
|
1151
|
+
return { v, r, s };
|
|
1174
1152
|
}
|
|
1175
1153
|
|
|
1176
1154
|
// src/exact/facilitator/permit2.ts
|
|
1155
|
+
var exactProxyConfig = {
|
|
1156
|
+
proxyAddress: x402ExactPermit2ProxyAddress,
|
|
1157
|
+
proxyABI: x402ExactPermit2ProxyABI
|
|
1158
|
+
};
|
|
1177
1159
|
async function verifyPermit2(signer, payload, requirements, permit2Payload, context, options) {
|
|
1178
1160
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1179
1161
|
if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
|
|
@@ -1287,9 +1269,16 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1287
1269
|
if (!fieldResult.isValid) {
|
|
1288
1270
|
return { isValid: false, invalidReason: fieldResult.invalidReason, payer };
|
|
1289
1271
|
}
|
|
1290
|
-
const
|
|
1272
|
+
const exactSettleArgs = buildExactPermit2SettleArgs(permit2Payload);
|
|
1273
|
+
const simOk2 = await simulatePermit2SettleWithPermit(
|
|
1274
|
+
exactProxyConfig,
|
|
1275
|
+
signer,
|
|
1276
|
+
exactSettleArgs,
|
|
1277
|
+
eip2612Info
|
|
1278
|
+
);
|
|
1291
1279
|
if (!simOk2) {
|
|
1292
1280
|
return diagnosePermit2SimulationFailure(
|
|
1281
|
+
exactProxyConfig,
|
|
1293
1282
|
signer,
|
|
1294
1283
|
tokenAddress,
|
|
1295
1284
|
permit2Payload,
|
|
@@ -1314,12 +1303,14 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1314
1303
|
);
|
|
1315
1304
|
if (extensionSigner?.simulateTransactions) {
|
|
1316
1305
|
const simOk2 = await simulatePermit2SettleWithErc20Approval(
|
|
1306
|
+
exactProxyConfig,
|
|
1317
1307
|
extensionSigner,
|
|
1318
|
-
permit2Payload,
|
|
1308
|
+
buildExactPermit2SettleArgs(permit2Payload),
|
|
1319
1309
|
erc20Info
|
|
1320
1310
|
);
|
|
1321
1311
|
if (!simOk2) {
|
|
1322
1312
|
return diagnosePermit2SimulationFailure(
|
|
1313
|
+
exactProxyConfig,
|
|
1323
1314
|
signer,
|
|
1324
1315
|
tokenAddress,
|
|
1325
1316
|
permit2Payload,
|
|
@@ -1328,12 +1319,23 @@ async function verifyPermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1328
1319
|
}
|
|
1329
1320
|
return { isValid: true, invalidReason: void 0, payer };
|
|
1330
1321
|
}
|
|
1331
|
-
return checkPermit2Prerequisites(
|
|
1322
|
+
return checkPermit2Prerequisites(
|
|
1323
|
+
exactProxyConfig,
|
|
1324
|
+
signer,
|
|
1325
|
+
tokenAddress,
|
|
1326
|
+
payer,
|
|
1327
|
+
requirements.amount
|
|
1328
|
+
);
|
|
1332
1329
|
}
|
|
1333
1330
|
}
|
|
1334
|
-
const simOk = await simulatePermit2Settle(
|
|
1331
|
+
const simOk = await simulatePermit2Settle(
|
|
1332
|
+
exactProxyConfig,
|
|
1333
|
+
signer,
|
|
1334
|
+
buildExactPermit2SettleArgs(permit2Payload)
|
|
1335
|
+
);
|
|
1335
1336
|
if (!simOk) {
|
|
1336
1337
|
return diagnosePermit2SimulationFailure(
|
|
1338
|
+
exactProxyConfig,
|
|
1337
1339
|
signer,
|
|
1338
1340
|
tokenAddress,
|
|
1339
1341
|
permit2Payload,
|
|
@@ -1358,7 +1360,7 @@ async function settlePermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1358
1360
|
}
|
|
1359
1361
|
const eip2612Info = extractEip2612GasSponsoringInfo(payload);
|
|
1360
1362
|
if (eip2612Info) {
|
|
1361
|
-
return
|
|
1363
|
+
return settlePermit2WithEIP2612(exactProxyConfig, signer, payload, permit2Payload, eip2612Info);
|
|
1362
1364
|
}
|
|
1363
1365
|
const erc20Info = extractErc20ApprovalGasSponsoringInfo(payload);
|
|
1364
1366
|
if (erc20Info) {
|
|
@@ -1370,18 +1372,24 @@ async function settlePermit2(signer, payload, requirements, permit2Payload, cont
|
|
|
1370
1372
|
payload.accepted.network
|
|
1371
1373
|
);
|
|
1372
1374
|
if (extensionSigner) {
|
|
1373
|
-
return
|
|
1375
|
+
return settlePermit2WithERC20Approval(
|
|
1376
|
+
exactProxyConfig,
|
|
1377
|
+
extensionSigner,
|
|
1378
|
+
payload,
|
|
1379
|
+
permit2Payload,
|
|
1380
|
+
erc20Info
|
|
1381
|
+
);
|
|
1374
1382
|
}
|
|
1375
1383
|
}
|
|
1376
|
-
return
|
|
1384
|
+
return settlePermit2Direct(exactProxyConfig, signer, payload, permit2Payload);
|
|
1377
1385
|
}
|
|
1378
|
-
async function
|
|
1386
|
+
async function settlePermit2WithEIP2612(config, signer, payload, permit2Payload, eip2612Info) {
|
|
1379
1387
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1380
1388
|
try {
|
|
1381
1389
|
const { v, r, s } = splitEip2612Signature(eip2612Info.signature);
|
|
1382
1390
|
const tx = await signer.writeContract({
|
|
1383
|
-
address:
|
|
1384
|
-
abi:
|
|
1391
|
+
address: config.proxyAddress,
|
|
1392
|
+
abi: config.proxyABI,
|
|
1385
1393
|
functionName: "settleWithPermit",
|
|
1386
1394
|
args: [
|
|
1387
1395
|
{
|
|
@@ -1391,38 +1399,42 @@ async function _settlePermit2WithEIP2612(signer, payload, permit2Payload, eip261
|
|
|
1391
1399
|
s,
|
|
1392
1400
|
v
|
|
1393
1401
|
},
|
|
1394
|
-
...
|
|
1402
|
+
...buildExactPermit2SettleArgs(permit2Payload)
|
|
1395
1403
|
]
|
|
1396
1404
|
});
|
|
1397
|
-
return
|
|
1405
|
+
return waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1398
1406
|
} catch (error) {
|
|
1399
1407
|
return mapSettleError(error, payload, payer);
|
|
1400
1408
|
}
|
|
1401
1409
|
}
|
|
1402
|
-
async function
|
|
1410
|
+
async function settlePermit2WithERC20Approval(config, extensionSigner, payload, permit2Payload, erc20Info) {
|
|
1403
1411
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1404
1412
|
try {
|
|
1405
|
-
const settleData =
|
|
1413
|
+
const settleData = (0, import_viem7.encodeFunctionData)({
|
|
1414
|
+
abi: config.proxyABI,
|
|
1415
|
+
functionName: "settle",
|
|
1416
|
+
args: buildExactPermit2SettleArgs(permit2Payload)
|
|
1417
|
+
});
|
|
1406
1418
|
const txHashes = await extensionSigner.sendTransactions([
|
|
1407
1419
|
erc20Info.signedTransaction,
|
|
1408
|
-
{ to:
|
|
1420
|
+
{ to: config.proxyAddress, data: settleData, gas: BigInt(3e5) }
|
|
1409
1421
|
]);
|
|
1410
1422
|
const settleTxHash = txHashes[txHashes.length - 1];
|
|
1411
|
-
return
|
|
1423
|
+
return waitAndReturnSettleResponse(extensionSigner, settleTxHash, payload, payer);
|
|
1412
1424
|
} catch (error) {
|
|
1413
1425
|
return mapSettleError(error, payload, payer);
|
|
1414
1426
|
}
|
|
1415
1427
|
}
|
|
1416
|
-
async function
|
|
1428
|
+
async function settlePermit2Direct(config, signer, payload, permit2Payload) {
|
|
1417
1429
|
const payer = permit2Payload.permit2Authorization.from;
|
|
1418
1430
|
try {
|
|
1419
1431
|
const tx = await signer.writeContract({
|
|
1420
|
-
address:
|
|
1421
|
-
abi:
|
|
1432
|
+
address: config.proxyAddress,
|
|
1433
|
+
abi: config.proxyABI,
|
|
1422
1434
|
functionName: "settle",
|
|
1423
|
-
args:
|
|
1435
|
+
args: buildExactPermit2SettleArgs(permit2Payload)
|
|
1424
1436
|
});
|
|
1425
|
-
return
|
|
1437
|
+
return waitAndReturnSettleResponse(signer, tx, payload, payer);
|
|
1426
1438
|
} catch (error) {
|
|
1427
1439
|
return mapSettleError(error, payload, payer);
|
|
1428
1440
|
}
|
|
@@ -1527,7 +1539,9 @@ var EVM_NETWORK_CHAIN_ID_MAP = {
|
|
|
1527
1539
|
educhain: 41923,
|
|
1528
1540
|
"skale-base-sepolia": 324705682,
|
|
1529
1541
|
megaeth: 4326,
|
|
1530
|
-
monad: 143
|
|
1542
|
+
monad: 143,
|
|
1543
|
+
stable: 988,
|
|
1544
|
+
"stable-testnet": 2201
|
|
1531
1545
|
};
|
|
1532
1546
|
var NETWORKS = Object.keys(EVM_NETWORK_CHAIN_ID_MAP);
|
|
1533
1547
|
function getEvmChainIdV1(network) {
|