@swimmingkiim/pay-sdk 0.1.22 → 0.1.24

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.
@@ -104,12 +104,18 @@ console.log("Transaction Hash:", txHash);
104
104
 
105
105
  ### 5. Auto-Deposit Feature
106
106
 
107
- The SDK includes a built-in **Auto-Deposit** mechanism.
108
- 1. **Check**: Before sending, it checks if the Smart Account has enough USDC for the Paymaster fee (default 0.1 USDC).
109
- 2. **Deposit**: If funds are insufficient, it automatically triggers a deposit transaction from the signer's EOA (Externally Owned Account) to the Smart Account.
110
- 3. **Execute**: Once the deposit is confirmed, it proceeds with the Paymaster transaction.
111
-
112
- **Note**: This requires your EOA to have sufficient USDC and ETH (for the deposit gas) if a top-up is needed.
107
+ The SDK includes a built-in **Auto-Deposit** mechanism to ensure smooth execution even for new accounts.
108
+
109
+ #### How it works:
110
+ 1. **Check**: Before sending a UserOperation, the SDK checks if the Smart Account has enough USDC to cover the Paymaster fee (default fee or custom amount).
111
+ 2. **Deposit**: If funds are insufficient, it automatically triggers a standard ETH transaction from the signer's EOA (Externally Owned Account) to the Smart Account to transfer the missing USDC.
112
+ 3. **Execute**: Once the deposit transaction is confirmed on-chain, it proceeds with the Paymaster sponsored transaction.
113
+
114
+ #### ⚠️ Important Requirements:
115
+ * **Signer EOA Funds**: Your private key's wallet (EOA) MUST have:
116
+ * **ETH**: To pay gas for the standard deposit transaction (this step is NOT sponsored).
117
+ * **USDC**: Sufficient balance to transfer to the Smart Account.
118
+ * **Permissions**: The EOA must be an owner of the Smart Account (handled automatically during creation).
113
119
 
114
120
  ## 🛡️ Error Handling
115
121
 
