moltspay 0.5.3 → 0.7.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.
Files changed (67) hide show
  1. package/dist/cdp/index.d.mts +111 -0
  2. package/dist/cdp/index.d.ts +111 -0
  3. package/dist/cdp/index.js +30655 -0
  4. package/dist/cdp/index.js.map +1 -0
  5. package/dist/cdp/index.mjs +30631 -0
  6. package/dist/cdp/index.mjs.map +1 -0
  7. package/dist/chains/index.d.mts +1 -1
  8. package/dist/chains/index.d.ts +1 -1
  9. package/dist/cli/index.js +940 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/index.mjs +917 -0
  12. package/dist/cli/index.mjs.map +1 -0
  13. package/dist/client/index.d.mts +134 -0
  14. package/dist/client/index.d.ts +134 -0
  15. package/dist/client/index.js +331 -0
  16. package/dist/client/index.js.map +1 -0
  17. package/dist/client/index.mjs +296 -0
  18. package/dist/client/index.mjs.map +1 -0
  19. package/dist/createWallet-D53qu7ie.d.mts +77 -0
  20. package/dist/createWallet-D53qu7ie.d.ts +77 -0
  21. package/dist/index-Dg8n6wdW.d.mts +32 -0
  22. package/dist/index-Dg8n6wdW.d.ts +32 -0
  23. package/dist/index.d.mts +6 -937
  24. package/dist/index.d.ts +6 -937
  25. package/dist/index.js +31023 -3250
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +30998 -3178
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/server/index.d.mts +120 -0
  30. package/dist/server/index.d.ts +120 -0
  31. package/dist/server/index.js +418 -0
  32. package/dist/server/index.js.map +1 -0
  33. package/dist/server/index.mjs +393 -0
  34. package/dist/server/index.mjs.map +1 -0
  35. package/dist/wallet/index.d.mts +3 -451
  36. package/dist/wallet/index.d.ts +3 -451
  37. package/dist/wallet/index.js +5 -1021
  38. package/dist/wallet/index.js.map +1 -1
  39. package/dist/wallet/index.mjs +16 -1015
  40. package/dist/wallet/index.mjs.map +1 -1
  41. package/package.json +19 -19
  42. package/dist/cli.js +0 -1984
  43. package/dist/cli.js.map +0 -1
  44. package/dist/cli.mjs +0 -1969
  45. package/dist/cli.mjs.map +0 -1
  46. package/dist/guide/index.d.mts +0 -39
  47. package/dist/guide/index.d.ts +0 -39
  48. package/dist/guide/index.js +0 -181
  49. package/dist/guide/index.js.map +0 -1
  50. package/dist/guide/index.mjs +0 -152
  51. package/dist/guide/index.mjs.map +0 -1
  52. package/dist/index-CyFg9s2m.d.mts +0 -161
  53. package/dist/index-CyFg9s2m.d.ts +0 -161
  54. package/dist/orders/index.d.mts +0 -97
  55. package/dist/orders/index.d.ts +0 -97
  56. package/dist/orders/index.js +0 -162
  57. package/dist/orders/index.js.map +0 -1
  58. package/dist/orders/index.mjs +0 -136
  59. package/dist/orders/index.mjs.map +0 -1
  60. package/dist/permit/index.d.mts +0 -49
  61. package/dist/permit/index.d.ts +0 -49
  62. package/dist/permit/index.js +0 -273
  63. package/dist/permit/index.js.map +0 -1
  64. package/dist/permit/index.mjs +0 -246
  65. package/dist/permit/index.mjs.map +0 -1
  66. /package/dist/{cli.d.mts → cli/index.d.mts} +0 -0
  67. /package/dist/{cli.d.ts → cli/index.d.ts} +0 -0
