@t402/evm 2.4.0 → 2.6.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/dist/cjs/exact/client/index.d.ts +1 -1
- package/dist/cjs/exact/server/index.js +13 -0
- package/dist/cjs/exact/server/index.js.map +1 -1
- package/dist/cjs/index-fzI2FyBT.d.ts +122 -0
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +13 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/permit2/client/index.d.ts +81 -0
- package/dist/cjs/permit2/client/index.js +150 -0
- package/dist/cjs/permit2/client/index.js.map +1 -0
- package/dist/cjs/permit2/facilitator/index.d.ts +82 -0
- package/dist/cjs/permit2/facilitator/index.js +301 -0
- package/dist/cjs/permit2/facilitator/index.js.map +1 -0
- package/dist/cjs/permit2/index.d.ts +145 -0
- package/dist/cjs/permit2/index.js +1075 -0
- package/dist/cjs/permit2/index.js.map +1 -0
- package/dist/cjs/permit2/server/index.d.ts +3 -0
- package/dist/cjs/permit2/server/index.js +686 -0
- package/dist/cjs/permit2/server/index.js.map +1 -0
- package/dist/cjs/{scheme-CIar5W2B.d.ts → scheme-549isuwf.d.ts} +1 -1
- package/dist/cjs/upto/client/index.js.map +1 -1
- package/dist/cjs/upto/index.d.ts +1 -1
- package/dist/cjs/upto/index.js +13 -0
- package/dist/cjs/upto/index.js.map +1 -1
- package/dist/esm/chunk-3KHB6QTD.mjs +112 -0
- package/dist/esm/chunk-3KHB6QTD.mjs.map +1 -0
- package/dist/esm/{chunk-SURTCHSX.mjs → chunk-AH3XB4XD.mjs} +1 -1
- package/dist/esm/chunk-AH3XB4XD.mjs.map +1 -0
- package/dist/esm/{chunk-SJ52GTJJ.mjs → chunk-EEZNFYCW.mjs} +6 -6
- package/dist/esm/{chunk-IWSDEZKI.mjs → chunk-FUUW3JGG.mjs} +14 -1
- package/dist/esm/chunk-FUUW3JGG.mjs.map +1 -0
- package/dist/esm/chunk-MMQSLAA2.mjs +190 -0
- package/dist/esm/chunk-MMQSLAA2.mjs.map +1 -0
- package/dist/esm/chunk-NIGKNI66.mjs +224 -0
- package/dist/esm/chunk-NIGKNI66.mjs.map +1 -0
- package/dist/esm/chunk-URG4HEYQ.mjs +74 -0
- package/dist/esm/chunk-URG4HEYQ.mjs.map +1 -0
- package/dist/esm/exact/client/index.d.mts +1 -1
- package/dist/esm/exact/server/index.mjs +1 -1
- package/dist/esm/index-fzI2FyBT.d.mts +122 -0
- package/dist/esm/index.d.mts +1 -1
- package/dist/esm/index.mjs +10 -10
- package/dist/esm/permit2/client/index.d.mts +81 -0
- package/dist/esm/permit2/client/index.mjs +11 -0
- package/dist/esm/permit2/client/index.mjs.map +1 -0
- package/dist/esm/permit2/facilitator/index.d.mts +82 -0
- package/dist/esm/permit2/facilitator/index.mjs +11 -0
- package/dist/esm/permit2/facilitator/index.mjs.map +1 -0
- package/dist/esm/permit2/index.d.mts +145 -0
- package/dist/esm/permit2/index.mjs +31 -0
- package/dist/esm/permit2/index.mjs.map +1 -0
- package/dist/esm/permit2/server/index.d.mts +3 -0
- package/dist/esm/permit2/server/index.mjs +12 -0
- package/dist/esm/permit2/server/index.mjs.map +1 -0
- package/dist/esm/{scheme-DATfd6oM.d.mts → scheme-lCNykV7l.d.mts} +1 -1
- package/dist/esm/upto/client/index.mjs +1 -1
- package/dist/esm/upto/index.d.mts +1 -1
- package/dist/esm/upto/index.mjs +3 -3
- package/package.json +63 -16
- package/dist/esm/chunk-IWSDEZKI.mjs.map +0 -1
- package/dist/esm/chunk-SURTCHSX.mjs.map +0 -1
- /package/dist/esm/{chunk-SJ52GTJJ.mjs.map → chunk-EEZNFYCW.mjs.map} +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@t402/core/types';
|
|
2
|
+
import { C as ClientEvmSigner } from '../../signer-DcavxxZt.js';
|
|
3
|
+
import { SelectPaymentRequirements, PaymentPolicy, t402Client } from '@t402/core/client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* EVM client implementation for the Permit2 payment scheme.
|
|
7
|
+
*
|
|
8
|
+
* Uses Uniswap Permit2 SignatureTransfer for gasless token approvals.
|
|
9
|
+
*/
|
|
10
|
+
declare class Permit2EvmScheme implements SchemeNetworkClient {
|
|
11
|
+
private readonly signer;
|
|
12
|
+
readonly scheme = "permit2";
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new Permit2EvmScheme instance.
|
|
15
|
+
*
|
|
16
|
+
* @param signer - The EVM signer for client operations
|
|
17
|
+
*/
|
|
18
|
+
constructor(signer: ClientEvmSigner);
|
|
19
|
+
/**
|
|
20
|
+
* Creates a payment payload for the Permit2 scheme.
|
|
21
|
+
*
|
|
22
|
+
* @param t402Version - The t402 protocol version
|
|
23
|
+
* @param paymentRequirements - The payment requirements
|
|
24
|
+
* @returns Promise resolving to a payment payload
|
|
25
|
+
*/
|
|
26
|
+
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "t402Version" | "payload">>;
|
|
27
|
+
/**
|
|
28
|
+
* Sign the Permit2 SignatureTransfer using EIP-712
|
|
29
|
+
*
|
|
30
|
+
* @param permit - The permit transfer data
|
|
31
|
+
* @param spender - The spender address
|
|
32
|
+
* @param requirements - The payment requirements
|
|
33
|
+
* @returns Signed typed data hex string
|
|
34
|
+
*/
|
|
35
|
+
private signPermit2;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Configuration options for registering Permit2 EVM schemes to an t402Client
|
|
40
|
+
*/
|
|
41
|
+
interface Permit2EvmClientConfig {
|
|
42
|
+
/**
|
|
43
|
+
* The EVM signer to use for creating payment payloads
|
|
44
|
+
*/
|
|
45
|
+
signer: ClientEvmSigner;
|
|
46
|
+
/**
|
|
47
|
+
* Optional payment requirements selector function
|
|
48
|
+
* If not provided, uses the default selector (first available option)
|
|
49
|
+
*/
|
|
50
|
+
paymentRequirementsSelector?: SelectPaymentRequirements;
|
|
51
|
+
/**
|
|
52
|
+
* Optional policies to apply to the client
|
|
53
|
+
*/
|
|
54
|
+
policies?: PaymentPolicy[];
|
|
55
|
+
/**
|
|
56
|
+
* Optional specific networks to register
|
|
57
|
+
* If not provided, registers wildcard support (eip155:*)
|
|
58
|
+
*/
|
|
59
|
+
networks?: Network[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Registers Permit2 EVM payment schemes to an t402Client instance.
|
|
63
|
+
*
|
|
64
|
+
* @param client - The t402Client instance to register schemes to
|
|
65
|
+
* @param config - Configuration for Permit2 EVM client registration
|
|
66
|
+
* @returns The client instance for chaining
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* import { registerPermit2EvmScheme } from "@t402/evm/permit2/client";
|
|
71
|
+
* import { t402Client } from "@t402/core/client";
|
|
72
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
73
|
+
*
|
|
74
|
+
* const account = privateKeyToAccount("0x...");
|
|
75
|
+
* const client = new t402Client();
|
|
76
|
+
* registerPermit2EvmScheme(client, { signer: account });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
declare function registerPermit2EvmScheme(client: t402Client, config: Permit2EvmClientConfig): t402Client;
|
|
80
|
+
|
|
81
|
+
export { type Permit2EvmClientConfig, Permit2EvmScheme, registerPermit2EvmScheme };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
|
|
22
|
+
// src/permit2/client/index.ts
|
|
23
|
+
var client_exports = {};
|
|
24
|
+
__export(client_exports, {
|
|
25
|
+
Permit2EvmScheme: () => Permit2EvmScheme,
|
|
26
|
+
registerPermit2EvmScheme: () => registerPermit2EvmScheme
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(client_exports);
|
|
29
|
+
|
|
30
|
+
// src/permit2/client/scheme.ts
|
|
31
|
+
var import_viem = require("viem");
|
|
32
|
+
|
|
33
|
+
// src/permit2/constants.ts
|
|
34
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
35
|
+
var permit2Types = {
|
|
36
|
+
PermitTransferFrom: [
|
|
37
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
38
|
+
{ name: "spender", type: "address" },
|
|
39
|
+
{ name: "nonce", type: "uint256" },
|
|
40
|
+
{ name: "deadline", type: "uint256" }
|
|
41
|
+
],
|
|
42
|
+
TokenPermissions: [
|
|
43
|
+
{ name: "token", type: "address" },
|
|
44
|
+
{ name: "amount", type: "uint256" }
|
|
45
|
+
]
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// src/permit2/client/scheme.ts
|
|
49
|
+
var Permit2EvmScheme = class {
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new Permit2EvmScheme instance.
|
|
52
|
+
*
|
|
53
|
+
* @param signer - The EVM signer for client operations
|
|
54
|
+
*/
|
|
55
|
+
constructor(signer) {
|
|
56
|
+
this.signer = signer;
|
|
57
|
+
__publicField(this, "scheme", "permit2");
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Creates a payment payload for the Permit2 scheme.
|
|
61
|
+
*
|
|
62
|
+
* @param t402Version - The t402 protocol version
|
|
63
|
+
* @param paymentRequirements - The payment requirements
|
|
64
|
+
* @returns Promise resolving to a payment payload
|
|
65
|
+
*/
|
|
66
|
+
async createPaymentPayload(t402Version, paymentRequirements) {
|
|
67
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
68
|
+
const deadline = now + paymentRequirements.maxTimeoutSeconds;
|
|
69
|
+
const nonce = BigInt(
|
|
70
|
+
"0x" + Array.from(globalThis.crypto.getRandomValues(new Uint8Array(32))).map((b) => b.toString(16).padStart(2, "0")).join("")
|
|
71
|
+
).toString();
|
|
72
|
+
const permit = {
|
|
73
|
+
permitted: {
|
|
74
|
+
token: (0, import_viem.getAddress)(paymentRequirements.asset),
|
|
75
|
+
amount: paymentRequirements.amount
|
|
76
|
+
},
|
|
77
|
+
nonce,
|
|
78
|
+
deadline: deadline.toString()
|
|
79
|
+
};
|
|
80
|
+
const transferDetails = {
|
|
81
|
+
to: (0, import_viem.getAddress)(paymentRequirements.payTo),
|
|
82
|
+
requestedAmount: paymentRequirements.amount
|
|
83
|
+
};
|
|
84
|
+
const signature = await this.signPermit2(permit, transferDetails.to, paymentRequirements);
|
|
85
|
+
const payload = {
|
|
86
|
+
permit,
|
|
87
|
+
transferDetails,
|
|
88
|
+
signature,
|
|
89
|
+
owner: this.signer.address
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
t402Version,
|
|
93
|
+
payload
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Sign the Permit2 SignatureTransfer using EIP-712
|
|
98
|
+
*
|
|
99
|
+
* @param permit - The permit transfer data
|
|
100
|
+
* @param spender - The spender address
|
|
101
|
+
* @param requirements - The payment requirements
|
|
102
|
+
* @returns Signed typed data hex string
|
|
103
|
+
*/
|
|
104
|
+
async signPermit2(permit, spender, requirements) {
|
|
105
|
+
const chainId = parseInt(requirements.network.split(":")[1]);
|
|
106
|
+
const domain = {
|
|
107
|
+
name: "Permit2",
|
|
108
|
+
chainId,
|
|
109
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
110
|
+
};
|
|
111
|
+
const message = {
|
|
112
|
+
permitted: {
|
|
113
|
+
token: permit.permitted.token,
|
|
114
|
+
amount: BigInt(permit.permitted.amount)
|
|
115
|
+
},
|
|
116
|
+
spender,
|
|
117
|
+
nonce: BigInt(permit.nonce),
|
|
118
|
+
deadline: BigInt(permit.deadline)
|
|
119
|
+
};
|
|
120
|
+
return await this.signer.signTypedData({
|
|
121
|
+
domain,
|
|
122
|
+
types: permit2Types,
|
|
123
|
+
primaryType: "PermitTransferFrom",
|
|
124
|
+
message
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// src/permit2/client/register.ts
|
|
130
|
+
function registerPermit2EvmScheme(client, config) {
|
|
131
|
+
if (config.networks && config.networks.length > 0) {
|
|
132
|
+
config.networks.forEach((network) => {
|
|
133
|
+
client.register(network, new Permit2EvmScheme(config.signer));
|
|
134
|
+
});
|
|
135
|
+
} else {
|
|
136
|
+
client.register("eip155:*", new Permit2EvmScheme(config.signer));
|
|
137
|
+
}
|
|
138
|
+
if (config.policies) {
|
|
139
|
+
config.policies.forEach((policy) => {
|
|
140
|
+
client.registerPolicy(policy);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return client;
|
|
144
|
+
}
|
|
145
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
146
|
+
0 && (module.exports = {
|
|
147
|
+
Permit2EvmScheme,
|
|
148
|
+
registerPermit2EvmScheme
|
|
149
|
+
});
|
|
150
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/permit2/client/index.ts","../../../../src/permit2/client/scheme.ts","../../../../src/permit2/constants.ts","../../../../src/permit2/client/register.ts"],"sourcesContent":["export { Permit2EvmScheme } from \"./scheme\";\nexport { registerPermit2EvmScheme } from \"./register\";\nexport type { Permit2EvmClientConfig } from \"./register\";\n","import { PaymentPayload, PaymentRequirements, SchemeNetworkClient } from \"@t402/core/types\";\nimport { getAddress } from \"viem\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { Permit2PayloadV2 } from \"../types\";\nimport { PERMIT2_ADDRESS, permit2Types } from \"../constants\";\n\n/**\n * EVM client implementation for the Permit2 payment scheme.\n *\n * Uses Uniswap Permit2 SignatureTransfer for gasless token approvals.\n */\nexport class Permit2EvmScheme implements SchemeNetworkClient {\n readonly scheme = \"permit2\";\n\n /**\n * Creates a new Permit2EvmScheme instance.\n *\n * @param signer - The EVM signer for client operations\n */\n constructor(private readonly signer: ClientEvmSigner) {}\n\n /**\n * Creates a payment payload for the Permit2 scheme.\n *\n * @param t402Version - The t402 protocol version\n * @param paymentRequirements - The payment requirements\n * @returns Promise resolving to a payment payload\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n const now = Math.floor(Date.now() / 1000);\n const deadline = now + paymentRequirements.maxTimeoutSeconds;\n\n // Use a random nonce (Permit2 nonces are not sequential for SignatureTransfer)\n const nonce = BigInt(\n \"0x\" +\n Array.from(globalThis.crypto.getRandomValues(new Uint8Array(32)))\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\"),\n ).toString();\n\n const permit = {\n permitted: {\n token: getAddress(paymentRequirements.asset) as `0x${string}`,\n amount: paymentRequirements.amount,\n },\n nonce,\n deadline: deadline.toString(),\n };\n\n const transferDetails = {\n to: getAddress(paymentRequirements.payTo) as `0x${string}`,\n requestedAmount: paymentRequirements.amount,\n };\n\n // Sign the Permit2 typed data\n const signature = await this.signPermit2(permit, transferDetails.to, paymentRequirements);\n\n const payload: Permit2PayloadV2 = {\n permit,\n transferDetails,\n signature,\n owner: this.signer.address,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n\n /**\n * Sign the Permit2 SignatureTransfer using EIP-712\n *\n * @param permit - The permit transfer data\n * @param spender - The spender address\n * @param requirements - The payment requirements\n * @returns Signed typed data hex string\n */\n private async signPermit2(\n permit: Permit2PayloadV2[\"permit\"],\n spender: `0x${string}`,\n requirements: PaymentRequirements,\n ): Promise<`0x${string}`> {\n const chainId = parseInt(requirements.network.split(\":\")[1]);\n\n const domain = {\n name: \"Permit2\",\n chainId,\n verifyingContract: PERMIT2_ADDRESS,\n };\n\n const message = {\n permitted: {\n token: permit.permitted.token,\n amount: BigInt(permit.permitted.amount),\n },\n spender,\n nonce: BigInt(permit.nonce),\n deadline: BigInt(permit.deadline),\n };\n\n return await this.signer.signTypedData({\n domain,\n types: permit2Types,\n primaryType: \"PermitTransferFrom\",\n message,\n });\n }\n}\n","/**\n * Permit2 Constants\n *\n * Uniswap Permit2 contract addresses, type hashes, and ABI fragments.\n */\n\n/** Canonical Permit2 contract address (same on all EVM chains) */\nexport const PERMIT2_ADDRESS = \"0x000000000022D473030F116dDEE9F6B43aC78BA3\" as const;\n\n/** EIP-712 type definitions for Permit2 SignatureTransfer */\nexport const permit2Types = {\n PermitTransferFrom: [\n { name: \"permitted\", type: \"TokenPermissions\" },\n { name: \"spender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n TokenPermissions: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n} as const;\n\n/** Permit2 ABI for permitTransferFrom */\nexport const permit2ABI = [\n {\n inputs: [\n {\n components: [\n {\n components: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"permitted\",\n type: \"tuple\",\n },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n name: \"permit\",\n type: \"tuple\",\n },\n {\n components: [\n { name: \"to\", type: \"address\" },\n { name: \"requestedAmount\", type: \"uint256\" },\n ],\n name: \"transferDetails\",\n type: \"tuple\",\n },\n { name: \"owner\", type: \"address\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"permitTransferFrom\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/** ERC20 balanceOf ABI for balance checks */\nexport const erc20BalanceABI = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n","import { t402Client, SelectPaymentRequirements, PaymentPolicy } from \"@t402/core/client\";\nimport { Network } from \"@t402/core/types\";\nimport { ClientEvmSigner } from \"../../signer\";\nimport { Permit2EvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering Permit2 EVM schemes to an t402Client\n */\nexport interface Permit2EvmClientConfig {\n /**\n * The EVM signer to use for creating payment payloads\n */\n signer: ClientEvmSigner;\n\n /**\n * Optional payment requirements selector function\n * If not provided, uses the default selector (first available option)\n */\n paymentRequirementsSelector?: SelectPaymentRequirements;\n\n /**\n * Optional policies to apply to the client\n */\n policies?: PaymentPolicy[];\n\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (eip155:*)\n */\n networks?: Network[];\n}\n\n/**\n * Registers Permit2 EVM payment schemes to an t402Client instance.\n *\n * @param client - The t402Client instance to register schemes to\n * @param config - Configuration for Permit2 EVM client registration\n * @returns The client instance for chaining\n *\n * @example\n * ```typescript\n * import { registerPermit2EvmScheme } from \"@t402/evm/permit2/client\";\n * import { t402Client } from \"@t402/core/client\";\n * import { privateKeyToAccount } from \"viem/accounts\";\n *\n * const account = privateKeyToAccount(\"0x...\");\n * const client = new t402Client();\n * registerPermit2EvmScheme(client, { signer: account });\n * ```\n */\nexport function registerPermit2EvmScheme(\n client: t402Client,\n config: Permit2EvmClientConfig,\n): t402Client {\n if (config.networks && config.networks.length > 0) {\n config.networks.forEach(network => {\n client.register(network, new Permit2EvmScheme(config.signer));\n });\n } else {\n client.register(\"eip155:*\", new Permit2EvmScheme(config.signer));\n }\n\n if (config.policies) {\n config.policies.forEach(policy => {\n client.registerPolicy(policy);\n });\n }\n\n return client;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse, Network } from '@t402/core/types';
|
|
2
|
+
import { F as FacilitatorEvmSigner } from '../../signer-DcavxxZt.js';
|
|
3
|
+
import { t402Facilitator } from '@t402/core/facilitator';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Configuration for Permit2 EVM facilitator
|
|
7
|
+
*/
|
|
8
|
+
interface Permit2EvmSchemeConfig {
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* EVM facilitator implementation for the Permit2 payment scheme.
|
|
13
|
+
*
|
|
14
|
+
* Verifies Permit2 signatures and settles payments by calling
|
|
15
|
+
* permitTransferFrom on the Permit2 contract.
|
|
16
|
+
*/
|
|
17
|
+
declare class Permit2EvmScheme implements SchemeNetworkFacilitator {
|
|
18
|
+
private readonly signer;
|
|
19
|
+
readonly scheme = "permit2";
|
|
20
|
+
readonly caipFamily = "eip155:*";
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new Permit2 facilitator instance.
|
|
23
|
+
*
|
|
24
|
+
* @param signer - The facilitator EVM signer
|
|
25
|
+
*/
|
|
26
|
+
constructor(signer: FacilitatorEvmSigner);
|
|
27
|
+
/**
|
|
28
|
+
* Get mechanism-specific extra data for supported kinds.
|
|
29
|
+
*
|
|
30
|
+
* @param _ - The network identifier
|
|
31
|
+
* @returns Extra data including permit2 contract address
|
|
32
|
+
*/
|
|
33
|
+
getExtra(_: string): Record<string, unknown> | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Get signer addresses for this facilitator.
|
|
36
|
+
*
|
|
37
|
+
* @param _ - The network identifier
|
|
38
|
+
* @returns Array of signer addresses
|
|
39
|
+
*/
|
|
40
|
+
getSigners(_: string): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Verify a Permit2 payment payload.
|
|
43
|
+
*
|
|
44
|
+
* @param payload - The payment payload to verify
|
|
45
|
+
* @param requirements - The payment requirements
|
|
46
|
+
* @returns Verification result
|
|
47
|
+
*/
|
|
48
|
+
verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
|
|
49
|
+
/**
|
|
50
|
+
* Settle a Permit2 payment by executing permitTransferFrom.
|
|
51
|
+
*
|
|
52
|
+
* @param payload - The payment payload
|
|
53
|
+
* @param requirements - The payment requirements
|
|
54
|
+
* @returns Settlement result
|
|
55
|
+
*/
|
|
56
|
+
settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Configuration options for registering Permit2 schemes to an t402Facilitator
|
|
61
|
+
*/
|
|
62
|
+
interface Permit2EvmFacilitatorConfig {
|
|
63
|
+
/**
|
|
64
|
+
* The EVM signer for facilitator operations (verify and settle)
|
|
65
|
+
*/
|
|
66
|
+
signer: FacilitatorEvmSigner;
|
|
67
|
+
/**
|
|
68
|
+
* Networks to register (single network or array of networks)
|
|
69
|
+
* Examples: "eip155:84532", ["eip155:84532", "eip155:1"]
|
|
70
|
+
*/
|
|
71
|
+
networks: Network | Network[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Registers Permit2 EVM payment schemes to an t402Facilitator instance.
|
|
75
|
+
*
|
|
76
|
+
* @param facilitator - The t402Facilitator instance to register schemes to
|
|
77
|
+
* @param config - Configuration for Permit2 EVM facilitator registration
|
|
78
|
+
* @returns The facilitator instance for chaining
|
|
79
|
+
*/
|
|
80
|
+
declare function registerPermit2EvmScheme(facilitator: t402Facilitator, config: Permit2EvmFacilitatorConfig): t402Facilitator;
|
|
81
|
+
|
|
82
|
+
export { type Permit2EvmFacilitatorConfig, Permit2EvmScheme, type Permit2EvmSchemeConfig, registerPermit2EvmScheme };
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
|
|
22
|
+
// src/permit2/facilitator/index.ts
|
|
23
|
+
var facilitator_exports = {};
|
|
24
|
+
__export(facilitator_exports, {
|
|
25
|
+
Permit2EvmScheme: () => Permit2EvmScheme,
|
|
26
|
+
registerPermit2EvmScheme: () => registerPermit2EvmScheme
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(facilitator_exports);
|
|
29
|
+
|
|
30
|
+
// src/permit2/facilitator/scheme.ts
|
|
31
|
+
var import_viem = require("viem");
|
|
32
|
+
|
|
33
|
+
// src/permit2/constants.ts
|
|
34
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
35
|
+
var permit2ABI = [
|
|
36
|
+
{
|
|
37
|
+
inputs: [
|
|
38
|
+
{
|
|
39
|
+
components: [
|
|
40
|
+
{
|
|
41
|
+
components: [
|
|
42
|
+
{ name: "token", type: "address" },
|
|
43
|
+
{ name: "amount", type: "uint256" }
|
|
44
|
+
],
|
|
45
|
+
name: "permitted",
|
|
46
|
+
type: "tuple"
|
|
47
|
+
},
|
|
48
|
+
{ name: "nonce", type: "uint256" },
|
|
49
|
+
{ name: "deadline", type: "uint256" }
|
|
50
|
+
],
|
|
51
|
+
name: "permit",
|
|
52
|
+
type: "tuple"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
components: [
|
|
56
|
+
{ name: "to", type: "address" },
|
|
57
|
+
{ name: "requestedAmount", type: "uint256" }
|
|
58
|
+
],
|
|
59
|
+
name: "transferDetails",
|
|
60
|
+
type: "tuple"
|
|
61
|
+
},
|
|
62
|
+
{ name: "owner", type: "address" },
|
|
63
|
+
{ name: "signature", type: "bytes" }
|
|
64
|
+
],
|
|
65
|
+
name: "permitTransferFrom",
|
|
66
|
+
outputs: [],
|
|
67
|
+
stateMutability: "nonpayable",
|
|
68
|
+
type: "function"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
inputs: [{ name: "account", type: "address" }],
|
|
72
|
+
name: "balanceOf",
|
|
73
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
74
|
+
stateMutability: "view",
|
|
75
|
+
type: "function"
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
var erc20BalanceABI = [
|
|
79
|
+
{
|
|
80
|
+
inputs: [{ name: "account", type: "address" }],
|
|
81
|
+
name: "balanceOf",
|
|
82
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
83
|
+
stateMutability: "view",
|
|
84
|
+
type: "function"
|
|
85
|
+
}
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
// src/permit2/facilitator/scheme.ts
|
|
89
|
+
var Permit2EvmScheme = class {
|
|
90
|
+
/**
|
|
91
|
+
* Creates a new Permit2 facilitator instance.
|
|
92
|
+
*
|
|
93
|
+
* @param signer - The facilitator EVM signer
|
|
94
|
+
*/
|
|
95
|
+
constructor(signer) {
|
|
96
|
+
this.signer = signer;
|
|
97
|
+
__publicField(this, "scheme", "permit2");
|
|
98
|
+
__publicField(this, "caipFamily", "eip155:*");
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get mechanism-specific extra data for supported kinds.
|
|
102
|
+
*
|
|
103
|
+
* @param _ - The network identifier
|
|
104
|
+
* @returns Extra data including permit2 contract address
|
|
105
|
+
*/
|
|
106
|
+
getExtra(_) {
|
|
107
|
+
return { permit2Address: PERMIT2_ADDRESS };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get signer addresses for this facilitator.
|
|
111
|
+
*
|
|
112
|
+
* @param _ - The network identifier
|
|
113
|
+
* @returns Array of signer addresses
|
|
114
|
+
*/
|
|
115
|
+
getSigners(_) {
|
|
116
|
+
return [...this.signer.getAddresses()];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Verify a Permit2 payment payload.
|
|
120
|
+
*
|
|
121
|
+
* @param payload - The payment payload to verify
|
|
122
|
+
* @param requirements - The payment requirements
|
|
123
|
+
* @returns Verification result
|
|
124
|
+
*/
|
|
125
|
+
async verify(payload, requirements) {
|
|
126
|
+
const permit2Payload = payload.payload;
|
|
127
|
+
if (!permit2Payload?.permit?.permitted?.token || !permit2Payload?.owner) {
|
|
128
|
+
return {
|
|
129
|
+
isValid: false,
|
|
130
|
+
invalidReason: "invalid_payload_structure",
|
|
131
|
+
payer: void 0
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (payload.accepted.scheme !== "permit2" || requirements.scheme !== "permit2") {
|
|
135
|
+
return {
|
|
136
|
+
isValid: false,
|
|
137
|
+
invalidReason: "unsupported_scheme",
|
|
138
|
+
payer: permit2Payload.owner
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
if (payload.accepted.network !== requirements.network) {
|
|
142
|
+
return {
|
|
143
|
+
isValid: false,
|
|
144
|
+
invalidReason: "network_mismatch",
|
|
145
|
+
payer: permit2Payload.owner
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
if ((0, import_viem.getAddress)(permit2Payload.permit.permitted.token) !== (0, import_viem.getAddress)(requirements.asset)) {
|
|
149
|
+
return {
|
|
150
|
+
isValid: false,
|
|
151
|
+
invalidReason: "token_mismatch",
|
|
152
|
+
payer: permit2Payload.owner
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if ((0, import_viem.getAddress)(permit2Payload.transferDetails.to) !== (0, import_viem.getAddress)(requirements.payTo)) {
|
|
156
|
+
return {
|
|
157
|
+
isValid: false,
|
|
158
|
+
invalidReason: "recipient_mismatch",
|
|
159
|
+
payer: permit2Payload.owner
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
163
|
+
if (BigInt(permit2Payload.permit.deadline) < BigInt(now + 6)) {
|
|
164
|
+
return {
|
|
165
|
+
isValid: false,
|
|
166
|
+
invalidReason: "permit_expired",
|
|
167
|
+
payer: permit2Payload.owner
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (BigInt(permit2Payload.permit.permitted.amount) < BigInt(requirements.amount)) {
|
|
171
|
+
return {
|
|
172
|
+
isValid: false,
|
|
173
|
+
invalidReason: "insufficient_permitted_amount",
|
|
174
|
+
payer: permit2Payload.owner
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (BigInt(permit2Payload.transferDetails.requestedAmount) < BigInt(requirements.amount)) {
|
|
178
|
+
return {
|
|
179
|
+
isValid: false,
|
|
180
|
+
invalidReason: "insufficient_requested_amount",
|
|
181
|
+
payer: permit2Payload.owner
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
const balance = await this.signer.readContract({
|
|
186
|
+
address: (0, import_viem.getAddress)(requirements.asset),
|
|
187
|
+
abi: erc20BalanceABI,
|
|
188
|
+
functionName: "balanceOf",
|
|
189
|
+
args: [(0, import_viem.getAddress)(permit2Payload.owner)]
|
|
190
|
+
});
|
|
191
|
+
if (BigInt(balance) < BigInt(requirements.amount)) {
|
|
192
|
+
return {
|
|
193
|
+
isValid: false,
|
|
194
|
+
invalidReason: "insufficient_funds",
|
|
195
|
+
payer: permit2Payload.owner
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
200
|
+
return {
|
|
201
|
+
isValid: false,
|
|
202
|
+
invalidReason: `balance_check_failed: ${errorMessage}`,
|
|
203
|
+
payer: permit2Payload.owner
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
isValid: true,
|
|
208
|
+
invalidReason: void 0,
|
|
209
|
+
payer: permit2Payload.owner
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Settle a Permit2 payment by executing permitTransferFrom.
|
|
214
|
+
*
|
|
215
|
+
* @param payload - The payment payload
|
|
216
|
+
* @param requirements - The payment requirements
|
|
217
|
+
* @returns Settlement result
|
|
218
|
+
*/
|
|
219
|
+
async settle(payload, requirements) {
|
|
220
|
+
const permit2Payload = payload.payload;
|
|
221
|
+
if (!permit2Payload?.permit?.permitted?.token || !permit2Payload?.owner) {
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
network: payload.accepted.network,
|
|
225
|
+
transaction: "",
|
|
226
|
+
errorReason: "invalid_payload_structure",
|
|
227
|
+
payer: void 0
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
const valid = await this.verify(payload, requirements);
|
|
231
|
+
if (!valid.isValid) {
|
|
232
|
+
return {
|
|
233
|
+
success: false,
|
|
234
|
+
network: payload.accepted.network,
|
|
235
|
+
transaction: "",
|
|
236
|
+
errorReason: valid.invalidReason ?? "invalid_scheme",
|
|
237
|
+
payer: permit2Payload.owner
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
const tx = await this.signer.writeContract({
|
|
242
|
+
address: PERMIT2_ADDRESS,
|
|
243
|
+
abi: permit2ABI,
|
|
244
|
+
functionName: "permitTransferFrom",
|
|
245
|
+
args: [
|
|
246
|
+
{
|
|
247
|
+
permitted: {
|
|
248
|
+
token: (0, import_viem.getAddress)(permit2Payload.permit.permitted.token),
|
|
249
|
+
amount: BigInt(permit2Payload.permit.permitted.amount)
|
|
250
|
+
},
|
|
251
|
+
nonce: BigInt(permit2Payload.permit.nonce),
|
|
252
|
+
deadline: BigInt(permit2Payload.permit.deadline)
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
to: (0, import_viem.getAddress)(permit2Payload.transferDetails.to),
|
|
256
|
+
requestedAmount: BigInt(permit2Payload.transferDetails.requestedAmount)
|
|
257
|
+
},
|
|
258
|
+
(0, import_viem.getAddress)(permit2Payload.owner),
|
|
259
|
+
permit2Payload.signature
|
|
260
|
+
]
|
|
261
|
+
});
|
|
262
|
+
const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });
|
|
263
|
+
if (receipt.status !== "success") {
|
|
264
|
+
return {
|
|
265
|
+
success: false,
|
|
266
|
+
errorReason: "invalid_transaction_state",
|
|
267
|
+
transaction: tx,
|
|
268
|
+
network: payload.accepted.network,
|
|
269
|
+
payer: permit2Payload.owner
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
success: true,
|
|
274
|
+
transaction: tx,
|
|
275
|
+
network: payload.accepted.network,
|
|
276
|
+
payer: permit2Payload.owner
|
|
277
|
+
};
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error("Failed to settle Permit2 transaction:", error);
|
|
280
|
+
return {
|
|
281
|
+
success: false,
|
|
282
|
+
errorReason: "transaction_failed",
|
|
283
|
+
transaction: "",
|
|
284
|
+
network: payload.accepted.network,
|
|
285
|
+
payer: permit2Payload.owner
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/permit2/facilitator/register.ts
|
|
292
|
+
function registerPermit2EvmScheme(facilitator, config) {
|
|
293
|
+
facilitator.register(config.networks, new Permit2EvmScheme(config.signer));
|
|
294
|
+
return facilitator;
|
|
295
|
+
}
|
|
296
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
297
|
+
0 && (module.exports = {
|
|
298
|
+
Permit2EvmScheme,
|
|
299
|
+
registerPermit2EvmScheme
|
|
300
|
+
});
|
|
301
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/permit2/facilitator/index.ts","../../../../src/permit2/facilitator/scheme.ts","../../../../src/permit2/constants.ts","../../../../src/permit2/facilitator/register.ts"],"sourcesContent":["export { Permit2EvmScheme } from \"./scheme\";\nexport type { Permit2EvmSchemeConfig } from \"./scheme\";\nexport { registerPermit2EvmScheme } from \"./register\";\nexport type { Permit2EvmFacilitatorConfig } from \"./register\";\n","import {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@t402/core/types\";\nimport { getAddress } from \"viem\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { Permit2PayloadV2 } from \"../types\";\nimport { PERMIT2_ADDRESS, permit2ABI, erc20BalanceABI } from \"../constants\";\n\n/**\n * Configuration for Permit2 EVM facilitator\n */\nexport interface Permit2EvmSchemeConfig {\n [key: string]: unknown;\n}\n\n/**\n * EVM facilitator implementation for the Permit2 payment scheme.\n *\n * Verifies Permit2 signatures and settles payments by calling\n * permitTransferFrom on the Permit2 contract.\n */\nexport class Permit2EvmScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"permit2\";\n readonly caipFamily = \"eip155:*\";\n\n /**\n * Creates a new Permit2 facilitator instance.\n *\n * @param signer - The facilitator EVM signer\n */\n constructor(private readonly signer: FacilitatorEvmSigner) {}\n\n /**\n * Get mechanism-specific extra data for supported kinds.\n *\n * @param _ - The network identifier\n * @returns Extra data including permit2 contract address\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n return { permit2Address: PERMIT2_ADDRESS };\n }\n\n /**\n * Get signer addresses for this facilitator.\n *\n * @param _ - The network identifier\n * @returns Array of signer addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verify a Permit2 payment payload.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Verification result\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n const permit2Payload = payload.payload as Permit2PayloadV2 | undefined;\n\n // Validate payload structure\n if (!permit2Payload?.permit?.permitted?.token || !permit2Payload?.owner) {\n return {\n isValid: false,\n invalidReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Verify scheme matches\n if (payload.accepted.scheme !== \"permit2\" || requirements.scheme !== \"permit2\") {\n return {\n isValid: false,\n invalidReason: \"unsupported_scheme\",\n payer: permit2Payload.owner,\n };\n }\n\n // Verify network matches\n if (payload.accepted.network !== requirements.network) {\n return {\n isValid: false,\n invalidReason: \"network_mismatch\",\n payer: permit2Payload.owner,\n };\n }\n\n // Verify token matches\n if (getAddress(permit2Payload.permit.permitted.token) !== getAddress(requirements.asset)) {\n return {\n isValid: false,\n invalidReason: \"token_mismatch\",\n payer: permit2Payload.owner,\n };\n }\n\n // Verify recipient matches\n if (getAddress(permit2Payload.transferDetails.to) !== getAddress(requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: \"recipient_mismatch\",\n payer: permit2Payload.owner,\n };\n }\n\n // Verify deadline is in the future\n const now = Math.floor(Date.now() / 1000);\n if (BigInt(permit2Payload.permit.deadline) < BigInt(now + 6)) {\n return {\n isValid: false,\n invalidReason: \"permit_expired\",\n payer: permit2Payload.owner,\n };\n }\n\n // Verify amount is sufficient\n if (BigInt(permit2Payload.permit.permitted.amount) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_permitted_amount\",\n payer: permit2Payload.owner,\n };\n }\n\n if (BigInt(permit2Payload.transferDetails.requestedAmount) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_requested_amount\",\n payer: permit2Payload.owner,\n };\n }\n\n // Check balance\n try {\n const balance = (await this.signer.readContract({\n address: getAddress(requirements.asset),\n abi: erc20BalanceABI,\n functionName: \"balanceOf\",\n args: [getAddress(permit2Payload.owner)],\n })) as bigint;\n\n if (BigInt(balance) < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"insufficient_funds\",\n payer: permit2Payload.owner,\n };\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n isValid: false,\n invalidReason: `balance_check_failed: ${errorMessage}`,\n payer: permit2Payload.owner,\n };\n }\n\n return {\n isValid: true,\n invalidReason: undefined,\n payer: permit2Payload.owner,\n };\n }\n\n /**\n * Settle a Permit2 payment by executing permitTransferFrom.\n *\n * @param payload - The payment payload\n * @param requirements - The payment requirements\n * @returns Settlement result\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const permit2Payload = payload.payload as Permit2PayloadV2 | undefined;\n\n if (!permit2Payload?.permit?.permitted?.token || !permit2Payload?.owner) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: \"invalid_payload_structure\",\n payer: undefined,\n };\n }\n\n // Re-verify before settling\n const valid = await this.verify(payload, requirements);\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"invalid_scheme\",\n payer: permit2Payload.owner,\n };\n }\n\n try {\n // Call permitTransferFrom on the Permit2 contract\n const tx = await this.signer.writeContract({\n address: PERMIT2_ADDRESS,\n abi: permit2ABI,\n functionName: \"permitTransferFrom\",\n args: [\n {\n permitted: {\n token: getAddress(permit2Payload.permit.permitted.token),\n amount: BigInt(permit2Payload.permit.permitted.amount),\n },\n nonce: BigInt(permit2Payload.permit.nonce),\n deadline: BigInt(permit2Payload.permit.deadline),\n },\n {\n to: getAddress(permit2Payload.transferDetails.to),\n requestedAmount: BigInt(permit2Payload.transferDetails.requestedAmount),\n },\n getAddress(permit2Payload.owner),\n permit2Payload.signature,\n ],\n });\n\n // Wait for transaction confirmation\n const receipt = await this.signer.waitForTransactionReceipt({ hash: tx });\n\n if (receipt.status !== \"success\") {\n return {\n success: false,\n errorReason: \"invalid_transaction_state\",\n transaction: tx,\n network: payload.accepted.network,\n payer: permit2Payload.owner,\n };\n }\n\n return {\n success: true,\n transaction: tx,\n network: payload.accepted.network,\n payer: permit2Payload.owner,\n };\n } catch (error) {\n console.error(\"Failed to settle Permit2 transaction:\", error);\n return {\n success: false,\n errorReason: \"transaction_failed\",\n transaction: \"\",\n network: payload.accepted.network,\n payer: permit2Payload.owner,\n };\n }\n }\n}\n","/**\n * Permit2 Constants\n *\n * Uniswap Permit2 contract addresses, type hashes, and ABI fragments.\n */\n\n/** Canonical Permit2 contract address (same on all EVM chains) */\nexport const PERMIT2_ADDRESS = \"0x000000000022D473030F116dDEE9F6B43aC78BA3\" as const;\n\n/** EIP-712 type definitions for Permit2 SignatureTransfer */\nexport const permit2Types = {\n PermitTransferFrom: [\n { name: \"permitted\", type: \"TokenPermissions\" },\n { name: \"spender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n TokenPermissions: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n} as const;\n\n/** Permit2 ABI for permitTransferFrom */\nexport const permit2ABI = [\n {\n inputs: [\n {\n components: [\n {\n components: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n name: \"permitted\",\n type: \"tuple\",\n },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n name: \"permit\",\n type: \"tuple\",\n },\n {\n components: [\n { name: \"to\", type: \"address\" },\n { name: \"requestedAmount\", type: \"uint256\" },\n ],\n name: \"transferDetails\",\n type: \"tuple\",\n },\n { name: \"owner\", type: \"address\" },\n { name: \"signature\", type: \"bytes\" },\n ],\n name: \"permitTransferFrom\",\n outputs: [],\n stateMutability: \"nonpayable\",\n type: \"function\",\n },\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n\n/** ERC20 balanceOf ABI for balance checks */\nexport const erc20BalanceABI = [\n {\n inputs: [{ name: \"account\", type: \"address\" }],\n name: \"balanceOf\",\n outputs: [{ name: \"\", type: \"uint256\" }],\n stateMutability: \"view\",\n type: \"function\",\n },\n] as const;\n","import { t402Facilitator } from \"@t402/core/facilitator\";\nimport { Network } from \"@t402/core/types\";\nimport { FacilitatorEvmSigner } from \"../../signer\";\nimport { Permit2EvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering Permit2 schemes to an t402Facilitator\n */\nexport interface Permit2EvmFacilitatorConfig {\n /**\n * The EVM signer for facilitator operations (verify and settle)\n */\n signer: FacilitatorEvmSigner;\n\n /**\n * Networks to register (single network or array of networks)\n * Examples: \"eip155:84532\", [\"eip155:84532\", \"eip155:1\"]\n */\n networks: Network | Network[];\n}\n\n/**\n * Registers Permit2 EVM payment schemes to an t402Facilitator instance.\n *\n * @param facilitator - The t402Facilitator instance to register schemes to\n * @param config - Configuration for Permit2 EVM facilitator registration\n * @returns The facilitator instance for chaining\n */\nexport function registerPermit2EvmScheme(\n facilitator: t402Facilitator,\n config: Permit2EvmFacilitatorConfig,\n): t402Facilitator {\n facilitator.register(config.networks, new Permit2EvmScheme(config.signer));\n\n return facilitator;\n}\n"],"mappings":"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","names":[]}
|