@@ -0,0 +1,219 @@
1
+ # PaymentVerifier Usage Guide
2
+
3
+ ## Overview
4
+ `PaymentVerifier` is a utility class in `@swimmingkiim/pay-sdk` that verifies on-chain ERC20 token transfers. It's designed for implementing "pay-per-use" API patterns.
5
+
6
+ ## Installation
7
+
8
+ The class is already included in `@swimmingkiim/pay-sdk`:
9
+
10
+ ```typescript
11
+ import { PaymentVerifier } from '@swimmingkiim/pay-sdk';
12
+ ```
13
+
14
+ ## Basic Usage
15
+
16
+ ### 1. Initialize PaymentVerifier
17
+
18
+ ```typescript
19
+ import { PaymentVerifier } from '@swimmingkiim/pay-sdk';
20
+ import { base } from 'viem/chains';
21
+
22
+ const verifier = new PaymentVerifier({
23
+ rpcUrl: 'https://mainnet.base.org',
24
+ chain: base,
25
+ tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' // Optional: USDC (default)
26
+ });
27
+ ```
28
+
29
+ ### 2. Verify a Payment
30
+
31
+ ```typescript
32
+ const result = await verifier.verifyUSDCPayment(
33
+ '0x123...', // Transaction hash
34
+ '0xabc...', // Expected sender
35
+ '0xdef...', // Expected receiver (your treasury)
36
+ 100000n // Minimum amount (0.1 USDC)
37
+ );
38
+
39
+ if (result.isValid) {
40
+ console.log(`Payment verified: ${result.amount} tokens`);
41
+ } else {
42
+ console.error(`Verification failed: ${result.error}`);
43
+ }
44
+ ```
45
+
46
+ ## API Reference
47
+
48
+ ### `PaymentVerifier`
49
+
50
+ #### Constructor
51
+
52
+ ```typescript
53
+ new PaymentVerifier(config: PaymentVerifierConfig)
54
+ ```
55
+
56
+ **Config:**
57
+ - `rpcUrl`: Blockchain RPC endpoint
58
+ - `chain`: viem Chain object (e.g., `base`, `mainnet`)
59
+ - `tokenAddress?`: ERC20 token address (defaults to USDC on Base)
60
+
61
+ #### Methods
62
+
63
+ ##### `verifyPayment()`
64
+
65
+ ```typescript
66
+ async verifyPayment(
67
+ txHash: `0x${string}`,
68
+ expectedFrom: `0x${string}`,
69
+ expectedTo: `0x${string}`,
70
+ minimumAmount: bigint
71
+ ): Promise<PaymentVerificationResult>
72
+ ```
73
+
74
+ Verifies an ERC20 transfer transaction.
75
+
76
+ **Returns:**
77
+ ```typescript
78
+ {
79
+ isValid: boolean;
80
+ error?: string;
81
+ txHash?: `0x${string}`;
82
+ from?: `0x${string}`;
83
+ to?: `0x${string}`;
84
+ amount?: bigint;
85
+ }
86
+ ```
87
+
88
+ ##### `verifyUSDCPayment()`
89
+
90
+ Convenience method with the same signature as `verifyPayment()` but optimized for USDC verification.
91
+
92
+ ## Real-World Example: Paymaster Proxy Server
93
+
94
+ ```typescript
95
+ import express from 'express';
96
+ import { PaymentVerifier, PaymasterManager } from '@swimmingkiim/pay-sdk';
97
+ import { base } from 'viem/chains';
98
+
99
+ const app = express();
100
+ app.use(express.json());
101
+
102
+ const TREASURY = process.env.TREASURY_ADDRESS as `0x${string}`;
103
+ const verifier = new PaymentVerifier({
104
+ rpcUrl: process.env.RPC_URL!,
105
+ chain: base
106
+ });
107
+
108
+ app.post('/api/sponsor', async (req, res) => {
109
+ const paymentTx = req.headers['x-payment-tx'] as `0x${string}`;
110
+
111
+ if (!paymentTx) {
112
+ return res.status(402).json({ error: 'Payment required' });
113
+ }
114
+
115
+ // Verify payment
116
+ const verification = await verifier.verifyUSDCPayment(
117
+ paymentTx,
118
+ req.body.userOperation.sender,
119
+ TREASURY,
120
+ 100000n // 0.1 USDC
121
+ );
122
+
123
+ if (!verification.isValid) {
124
+ return res.status(402).json({
125
+ error: 'Invalid payment',
126
+ details: verification.error
127
+ });
128
+ }
129
+
130
+ // Payment verified → provide service
131
+ const sponsorship = await paymasterManager.getStubPaymasterData(
132
+ req.body.userOperation
133
+ );
134
+
135
+ res.json(sponsorship);
136
+ });
137
+ ```
138
+
139
+ ## Best Practices
140
+
141
+ ### 1. Prevent Payment Reuse
142
+
143
+ Store verified transaction hashes to prevent reuse:
144
+
145
+ ```typescript
146
+ import Redis from 'ioredis';
147
+ const redis = new Redis();
148
+
149
+ // After verification:
150
+ if (verification.isValid) {
151
+ // Check if already used
152
+ const exists = await redis.exists(`payment:${txHash}`);
153
+ if (exists) {
154
+ return { error: 'Payment already used' };
155
+ }
156
+
157
+ // Mark as used (expires in 1 hour)
158
+ await redis.set(`payment:${txHash}`, 'used', 'EX', 3600);
159
+ }
160
+ ```
161
+
162
+ ### 2. Time-Based Expiration
163
+
164
+ Only accept recent payments:
165
+
166
+ ```typescript
167
+ const receipt = await publicClient.getTransactionReceipt({ hash: txHash });
168
+ const block = await publicClient.getBlock({ blockNumber: receipt.blockNumber });
169
+ const txTime = Number(block.timestamp) * 1000;
170
+ const now = Date.now();
171
+
172
+ if (now - txTime > 5 * 60 * 1000) { // 5 minutes
173
+ return { error: 'Payment expired' };
174
+ }
175
+ ```
176
+
177
+ ### 3. Credit System
178
+
179
+ Allow overpayment for credits:
180
+
181
+ ```typescript
182
+ const PRICE_PER_REQUEST = 100000n; // 0.1 USDC
183
+
184
+ if (verification.amount > PRICE_PER_REQUEST) {
185
+ const credits = verification.amount / PRICE_PER_REQUEST;
186
+ await db.addCredits(userAddress, Number(credits));
187
+ }
188
+ ```
189
+
190
+ ## Error Handling
191
+
192
+ Common errors returned in `PaymentVerificationResult.error`:
193
+
194
+ - `"Transaction not found"`: Invalid transaction hash
195
+ - `"Transaction failed"`: Transaction reverted on-chain
196
+ - `"No transfer events found for this token"`: Wrong token or no transfer occurred
197
+ - `"No matching transfer found in transaction"`: Transfer exists but doesn't match criteria (wrong sender/receiver/amount)
198
+
199
+ ## Chain Support
200
+
201
+ Works on any EVM-compatible chain. Examples:
202
+
203
+ ```typescript
204
+ import { mainnet, base, arbitrum, optimism } from 'viem/chains';
205
+
206
+ // Ethereum mainnet
207
+ const ethVerifier = new PaymentVerifier({
208
+ rpcUrl: 'https://eth.llamarpc.com',
209
+ chain: mainnet,
210
+ tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' // USDC on Ethereum
211
+ });
212
+
213
+ // Arbitrum
214
+ const arbVerifier = new PaymentVerifier({
215
+ rpcUrl: 'https://arb1.arbitrum.io/rpc',
216
+ chain: arbitrum,
217
+ tokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' // USDC on Arbitrum
218
+ });
219
+ ```
@@ -1 +1 @@
1
- {"version":3,"file":"smart-account.d.ts","sourceRoot":"","sources":["../../src/account/smart-account.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAQ,MAAM,MAAM,CAAA;AAIzH,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE5D,qBAAa,mBAAmB;IAKxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS,CAAC;IAPf,MAAM,EAAE,GAAG,CAAA;IACX,OAAO,EAAE,GAAG,CAAA;gBAGP,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EAC/C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,gBAAgB,YAAA;IAGlC,iBAAiB,CAAC,SAAS,GAAE,MAAW;IA4B9C,UAAU,IAAI,OAAO;IAIf,YAAY,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,EAAE;IAgBzE,cAAc,CAAC,cAAc,EAAE,MAAM;CAqE9C"}
1
+ {"version":3,"file":"smart-account.d.ts","sourceRoot":"","sources":["../../src/account/smart-account.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAQ,MAAM,MAAM,CAAA;AAIzH,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAE5D,qBAAa,mBAAmB;IAKxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS,CAAC;IAPf,MAAM,EAAE,GAAG,CAAA;IACX,OAAO,EAAE,GAAG,CAAA;gBAGP,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,EAC/C,YAAY,EAAE,YAAY,CAAC,SAAS,EAAE,KAAK,CAAC,EAC5C,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,gBAAgB,YAAA;IAGlC,iBAAiB,CAAC,SAAS,GAAE,MAAW;IAmC9C,UAAU,IAAI,OAAO;IAIf,YAAY,CAAC,KAAK,EAAE;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,EAAE;IAgBzE,cAAc,CAAC,cAAc,EAAE,MAAM;CAqE9C"}
@@ -27,14 +27,20 @@ export class SmartAccountManager {
27
27
  },
28
28
  saltNonce,
29
29
  });