@@ -1,273 +0,0 @@
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 __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/permit/index.ts
21
- var permit_exports = {};
22
- __export(permit_exports, {
23
- PermitPayment: () => PermitPayment
24
- });
25
- module.exports = __toCommonJS(permit_exports);
26
-
27
- // src/permit/Permit.ts
28
- var import_ethers = require("ethers");
29
-
30
- // src/chains/index.ts
31
- var CHAINS = {
32
- // ============ Mainnet ============
33
- base: {
34
- name: "Base",
35
- chainId: 8453,
36
- rpc: "https://mainnet.base.org",
37
- usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
38
- explorer: "https://basescan.org/address/",
39
- explorerTx: "https://basescan.org/tx/",
40
- avgBlockTime: 2
41
- },
42
- polygon: {
43
- name: "Polygon",
44
- chainId: 137,
45
- rpc: "https://polygon-rpc.com",
46
- usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
47
- explorer: "https://polygonscan.com/address/",
48
- explorerTx: "https://polygonscan.com/tx/",
49
- avgBlockTime: 2
50
- },
51
- ethereum: {
52
- name: "Ethereum",
53
- chainId: 1,
54
- rpc: "https://eth.llamarpc.com",
55
- usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
56
- explorer: "https://etherscan.io/address/",
57
- explorerTx: "https://etherscan.io/tx/",
58
- avgBlockTime: 12
59
- },
60
- // ============ Testnet ============
61
- base_sepolia: {
62
- name: "Base Sepolia",
63
- chainId: 84532,
64
- rpc: "https://sepolia.base.org",
65
- usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
66
- explorer: "https://sepolia.basescan.org/address/",
67
- explorerTx: "https://sepolia.basescan.org/tx/",
68
- avgBlockTime: 2
69
- },
70
- sepolia: {
71
- name: "Sepolia",
72
- chainId: 11155111,
73
- rpc: "https://rpc.sepolia.org",
74
- usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
75
- explorer: "https://sepolia.etherscan.io/address/",
76
- explorerTx: "https://sepolia.etherscan.io/tx/",
77
- avgBlockTime: 12
78
- }
79
- };
80
- function getChain(name) {
81
- const config = CHAINS[name];
82
- if (!config) {
83
- throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(", ")}`);
84
- }
85
- return config;
86
- }
87
- var ERC20_ABI = [
88
- "function balanceOf(address owner) view returns (uint256)",
89
- "function transfer(address to, uint256 amount) returns (bool)",
90
- "function approve(address spender, uint256 amount) returns (bool)",
91
- "function allowance(address owner, address spender) view returns (uint256)",
92
- "function decimals() view returns (uint8)",
93
- "function symbol() view returns (string)",
94
- "function name() view returns (string)",
95
- "function nonces(address owner) view returns (uint256)",
96
- "function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
97
- "event Transfer(address indexed from, address indexed to, uint256 value)",
98
- "event Approval(address indexed owner, address indexed spender, uint256 value)"
99
- ];
100
-
101
- // src/permit/Permit.ts
102
- var PermitPayment = class {
103
- chain;
104
- chainConfig;
105
- spenderAddress;
106
- provider;
107
- wallet;
108
- usdcContract;
109
- constructor(config = {}) {
110
- this.chain = config.chain || "base_sepolia";
111
- this.chainConfig = getChain(this.chain);
112
- this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || "";
113
- const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
114
- this.provider = new import_ethers.ethers.JsonRpcProvider(rpcUrl);
115
- const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
116
- if (privateKey) {
117
- this.wallet = new import_ethers.ethers.Wallet(privateKey, this.provider);
118
- this.spenderAddress = this.wallet.address;
119
- }
120
- this.usdcContract = new import_ethers.ethers.Contract(
121
- this.chainConfig.usdc,
122
- ERC20_ABI,
123
- this.wallet || this.provider
124
- );
125
- }
126
- /**
127
- * Get user current nonce
128
- */
129
- async getNonce(owner) {
130
- return Number(await this.usdcContract.nonces(owner));
131
- }
132
- /**
133
- * Generate EIP-712 signing request (for frontend/user wallet)
134
- */
135
- async createPermitRequest(owner, amount, orderId, deadlineMinutes = 30) {
136
- const nonce = await this.getNonce(owner);
137
- const deadline = Math.floor(Date.now() / 1e3) + deadlineMinutes * 60;
138
- const value = BigInt(Math.floor(amount * 1e6)).toString();
139
- const domain = {
140
- name: "USD Coin",
141
- version: "2",
142
- chainId: this.chainConfig.chainId,
143
- verifyingContract: this.chainConfig.usdc
144
- };
145
- const types = {
146
- EIP712Domain: [
147
- { name: "name", type: "string" },
148
- { name: "version", type: "string" },
149
- { name: "chainId", type: "uint256" },
150
- { name: "verifyingContract", type: "address" }
151
- ],
152
- Permit: [
153
- { name: "owner", type: "address" },
154
- { name: "spender", type: "address" },
155
- { name: "value", type: "uint256" },
156
- { name: "nonce", type: "uint256" },
157
- { name: "deadline", type: "uint256" }
158
- ]
159
- };
160
- const message = {
161
- owner,
162
- spender: this.spenderAddress,
163
- value,
164
- nonce,
165
- deadline
166
- };
167
- const typedData = {
168
- types,
169
- primaryType: "Permit",
170
- domain,
171
- message
172
- };
173
- return {
174
- type: "permit_request",
175
- version: "1.0",
176
- order_id: orderId,
177
- typed_data: typedData
178
- };
179
- }
180
- /**
181
- * Execute permit + transferFrom
182
- *
183
- * @param owner User address
184
- * @param amount Amount
185
- * @param signature User signature {v, r, s, deadline}
186
- */
187
- async executePermitAndTransfer(owner, amount, signature) {
188
- if (!this.wallet) {
189
- return { success: false, error: "Wallet not configured. Private key required." };
190
- }
191
- try {
192
- const value = BigInt(Math.floor(amount * 1e6));
193
- const permitTx = await this.usdcContract.permit(
194
- owner,
195
- this.spenderAddress,
196
- value,
197
- signature.deadline,
198
- signature.v,
199
- signature.r,
200
- signature.s
201
- );
202
- await permitTx.wait();
203
- const transferTx = await this.usdcContract.transferFrom(owner, this.spenderAddress, value);
204
- const receipt = await transferTx.wait();
205
- return {
206
- success: receipt.status === 1,
207
- tx_hash: transferTx.hash
208
- };
209
- } catch (error) {
210
- return {
211
- success: false,
212
- error: error.message
213
- };
214
- }
215
- }
216
- /**
217
- * Execute permit only (no transfer)
218
- */
219
- async executePermit(owner, amount, signature) {
220
- if (!this.wallet) {
221
- return { success: false, error: "Wallet not configured. Private key required." };
222
- }
223
- try {
224
- const value = BigInt(Math.floor(amount * 1e6));
225
- const tx = await this.usdcContract.permit(
226
- owner,
227
- this.spenderAddress,
228
- value,
229
- signature.deadline,
230
- signature.v,
231
- signature.r,
232
- signature.s
233
- );
234
- const receipt = await tx.wait();
235
- return {
236
- success: receipt.status === 1,
237
- tx_hash: tx.hash
238
- };
239
- } catch (error) {
240
- return {
241
- success: false,
242
- error: error.message
243
- };
244
- }
245
- }
246
- /**
247
- * Format Permit request as user message
248
- */
249
- formatPermitMessage(request) {
250
- const { typed_data } = request;
251
- const { message } = typed_data;
252
- return `\u{1F510} **Signature Authorization Request**
253
-
254
- Authorize \`${(Number(message.value) / 1e6).toFixed(2)} USDC\` to service provider
255
-
256
- **Signature Details:**
257
- - Owner: \`${message.owner}\`
258
- - Spender: \`${message.spender}\`
259
- - Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC
260
- - Deadline: ${new Date(message.deadline * 1e3).toISOString()}
261
-
262
- Please sign this request in your wallet (no gas required).
263
-
264
- \`\`\`json
265
- ${JSON.stringify(typed_data, null, 2)}
266
- \`\`\``;
267
- }
268
- };
269
- // Annotate the CommonJS export names for ESM import in node:
270
- 0 && (module.exports = {
271
- PermitPayment
272
- });
273
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/permit/index.ts","../../src/permit/Permit.ts","../../src/chains/index.ts"],"sourcesContent":["export { PermitPayment, type PermitConfig } from './Permit.js';\n","/**\n * PermitPayment - EIP-2612 Gasless Pre-authorization\n * \n * User signs authorization, service provider pays gas to execute transferFrom\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n PermitRequest,\n PermitSignature,\n PermitExecuteResult,\n EIP712TypedData,\n} from '../types/index.js';\n\nexport interface PermitConfig {\n chain?: ChainName;\n privateKey?: string;\n spenderAddress?: string;\n rpcUrl?: string;\n}\n\nexport class PermitPayment {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly spenderAddress: string;\n \n private provider: ethers.JsonRpcProvider;\n private wallet?: ethers.Wallet;\n private usdcContract: ethers.Contract;\n\n constructor(config: PermitConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || '';\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (privateKey) {\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.spenderAddress = this.wallet.address;\n }\n\n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.wallet || this.provider\n );\n }\n\n /**\n * Get user current nonce\n */\n async getNonce(owner: string): Promise<number> {\n return Number(await this.usdcContract.nonces(owner));\n }\n\n /**\n * Generate EIP-712 signing request (for frontend/user wallet)\n */\n async createPermitRequest(\n owner: string,\n amount: number,\n orderId: string,\n deadlineMinutes: number = 30\n ): Promise<PermitRequest> {\n const nonce = await this.getNonce(owner);\n const deadline = Math.floor(Date.now() / 1000) + deadlineMinutes * 60;\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n // USDC EIP-712 domain (may differ by chain)\n const domain = {\n name: 'USD Coin',\n version: '2',\n chainId: this.chainConfig.chainId,\n verifyingContract: this.chainConfig.usdc,\n };\n\n const types = {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n const message = {\n owner,\n spender: this.spenderAddress,\n value,\n nonce,\n deadline,\n };\n\n const typedData: EIP712TypedData = {\n types,\n primaryType: 'Permit',\n domain,\n message,\n };\n\n return {\n type: 'permit_request',\n version: '1.0',\n order_id: orderId,\n typed_data: typedData,\n };\n }\n\n /**\n * Execute permit + transferFrom\n * \n * @param owner User address\n * @param amount Amount\n * @param signature User signature {v, r, s, deadline}\n */\n async executePermitAndTransfer(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n // 1. Call permit\n const permitTx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n await permitTx.wait();\n\n // 2. Call transferFrom\n const transferTx = await this.usdcContract.transferFrom(owner, this.spenderAddress, value);\n const receipt = await transferTx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: transferTx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Execute permit only (no transfer)\n */\n async executePermit(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n const tx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: tx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Format Permit request as user message\n */\n formatPermitMessage(request: PermitRequest): string {\n const { typed_data } = request;\n const { message } = typed_data;\n\n return `🔐 **Signature Authorization Request**\n\nAuthorize \\`${(Number(message.value) / 1e6).toFixed(2)} USDC\\` to service provider\n\n**Signature Details:**\n- Owner: \\`${message.owner}\\`\n- Spender: \\`${message.spender}\\`\n- Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC\n- Deadline: ${new Date(message.deadline * 1000).toISOString()}\n\nPlease sign this request in your wallet (no gas required).\n\n\\`\\`\\`json\n${JSON.stringify(typed_data, null, 2)}\n\\`\\`\\``;\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName } from '../types/index.js';\n\nexport const CHAINS: Record<ChainName, ChainConfig> = {\n // ============ Mainnet ============\n base: {\n name: 'Base',\n chainId: 8453,\n rpc: 'https://mainnet.base.org',\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n explorer: 'https://basescan.org/address/',\n explorerTx: 'https://basescan.org/tx/',\n avgBlockTime: 2,\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n rpc: 'https://polygon-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\n};\n\n/**\n * Get chain configuration\n */\nexport function getChain(name: ChainName): ChainConfig {\n const config = CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * List all supported chains\n */\nexport function listChains(): ChainName[] {\n return Object.keys(CHAINS) as ChainName[];\n}\n\n/**\n * Get chain config by chainId\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(CHAINS).find(c => c.chainId === chainId);\n}\n\n/**\n * ERC20 ABI (minimal, only required methods)\n */\nexport const ERC20_ABI = [\n 'function balanceOf(address owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n 'function symbol() view returns (string)',\n 'function name() view returns (string)',\n 'function nonces(address owner) view returns (uint256)',\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n];\n\nexport type { ChainConfig, ChainName };\n"],"mappings":"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","names":[]}
@@ -1,246 +0,0 @@
1
- // src/permit/Permit.ts
2
- import { ethers } from "ethers";
3
-
4
- // src/chains/index.ts
5
- var CHAINS = {
6
- // ============ Mainnet ============
7
- base: {
8
- name: "Base",
9
- chainId: 8453,
10
- rpc: "https://mainnet.base.org",
11
- usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
12
- explorer: "https://basescan.org/address/",
13
- explorerTx: "https://basescan.org/tx/",
14
- avgBlockTime: 2
15
- },
16
- polygon: {
17
- name: "Polygon",
18
- chainId: 137,
19
- rpc: "https://polygon-rpc.com",
20
- usdc: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
21
- explorer: "https://polygonscan.com/address/",
22
- explorerTx: "https://polygonscan.com/tx/",
23
- avgBlockTime: 2
24
- },
25
- ethereum: {
26
- name: "Ethereum",
27
- chainId: 1,
28
- rpc: "https://eth.llamarpc.com",
29
- usdc: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
30
- explorer: "https://etherscan.io/address/",
31
- explorerTx: "https://etherscan.io/tx/",
32
- avgBlockTime: 12
33
- },
34
- // ============ Testnet ============
35
- base_sepolia: {
36
- name: "Base Sepolia",
37
- chainId: 84532,
38
- rpc: "https://sepolia.base.org",
39
- usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
40
- explorer: "https://sepolia.basescan.org/address/",
41
- explorerTx: "https://sepolia.basescan.org/tx/",
42
- avgBlockTime: 2
43
- },
44
- sepolia: {
45
- name: "Sepolia",
46
- chainId: 11155111,
47
- rpc: "https://rpc.sepolia.org",
48
- usdc: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
49
- explorer: "https://sepolia.etherscan.io/address/",
50
- explorerTx: "https://sepolia.etherscan.io/tx/",
51
- avgBlockTime: 12
52
- }
53
- };
54
- function getChain(name) {
55
- const config = CHAINS[name];
56
- if (!config) {
57
- throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(", ")}`);
58
- }
59
- return config;
60
- }
61
- var ERC20_ABI = [
62
- "function balanceOf(address owner) view returns (uint256)",
63
- "function transfer(address to, uint256 amount) returns (bool)",
64
- "function approve(address spender, uint256 amount) returns (bool)",
65
- "function allowance(address owner, address spender) view returns (uint256)",
66
- "function decimals() view returns (uint8)",
67
- "function symbol() view returns (string)",
68
- "function name() view returns (string)",
69
- "function nonces(address owner) view returns (uint256)",
70
- "function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)",
71
- "event Transfer(address indexed from, address indexed to, uint256 value)",
72
- "event Approval(address indexed owner, address indexed spender, uint256 value)"
73
- ];
74
-
75
- // src/permit/Permit.ts
76
- var PermitPayment = class {
77
- chain;
78
- chainConfig;
79
- spenderAddress;
80
- provider;
81
- wallet;
82
- usdcContract;
83
- constructor(config = {}) {
84
- this.chain = config.chain || "base_sepolia";
85
- this.chainConfig = getChain(this.chain);
86
- this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || "";
87
- const rpcUrl = config.rpcUrl || this.chainConfig.rpc;
88
- this.provider = new ethers.JsonRpcProvider(rpcUrl);
89
- const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;
90
- if (privateKey) {
91
- this.wallet = new ethers.Wallet(privateKey, this.provider);
92
- this.spenderAddress = this.wallet.address;
93
- }
94
- this.usdcContract = new ethers.Contract(
95
- this.chainConfig.usdc,
96
- ERC20_ABI,
97
- this.wallet || this.provider
98
- );
99
- }
100
- /**
101
- * Get user current nonce
102
- */
103
- async getNonce(owner) {
104
- return Number(await this.usdcContract.nonces(owner));
105
- }
106
- /**
107
- * Generate EIP-712 signing request (for frontend/user wallet)
108
- */
109
- async createPermitRequest(owner, amount, orderId, deadlineMinutes = 30) {
110
- const nonce = await this.getNonce(owner);
111
- const deadline = Math.floor(Date.now() / 1e3) + deadlineMinutes * 60;
112
- const value = BigInt(Math.floor(amount * 1e6)).toString();
113
- const domain = {
114
- name: "USD Coin",
115
- version: "2",
116
- chainId: this.chainConfig.chainId,
117
- verifyingContract: this.chainConfig.usdc
118
- };
119
- const types = {
120
- EIP712Domain: [
121
- { name: "name", type: "string" },
122
- { name: "version", type: "string" },
123
- { name: "chainId", type: "uint256" },
124
- { name: "verifyingContract", type: "address" }
125
- ],
126
- Permit: [
127
- { name: "owner", type: "address" },
128
- { name: "spender", type: "address" },
129
- { name: "value", type: "uint256" },
130
- { name: "nonce", type: "uint256" },
131
- { name: "deadline", type: "uint256" }
132
- ]
133
- };
134
- const message = {
135
- owner,
136
- spender: this.spenderAddress,
137
- value,
138
- nonce,
139
- deadline
140
- };
141
- const typedData = {
142
- types,
143
- primaryType: "Permit",
144
- domain,
145
- message
146
- };
147
- return {
148
- type: "permit_request",
149
- version: "1.0",
150
- order_id: orderId,
151
- typed_data: typedData
152
- };
153
- }
154
- /**
155
- * Execute permit + transferFrom
156
- *
157
- * @param owner User address
158
- * @param amount Amount
159
- * @param signature User signature {v, r, s, deadline}
160
- */
161
- async executePermitAndTransfer(owner, amount, signature) {
162
- if (!this.wallet) {
163
- return { success: false, error: "Wallet not configured. Private key required." };
164
- }
165
- try {
166
- const value = BigInt(Math.floor(amount * 1e6));
167
- const permitTx = await this.usdcContract.permit(
168
- owner,
169
- this.spenderAddress,
170
- value,
171
- signature.deadline,
172
- signature.v,
173
- signature.r,
174
- signature.s
175
- );
176
- await permitTx.wait();
177
- const transferTx = await this.usdcContract.transferFrom(owner, this.spenderAddress, value);
178
- const receipt = await transferTx.wait();
179
- return {
180
- success: receipt.status === 1,
181
- tx_hash: transferTx.hash
182
- };
183
- } catch (error) {
184
- return {
185
- success: false,
186
- error: error.message
187
- };
188
- }
189
- }
190
- /**
191
- * Execute permit only (no transfer)
192
- */
193
- async executePermit(owner, amount, signature) {
194
- if (!this.wallet) {
195
- return { success: false, error: "Wallet not configured. Private key required." };
196
- }
197
- try {
198
- const value = BigInt(Math.floor(amount * 1e6));
199
- const tx = await this.usdcContract.permit(
200
- owner,
201
- this.spenderAddress,
202
- value,
203
- signature.deadline,
204
- signature.v,
205
- signature.r,
206
- signature.s
207
- );
208
- const receipt = await tx.wait();
209
- return {
210
- success: receipt.status === 1,
211
- tx_hash: tx.hash
212
- };
213
- } catch (error) {
214
- return {
215
- success: false,
216
- error: error.message
217
- };
218
- }
219
- }
220
- /**
221
- * Format Permit request as user message
222
- */
223
- formatPermitMessage(request) {
224
- const { typed_data } = request;
225
- const { message } = typed_data;
226
- return `\u{1F510} **Signature Authorization Request**
227
-
228
- Authorize \`${(Number(message.value) / 1e6).toFixed(2)} USDC\` to service provider
229
-
230
- **Signature Details:**
231
- - Owner: \`${message.owner}\`
232
- - Spender: \`${message.spender}\`
233
- - Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC
234
- - Deadline: ${new Date(message.deadline * 1e3).toISOString()}
235
-
236
- Please sign this request in your wallet (no gas required).
237
-
238
- \`\`\`json
239
- ${JSON.stringify(typed_data, null, 2)}
240
- \`\`\``;
241
- }
242
- };
243
- export {
244
- PermitPayment
245
- };
246
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/permit/Permit.ts","../../src/chains/index.ts"],"sourcesContent":["/**\n * PermitPayment - EIP-2612 Gasless Pre-authorization\n * \n * User signs authorization, service provider pays gas to execute transferFrom\n */\n\nimport { ethers } from 'ethers';\nimport { getChain, ERC20_ABI } from '../chains/index.js';\nimport type {\n ChainName,\n ChainConfig,\n PermitRequest,\n PermitSignature,\n PermitExecuteResult,\n EIP712TypedData,\n} from '../types/index.js';\n\nexport interface PermitConfig {\n chain?: ChainName;\n privateKey?: string;\n spenderAddress?: string;\n rpcUrl?: string;\n}\n\nexport class PermitPayment {\n readonly chain: ChainName;\n readonly chainConfig: ChainConfig;\n readonly spenderAddress: string;\n \n private provider: ethers.JsonRpcProvider;\n private wallet?: ethers.Wallet;\n private usdcContract: ethers.Contract;\n\n constructor(config: PermitConfig = {}) {\n this.chain = config.chain || 'base_sepolia';\n this.chainConfig = getChain(this.chain);\n this.spenderAddress = config.spenderAddress || process.env.PAYMENT_AGENT_WALLET || '';\n\n const rpcUrl = config.rpcUrl || this.chainConfig.rpc;\n this.provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const privateKey = config.privateKey || process.env.PAYMENT_AGENT_PRIVATE_KEY;\n if (privateKey) {\n this.wallet = new ethers.Wallet(privateKey, this.provider);\n this.spenderAddress = this.wallet.address;\n }\n\n this.usdcContract = new ethers.Contract(\n this.chainConfig.usdc,\n ERC20_ABI,\n this.wallet || this.provider\n );\n }\n\n /**\n * Get user current nonce\n */\n async getNonce(owner: string): Promise<number> {\n return Number(await this.usdcContract.nonces(owner));\n }\n\n /**\n * Generate EIP-712 signing request (for frontend/user wallet)\n */\n async createPermitRequest(\n owner: string,\n amount: number,\n orderId: string,\n deadlineMinutes: number = 30\n ): Promise<PermitRequest> {\n const nonce = await this.getNonce(owner);\n const deadline = Math.floor(Date.now() / 1000) + deadlineMinutes * 60;\n const value = BigInt(Math.floor(amount * 1e6)).toString();\n\n // USDC EIP-712 domain (may differ by chain)\n const domain = {\n name: 'USD Coin',\n version: '2',\n chainId: this.chainConfig.chainId,\n verifyingContract: this.chainConfig.usdc,\n };\n\n const types = {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n Permit: [\n { name: 'owner', type: 'address' },\n { name: 'spender', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'nonce', type: 'uint256' },\n { name: 'deadline', type: 'uint256' },\n ],\n };\n\n const message = {\n owner,\n spender: this.spenderAddress,\n value,\n nonce,\n deadline,\n };\n\n const typedData: EIP712TypedData = {\n types,\n primaryType: 'Permit',\n domain,\n message,\n };\n\n return {\n type: 'permit_request',\n version: '1.0',\n order_id: orderId,\n typed_data: typedData,\n };\n }\n\n /**\n * Execute permit + transferFrom\n * \n * @param owner User address\n * @param amount Amount\n * @param signature User signature {v, r, s, deadline}\n */\n async executePermitAndTransfer(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n // 1. Call permit\n const permitTx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n await permitTx.wait();\n\n // 2. Call transferFrom\n const transferTx = await this.usdcContract.transferFrom(owner, this.spenderAddress, value);\n const receipt = await transferTx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: transferTx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Execute permit only (no transfer)\n */\n async executePermit(\n owner: string,\n amount: number,\n signature: PermitSignature\n ): Promise<PermitExecuteResult> {\n if (!this.wallet) {\n return { success: false, error: 'Wallet not configured. Private key required.' };\n }\n\n try {\n const value = BigInt(Math.floor(amount * 1e6));\n\n const tx = await this.usdcContract.permit(\n owner,\n this.spenderAddress,\n value,\n signature.deadline,\n signature.v,\n signature.r,\n signature.s\n );\n const receipt = await tx.wait();\n\n return {\n success: receipt.status === 1,\n tx_hash: tx.hash,\n };\n } catch (error) {\n return {\n success: false,\n error: (error as Error).message,\n };\n }\n }\n\n /**\n * Format Permit request as user message\n */\n formatPermitMessage(request: PermitRequest): string {\n const { typed_data } = request;\n const { message } = typed_data;\n\n return `🔐 **Signature Authorization Request**\n\nAuthorize \\`${(Number(message.value) / 1e6).toFixed(2)} USDC\\` to service provider\n\n**Signature Details:**\n- Owner: \\`${message.owner}\\`\n- Spender: \\`${message.spender}\\`\n- Amount: ${(Number(message.value) / 1e6).toFixed(2)} USDC\n- Deadline: ${new Date(message.deadline * 1000).toISOString()}\n\nPlease sign this request in your wallet (no gas required).\n\n\\`\\`\\`json\n${JSON.stringify(typed_data, null, 2)}\n\\`\\`\\``;\n }\n}\n","/**\n * Blockchain Configuration\n */\n\nimport type { ChainConfig, ChainName } from '../types/index.js';\n\nexport const CHAINS: Record<ChainName, ChainConfig> = {\n // ============ Mainnet ============\n base: {\n name: 'Base',\n chainId: 8453,\n rpc: 'https://mainnet.base.org',\n usdc: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n explorer: 'https://basescan.org/address/',\n explorerTx: 'https://basescan.org/tx/',\n avgBlockTime: 2,\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n rpc: 'https://polygon-rpc.com',\n usdc: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n explorer: 'https://polygonscan.com/address/',\n explorerTx: 'https://polygonscan.com/tx/',\n avgBlockTime: 2,\n },\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n rpc: 'https://eth.llamarpc.com',\n usdc: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n explorer: 'https://etherscan.io/address/',\n explorerTx: 'https://etherscan.io/tx/',\n avgBlockTime: 12,\n },\n\n // ============ Testnet ============\n base_sepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n rpc: 'https://sepolia.base.org',\n usdc: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n explorer: 'https://sepolia.basescan.org/address/',\n explorerTx: 'https://sepolia.basescan.org/tx/',\n avgBlockTime: 2,\n },\n sepolia: {\n name: 'Sepolia',\n chainId: 11155111,\n rpc: 'https://rpc.sepolia.org',\n usdc: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n explorer: 'https://sepolia.etherscan.io/address/',\n explorerTx: 'https://sepolia.etherscan.io/tx/',\n avgBlockTime: 12,\n },\n};\n\n/**\n * Get chain configuration\n */\nexport function getChain(name: ChainName): ChainConfig {\n const config = CHAINS[name];\n if (!config) {\n throw new Error(`Unsupported chain: ${name}. Supported: ${Object.keys(CHAINS).join(', ')}`);\n }\n return config;\n}\n\n/**\n * List all supported chains\n */\nexport function listChains(): ChainName[] {\n return Object.keys(CHAINS) as ChainName[];\n}\n\n/**\n * Get chain config by chainId\n */\nexport function getChainById(chainId: number): ChainConfig | undefined {\n return Object.values(CHAINS).find(c => c.chainId === chainId);\n}\n\n/**\n * ERC20 ABI (minimal, only required methods)\n */\nexport const ERC20_ABI = [\n 'function balanceOf(address owner) view returns (uint256)',\n 'function transfer(address to, uint256 amount) returns (bool)',\n 'function approve(address spender, uint256 amount) returns (bool)',\n 'function allowance(address owner, address spender) view returns (uint256)',\n 'function decimals() view returns (uint8)',\n 'function symbol() view returns (string)',\n 'function name() view returns (string)',\n 'function nonces(address owner) view returns (uint256)',\n 'function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)',\n 'event Transfer(address indexed from, address indexed to, uint256 value)',\n 'event Approval(address indexed owner, address indexed spender, uint256 value)',\n];\n\nexport type { ChainConfig, ChainName };\n"],"mappings":"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","names":[]}
File without changes
File without changes