30
+ const apiKey = this.paymaster?.getApiKey();
31
+ const fetchOptions = apiKey ? { headers: { 'x-api-key': apiKey } } : undefined;
30
32
  this.client = createSmartAccountClient({
31
33
  account: this.account,
32
34
  chain: this.signer.chain,
33
- bundlerTransport: http(this.rpcUrl),
35
+ bundlerTransport: http(this.rpcUrl, { fetchOptions }),
34
36
  paymaster: this.paymaster ? this.paymaster.getClient() : undefined,
35
37
  userOperation: {
36
38
  estimateFeesPerGas: async () => {
37
- return (await this.publicClient.estimateFeesPerGas());
39
+ const fees = await this.publicClient.estimateFeesPerGas();
40
+ return {
41
+ maxFeePerGas: (fees.maxFeePerGas * 20n) / 10n, // 2x (safety margin)
42
+ maxPriorityFeePerGas: (fees.maxPriorityFeePerGas * 20n) / 10n
43
+ };
38
44
  }
39
45
  }
40
46
  }).extend(erc7579Actions());
@@ -47,8 +53,8 @@ export class SmartAccountManager {
47
53
  if (!this.client)
48
54
  throw new Error("Account not initialized");
49
55
  // [Fee Logic] Ensure Smart Account has enough USDC for the fee
50
- // We assume 0.1 USDC is required per transaction for now (as per Paymaster config)
51
- await this.ensureGasFunds(100000n);
56
+ // We assume 0.6 USDC is required per transaction (matching Paymaster Policy)
57
+ await this.ensureGasFunds(600000n);
52
58
  const txHash = await this.client.sendTransaction({
53
59
  calls: calls,
54
60
  account: this.account
@@ -1 +1 @@
1
- {"version":3,"file":"smart-account.js","sourceRoot":"","sources":["../../src/account/smart-account.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"smart-account.js","sourceRoot":"","sources":["../../src/account/smart-account.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./account/smart-account.js";
2
2
  export * from "./paymaster/paymaster.js";
3
+ export * from "./payment/payment-verifier.js";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,+BAA+B,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./account/smart-account.js";
2
2
  export * from "./paymaster/paymaster.js";
3
+ export * from "./payment/payment-verifier.js";
3
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,+BAA+B,CAAA"}
@@ -1,7 +1,9 @@
1
1
  export declare class PaymasterManager {
2
2
  private client;
3
+ private apiKey?;
3
4
  constructor(rpcUrl?: string, apiKey?: string);
4
5
  getClient(): any;
6
+ getApiKey(): string | undefined;
5
7
  getStubPaymasterData(userOp: any): Promise<any>;
6
8
  /**
7
9
  * Appends a fee transfer transaction to the list of calls.
@@ -1 +1 @@
1
- {"version":3,"file":"paymaster.d.ts","sourceRoot":"","sources":["../../src/paymaster/paymaster.ts"],"names":[],"mappings":"AAMA,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAK;gBAEP,MAAM,GAAE,MAA6C,EAAE,MAAM,CAAC,EAAE,MAAM;IAYlF,SAAS;IAIH,oBAAoB,CAAC,MAAM,EAAE,GAAG;IAMtC;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAwBxG"}
1
+ {"version":3,"file":"paymaster.d.ts","sourceRoot":"","sources":["../../src/paymaster/paymaster.ts"],"names":[],"mappings":"AAMA,qBAAa,gBAAgB;IACzB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,MAAM,CAAC,CAAQ;gBAEX,MAAM,GAAE,MAA6C,EAAE,MAAM,CAAC,EAAE,MAAM;IAalF,SAAS;IAIT,SAAS;IAIH,oBAAoB,CAAC,MAAM,EAAE,GAAG;IAMtC;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAwBxG"}
@@ -3,7 +3,9 @@ import { http, encodeFunctionData, parseAbi } from "viem";
3
3
  const ERC20_ABI = parseAbi(['function transfer(address to, uint256 amount) returns (bool)']);
4
4
  export class PaymasterManager {
5
5
  client;
6
+ apiKey;
6
7
  constructor(rpcUrl = "http://localhost:8080/v1/paymaster", apiKey) {
8
+ this.apiKey = apiKey;
7
9
  const fetchOptions = apiKey ? { headers: { 'x-api-key': apiKey } } : undefined;
8
10
  this.client = createPimlicoClient({
9
11
  transport: http(rpcUrl, { fetchOptions }),
@@ -16,6 +18,9 @@ export class PaymasterManager {
16
18
  getClient() {
17
19
  return this.client;
18
20
  }
21
+ getApiKey() {
22
+ return this.apiKey;
23
+ }
19
24
  async getStubPaymasterData(userOp) {
20
25
  return this.client.sponsorUserOperation({
21
26
  userOperation: userOp
@@ -1 +1 @@
1
- {"version":3,"file":"paymaster.js","sourceRoot":"","sources":["../../src/paymaster/paymaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAO,MAAM,MAAM,CAAA;AAE9D,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC;AAG7F,MAAM,OAAO,gBAAgB;IACjB,MAAM,CAAK;IAEnB,YAAY,SAAiB,oCAAoC,EAAE,MAAe;QAC9E,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/E,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC;YAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,CAAC;YACzC,UAAU,EAAE;gBACR,OAAO,EAAE,4CAA4C;gBACrD,OAAO,EAAE,KAAK;aACjB;SACJ,CAAC,CAAA;IACN,CAAC;IAED,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,MAAW;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;YACpC,aAAa,EAAE,MAAM;SACxB,CAAC,CAAA;IACN,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAY,EAAE,SAA+D;QACjG,yCAAyC;QACzC,MAAM,MAAM,GAAG;YACX,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,4CAA4C,EAAE,sBAAsB;YACrG,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,OAAO,EAAE,WAAW;YACjD,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,4CAA4C,CAAC,eAAe;SAC1F,CAAC;QAEF,IAAI,MAAM,CAAC,QAAQ,KAAK,4CAA4C,EAAE,CAAC;YACnE,OAAO,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;QAC1G,CAAC;QAED,MAAM,OAAO,GAAG;YACZ,EAAE,EAAE,MAAM,CAAC,KAAY;YACvB,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,kBAAkB,CAAC;gBACrB,GAAG,EAAE,SAAS;gBACd,YAAY,EAAE,UAAU;gBACxB,IAAI,EAAE,CAAC,MAAM,CAAC,QAAe,EAAE,MAAM,CAAC,MAAM,CAAC;aAChD,CAAC;SACL,CAAC;QAEF,OAAO,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ"}
1
+ {"version":3,"file":"paymaster.js","sourceRoot":"","sources":["../../src/paymaster/paymaster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAO,MAAM,MAAM,CAAA;AAE9D,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC;AAG7F,MAAM,OAAO,gBAAgB;IACjB,MAAM,CAAK;IACX,MAAM,CAAS;IAEvB,YAAY,SAAiB,oCAAoC,EAAE,MAAe;QAC9E,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/E,IAAI,CAAC,MAAM,GAAG,mBAAmB,CAAC;YAC9B,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,CAAC;YACzC,UAAU,EAAE;gBACR,OAAO,EAAE,4CAA4C;gBACrD,OAAO,EAAE,KAAK;aACjB;SACJ,CAAC,CAAA;IACN,CAAC;IAED,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAA;IACtB,CAAC;IAED,SAAS;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,MAAW;QAClC,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;YACpC,aAAa,EAAE,MAAM;SACxB,CAAC,CAAA;IACN,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,gBAAgB,CAAC,KAAY,EAAE,SAA+D;QACjG,yCAAyC;QACzC,MAAM,MAAM,GAAG;YACX,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,4CAA4C,EAAE,sBAAsB;YACrG,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,OAAO,EAAE,WAAW;YACjD,KAAK,EAAE,SAAS,EAAE,KAAK,IAAI,4CAA4C,CAAC,eAAe;SAC1F,CAAC;QAEF,IAAI,MAAM,CAAC,QAAQ,KAAK,4CAA4C,EAAE,CAAC;YACnE,OAAO,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;QAC1G,CAAC;QAED,MAAM,OAAO,GAAG;YACZ,EAAE,EAAE,MAAM,CAAC,KAAY;YACvB,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,kBAAkB,CAAC;gBACrB,GAAG,EAAE,SAAS;gBACd,YAAY,EAAE,UAAU;gBACxB,IAAI,EAAE,CAAC,MAAM,CAAC,QAAe,EAAE,MAAM,CAAC,MAAM,CAAC;aAChD,CAAC;SACL,CAAC;QAEF,OAAO,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ"}
@@ -0,0 +1,45 @@
1
+ import { Chain } from 'viem';
2
+ export interface PaymentVerificationResult {
3
+ isValid: boolean;
4
+ error?: string;
5
+ txHash?: `0x${string}`;
6
+ from?: `0x${string}`;
7
+ to?: `0x${string}`;
8
+ amount?: bigint;
9
+ }
10
+ export interface PaymentVerifierConfig {
11
+ rpcUrl: string;
12
+ chain: Chain;
13
+ tokenAddress?: `0x${string}`;
14
+ }
15
+ /**
16
+ * PaymentVerifier class for verifying ERC20 token payments on-chain.
17
+ * Useful for implementing pay-per-use API access patterns.
18
+ */
19
+ export declare class PaymentVerifier {
20
+ private publicClient;
21
+ private tokenAddress;
22
+ /**
23
+ * Creates a new PaymentVerifier instance
24
+ * @param config Configuration object with RPC URL, chain, and optional token address
25
+ */
26
+ constructor(config: PaymentVerifierConfig);
27
+ /**
28
+ * Verifies that a specific ERC20 transfer transaction occurred
29
+ * @param txHash Transaction hash to verify
30
+ * @param expectedFrom Expected sender address
31
+ * @param expectedTo Expected receiver address
32
+ * @param minimumAmount Minimum amount that must have been transferred (in token base units)
33
+ * @returns PaymentVerificationResult with verification status and details
34
+ */
35
+ verifyPayment(txHash: `0x${string}`, expectedFrom: `0x${string}`, expectedTo: `0x${string}`, minimumAmount: bigint): Promise<PaymentVerificationResult>;
36
+ /**
37
+ * Convenience method for verifying USDC payments
38
+ * @param txHash Transaction hash to verify
39
+ * @param expectedFrom Expected sender address
40
+ * @param expectedTo Expected receiver address
41
+ * @param minimumUSDC Minimum USDC amount in base units (1 USDC = 1000000)
42
+ */
43
+ verifyUSDCPayment(txHash: `0x${string}`, expectedFrom: `0x${string}`, expectedTo: `0x${string}`, minimumUSDC: bigint): Promise<PaymentVerificationResult>;
44
+ }
45
+ //# sourceMappingURL=payment-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-verifier.d.ts","sourceRoot":"","sources":["../../src/payment/payment-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+E,KAAK,EAAE,MAAM,MAAM,CAAC;AAI1G,MAAM,WAAW,yBAAyB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACrB,EAAE,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;CAChC;AAED;;;GAGG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,YAAY,CAAgB;IAEpC;;;OAGG;gBACS,MAAM,EAAE,qBAAqB;IAUzC;;;;;;;OAOG;IACG,aAAa,CACf,MAAM,EAAE,KAAK,MAAM,EAAE,EACrB,YAAY,EAAE,KAAK,MAAM,EAAE,EAC3B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,aAAa,EAAE,MAAM,GACtB,OAAO,CAAC,yBAAyB,CAAC;IA+ErC;;;;;;OAMG;IACG,iBAAiB,CACnB,MAAM,EAAE,KAAK,MAAM,EAAE,EACrB,YAAY,EAAE,KAAK,MAAM,EAAE,EAC3B,UAAU,EAAE,KAAK,MAAM,EAAE,EACzB,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,yBAAyB,CAAC;CAGxC"}
@@ -0,0 +1,108 @@
1
+ import { createPublicClient, http, decodeEventLog, parseAbi } from 'viem';
2
+ const TRANSFER_EVENT_ABI = parseAbi(['event Transfer(address indexed from, address indexed to, uint256 value)']);
3
+ /**
4
+ * PaymentVerifier class for verifying ERC20 token payments on-chain.
5
+ * Useful for implementing pay-per-use API access patterns.
6
+ */
7
+ export class PaymentVerifier {
8
+ publicClient;
9
+ tokenAddress;
10
+ /**
11
+ * Creates a new PaymentVerifier instance
12
+ * @param config Configuration object with RPC URL, chain, and optional token address
13
+ */
14
+ constructor(config) {
15
+ this.publicClient = createPublicClient({
16
+ chain: config.chain,
17
+ transport: http(config.rpcUrl)
18
+ });
19
+ // Default to USDC on Base if not specified
20
+ this.tokenAddress = config.tokenAddress || '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
21
+ }
22
+ /**
23
+ * Verifies that a specific ERC20 transfer transaction occurred
24
+ * @param txHash Transaction hash to verify
25
+ * @param expectedFrom Expected sender address
26
+ * @param expectedTo Expected receiver address
27
+ * @param minimumAmount Minimum amount that must have been transferred (in token base units)
28
+ * @returns PaymentVerificationResult with verification status and details
29
+ */
30
+ async verifyPayment(txHash, expectedFrom, expectedTo, minimumAmount) {
31
+ try {
32
+ // 1. Get transaction receipt
33
+ const receipt = await this.publicClient.getTransactionReceipt({ hash: txHash });
34
+ if (!receipt) {
35
+ return {
36
+ isValid: false,
37
+ error: 'Transaction not found'
38
+ };
39
+ }
40
+ if (receipt.status !== 'success') {
41
+ return {
42
+ isValid: false,
43
+ error: 'Transaction failed',
44
+ txHash
45
+ };
46
+ }
47
+ // 2. Filter logs for the specified token contract
48
+ const tokenLogs = receipt.logs.filter(log => log.address.toLowerCase() === this.tokenAddress.toLowerCase());
49
+ if (tokenLogs.length === 0) {
50
+ return {
51
+ isValid: false,
52
+ error: 'No transfer events found for this token',
53
+ txHash
54
+ };
55
+ }
56
+ // 3. Parse Transfer events and find matching one
57
+ for (const log of tokenLogs) {
58
+ try {
59
+ const decoded = decodeEventLog({
60
+ abi: TRANSFER_EVENT_ABI,
61
+ data: log.data,
62
+ topics: log.topics
63
+ });
64
+ const { from, to, value } = decoded.args;
65
+ // Check if this transfer matches our criteria
66
+ if (from.toLowerCase() === expectedFrom.toLowerCase() &&
67
+ to.toLowerCase() === expectedTo.toLowerCase() &&
68
+ value >= minimumAmount) {
69
+ return {
70
+ isValid: true,
71
+ txHash,
72
+ from,
73
+ to,
74
+ amount: value
75
+ };
76
+ }
77
+ }
78
+ catch (decodeError) {
79
+ // Skip logs that don't match Transfer event signature
80
+ continue;
81
+ }
82
+ }
83
+ // No matching transfer found
84
+ return {
85
+ isValid: false,
86
+ error: 'No matching transfer found in transaction',
87
+ txHash
88
+ };
89
+ }
90
+ catch (error) {
91
+ return {
92
+ isValid: false,
93
+ error: error.message || 'Unknown error during verification'
94
+ };
95
+ }
96
+ }
97
+ /**
98
+ * Convenience method for verifying USDC payments
99
+ * @param txHash Transaction hash to verify
100
+ * @param expectedFrom Expected sender address
101
+ * @param expectedTo Expected receiver address
102
+ * @param minimumUSDC Minimum USDC amount in base units (1 USDC = 1000000)
103
+ */
104
+ async verifyUSDCPayment(txHash, expectedFrom, expectedTo, minimumUSDC) {
105
+ return this.verifyPayment(txHash, expectedFrom, expectedTo, minimumUSDC);
106
+ }
107
+ }
108
+ //# sourceMappingURL=payment-verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-verifier.js","sourceRoot":"","sources":["../../src/payment/payment-verifier.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swimmingkiim/pay-sdk",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/swimmingkiim/a2a-project.git"
@@ -31,14 +31,21 @@ export class SmartAccountManager {
31
31
  saltNonce,
32
32
  })
33
33
 
34
+ const apiKey = this.paymaster?.getApiKey();
35
+ const fetchOptions = apiKey ? { headers: { 'x-api-key': apiKey } } : undefined;
36
+
34
37
  this.client = createSmartAccountClient({
35
38
  account: this.account,
36
39
  chain: this.signer.chain,
37
- bundlerTransport: http(this.rpcUrl),
40
+ bundlerTransport: http(this.rpcUrl, { fetchOptions }),
38
41
  paymaster: this.paymaster ? this.paymaster.getClient() : undefined,
39
42
  userOperation: {
40
43
  estimateFeesPerGas: async () => {
41
- return (await this.publicClient.estimateFeesPerGas()) as any
44
+ const fees = await this.publicClient.estimateFeesPerGas();
45
+ return {
46
+ maxFeePerGas: (fees.maxFeePerGas * 20n) / 10n, // 2x (safety margin)
47
+ maxPriorityFeePerGas: (fees.maxPriorityFeePerGas * 20n) / 10n
48
+ } as any;
42
49
  }
43
50
  }
44
51
  }).extend(erc7579Actions())
@@ -54,8 +61,8 @@ export class SmartAccountManager {
54
61
  if (!this.client) throw new Error("Account not initialized")
55
62
 
56
63
  // [Fee Logic] Ensure Smart Account has enough USDC for the fee
57
- // We assume 0.1 USDC is required per transaction for now (as per Paymaster config)
58
- await this.ensureGasFunds(100000n);
64
+ // We assume 0.6 USDC is required per transaction (matching Paymaster Policy)
65
+ await this.ensureGasFunds(600000n);
59
66
 
60
67
  const txHash = await this.client.sendTransaction({
61
68
  calls: calls,
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * from "./account/smart-account.js"
2
2
  export * from "./paymaster/paymaster.js"
3
+ export * from "./payment/payment-verifier.js"
@@ -6,8 +6,10 @@ const ERC20_ABI = parseAbi(['function transfer(address to, uint256 amount) retur
6
6
 
7
7
  export class PaymasterManager {
8
8
  private client: any
9
+ private apiKey?: string
9
10
 
10
11
  constructor(rpcUrl: string = "http://localhost:8080/v1/paymaster", apiKey?: string) {
12
+ this.apiKey = apiKey;
11
13
  const fetchOptions = apiKey ? { headers: { 'x-api-key': apiKey } } : undefined;
12
14
 
13
15
  this.client = createPimlicoClient({
@@ -23,6 +25,10 @@ export class PaymasterManager {
23
25
  return this.client
24
26
  }
25
27
 
28
+ getApiKey() {
29
+ return this.apiKey;
30
+ }
31
+
26
32
  async getStubPaymasterData(userOp: any) {
27
33
  return this.client.sponsorUserOperation({
28
34
  userOperation: userOp