@swimmingkiim/pay-sdk 0.1.25 → 0.1.26
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/.env +11 -0
- package/README.md +1 -1
- package/dist/account/smart-account.js +2 -2
- package/dist/account/smart-account.js.map +1 -1
- package/dist/paymaster/paymaster.d.ts +31 -6
- package/dist/paymaster/paymaster.d.ts.map +1 -1
- package/dist/paymaster/paymaster.js +32 -10
- package/dist/paymaster/paymaster.js.map +1 -1
- package/dist/payment/payment-verifier.js +1 -1
- package/dist/payment/payment-verifier.js.map +1 -1
- package/package.json +2 -2
- package/src/account/smart-account.ts +2 -2
- package/src/paymaster/paymaster.ts +46 -11
- package/src/payment/payment-verifier.ts +1 -1
- package/test/paymaster-health-test.ts +78 -0
- package/test/paymaster-manager.test.ts +83 -0
- package/test/paymaster-production-test.ts +217 -0
- package/tsconfig.json +5 -0
- package/tsconfig.tsbuildinfo +1 -1
package/.env
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Your wallet private key (must have funds for initial deposit/gas if needed)
|
|
2
|
+
PRIVATE_KEY=0x26a4dd6463c220236d0b5394674c4a9f352b327f5bc2b7849b6a140adda29c76
|
|
3
|
+
|
|
4
|
+
# Base Mainnet RPC URL (e.g. from Alchemy, Infura, or public)
|
|
5
|
+
RPC_URL=https://mainnet.base.org
|
|
6
|
+
|
|
7
|
+
# The Paymaster URL you want to test
|
|
8
|
+
PAYMASTER_URL=https://paymaster.a10m.work/v1/paymaster
|
|
9
|
+
|
|
10
|
+
# Your Paymaster API Key
|
|
11
|
+
A2A_PAYMASTER_API_KEY=8afe8ba70764f0ba24698d63edaf5909b2ad263756cbefff801357d7d1d039df
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ A2A Payment SDK for managing ERC-4337 Smart Accounts, Session Keys, and Gas Spon
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npm install @swimmingkiim/pay-sdk viem permissionless
|
|
15
|
+
npm install @swimmingkiim/pay-sdk viem@2.7.1 permissionless@^0.2.14
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
@@ -38,8 +38,8 @@ export class SmartAccountManager {
|
|
|
38
38
|
estimateFeesPerGas: async () => {
|
|
39
39
|
const fees = await this.publicClient.estimateFeesPerGas();
|
|
40
40
|
return {
|
|
41
|
-
maxFeePerGas: (fees.maxFeePerGas * 20n) / 10n, // 2x (safety margin)
|
|
42
|
-
maxPriorityFeePerGas: (fees.maxPriorityFeePerGas * 20n) / 10n
|
|
41
|
+
maxFeePerGas: ((fees.maxFeePerGas ?? 0n) * 20n) / 10n, // 2x (safety margin)
|
|
42
|
+
maxPriorityFeePerGas: ((fees.maxPriorityFeePerGas ?? 0n) * 20n) / 10n
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"smart-account.js","sourceRoot":"","sources":["../../src/account/smart-account.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,OAAO,EAAgG,IAAI,EAAE,MAAM,MAAM,CAAA;AACzH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAI/D,MAAM,OAAO,mBAAmB;IAKhB;IACA;IACA;IACA;IAPL,MAAM,CAAK;IACX,OAAO,CAAK;IAEnB,YACY,MAA+C,EAC/C,YAA4C,EAC5C,MAAc,EACd,SAA4B;QAH5B,WAAM,GAAN,MAAM,CAAyC;QAC/C,iBAAY,GAAZ,YAAY,CAAgC;QAC5C,WAAM,GAAN,MAAM,CAAQ;QACd,cAAS,GAAT,SAAS,CAAmB;IACpC,CAAC;IAEL,KAAK,CAAC,iBAAiB,CAAC,YAAoB,EAAE;QAC1C,sCAAsC;QACtC,IAAI,CAAC,OAAO,GAAG,MAAM,kBAAkB,CAAC;YACpC,MAAM,EAAE,IAAI,CAAC,YAAY;YACzB,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YAC7B,OAAO,EAAE,OAAO;YAChB,UAAU,EAAE;gBACR,OAAO,EAAE,4CAA4C,EAAE,iBAAiB;gBACxE,OAAO,EAAE,KAAK;aACjB;YACD,SAAS;SACZ,CAAC,CAAA;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,CAAC;QAC3C,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,wBAAwB,CAAC;YACnC,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;YACxB,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,CAAC;YACrD,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;YAClE,aAAa,EAAE;gBACX,kBAAkB,EAAE,KAAK,IAAI,EAAE;oBAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,kBAAkB,EAAE,CAAC;oBAC1D,OAAO;wBACH,YAAY,EAAE,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"smart-account.js","sourceRoot":"","sources":["../../src/account/smart-account.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fee configuration for PaymasterManager
|
|
3
|
+
*/
|
|
4
|
+
export interface FeeConfig {
|
|
5
|
+
treasury: string;
|
|
6
|
+
amount: bigint;
|
|
7
|
+
tokenType: 'USDC' | 'COMP';
|
|
8
|
+
tokenAddress?: string;
|
|
9
|
+
}
|
|
1
10
|
export declare class PaymasterManager {
|
|
2
11
|
private client;
|
|
3
12
|
private apiKey?;
|
|
@@ -7,14 +16,30 @@ export declare class PaymasterManager {
|
|
|
7
16
|
getStubPaymasterData(userOp: any): Promise<any>;
|
|
8
17
|
/**
|
|
9
18
|
* Appends a fee transfer transaction to the list of calls.
|
|
19
|
+
*
|
|
20
|
+
* Supports dual-token economy: USDC (default) or COMP.
|
|
21
|
+
*
|
|
10
22
|
* @param calls Array of transaction calls { to, value, data }
|
|
11
|
-
* @param feeConfig Configuration for the fee
|
|
23
|
+
* @param feeConfig Configuration for the fee
|
|
12
24
|
* @returns New array of calls with the fee transaction appended
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // USDC fee (legacy)
|
|
28
|
+
* const calls = PaymasterManager.appendFeeToCalls([], {
|
|
29
|
+
* treasury: '0x...',
|
|
30
|
+
* amount: 100000n, // 0.1 USDC (6 decimals)
|
|
31
|
+
* tokenType: 'USDC'
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* // COMP fee (new)
|
|
36
|
+
* const calls = PaymasterManager.appendFeeToCalls([], {
|
|
37
|
+
* treasury: '0x...',
|
|
38
|
+
* amount: 25n * 10n**18n, // 25 COMP (18 decimals)
|
|
39
|
+
* tokenType: 'COMP'
|
|
40
|
+
* });
|
|
13
41
|
*/
|
|
14
|
-
static
|
|
15
|
-
|
|
16
|
-
amount: bigint;
|
|
17
|
-
token: string;
|
|
18
|
-
}): any[];
|
|
42
|
+
static TOKEN_ADDRESSES: Record<string, string>;
|
|
43
|
+
static appendFeeToCalls(calls: any[], feeConfig: FeeConfig): any[];
|
|
19
44
|
}
|
|
20
45
|
//# sourceMappingURL=paymaster.d.ts.map
|
|
@@ -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;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
|
|
1
|
+
{"version":3,"file":"paymaster.d.ts","sourceRoot":"","sources":["../../src/paymaster/paymaster.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,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;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAG5C;IAGF,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,SAAS;CAwB7D"}
|
|
@@ -28,27 +28,49 @@ export class PaymasterManager {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Appends a fee transfer transaction to the list of calls.
|
|
31
|
+
*
|
|
32
|
+
* Supports dual-token economy: USDC (default) or COMP.
|
|
33
|
+
*
|
|
31
34
|
* @param calls Array of transaction calls { to, value, data }
|
|
32
|
-
* @param feeConfig Configuration for the fee
|
|
35
|
+
* @param feeConfig Configuration for the fee
|
|
33
36
|
* @returns New array of calls with the fee transaction appended
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // USDC fee (legacy)
|
|
40
|
+
* const calls = PaymasterManager.appendFeeToCalls([], {
|
|
41
|
+
* treasury: '0x...',
|
|
42
|
+
* amount: 100000n, // 0.1 USDC (6 decimals)
|
|
43
|
+
* tokenType: 'USDC'
|
|
44
|
+
* });
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* // COMP fee (new)
|
|
48
|
+
* const calls = PaymasterManager.appendFeeToCalls([], {
|
|
49
|
+
* treasury: '0x...',
|
|
50
|
+
* amount: 25n * 10n**18n, // 25 COMP (18 decimals)
|
|
51
|
+
* tokenType: 'COMP'
|
|
52
|
+
* });
|
|
34
53
|
*/
|
|
54
|
+
static TOKEN_ADDRESSES = {
|
|
55
|
+
'USDC': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
|
|
56
|
+
'COMP': '0xED175F6ff582318b6DC16FE76e8B5CA7F8fB3Ce3', // ComputeToken on Base Sepolia
|
|
57
|
+
};
|
|
35
58
|
static appendFeeToCalls(calls, feeConfig) {
|
|
36
|
-
//
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (config.treasury === '0x0000000000000000000000000000000000000000') {
|
|
59
|
+
// Use custom address if provided, otherwise use default from static map
|
|
60
|
+
const tokenAddress = feeConfig.tokenAddress || PaymasterManager.TOKEN_ADDRESSES[feeConfig.tokenType];
|
|
61
|
+
if (!tokenAddress) {
|
|
62
|
+
throw new Error(`Token address not found for type: ${feeConfig.tokenType}. Please provide tokenAddress in config or update PaymasterManager.TOKEN_ADDRESSES.`);
|
|
63
|
+
}
|
|
64
|
+
if (feeConfig.treasury === '0x0000000000000000000000000000000000000000') {
|
|
43
65
|
console.warn("PaymasterManager: Treasury address is not set. Fee transaction might fail validation.");
|
|
44
66
|
}
|
|
45
67
|
const feeCall = {
|
|
46
|
-
to:
|
|
68
|
+
to: tokenAddress,
|
|
47
69
|
value: 0n,
|
|
48
70
|
data: encodeFunctionData({
|
|
49
71
|
abi: ERC20_ABI,
|
|
50
72
|
functionName: 'transfer',
|
|
51
|
-
args: [
|
|
73
|
+
args: [feeConfig.treasury, feeConfig.amount]
|
|
52
74
|
})
|
|
53
75
|
};
|
|
54
76
|
return [...calls, feeCall];
|
|
@@ -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;
|
|
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;AAa7F,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;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,eAAe,GAA2B;QAC7C,MAAM,EAAE,4CAA4C,EAAE,eAAe;QACrE,MAAM,EAAE,4CAA4C,EAAG,+BAA+B;KACzF,CAAC;IAGF,MAAM,CAAC,gBAAgB,CAAC,KAAY,EAAE,SAAoB;QACtD,wEAAwE;QACxE,MAAM,YAAY,GAAG,SAAS,CAAC,YAAY,IAAI,gBAAgB,CAAC,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAErG,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,SAAS,CAAC,SAAS,qFAAqF,CAAC,CAAC;QACnK,CAAC;QAED,IAAI,SAAS,CAAC,QAAQ,KAAK,4CAA4C,EAAE,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;QAC1G,CAAC;QAED,MAAM,OAAO,GAAG;YACZ,EAAE,EAAE,YAAmB;YACvB,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,kBAAkB,CAAC;gBACrB,GAAG,EAAE,SAAS;gBACd,YAAY,EAAE,UAAU;gBACxB,IAAI,EAAE,CAAC,SAAS,CAAC,QAAe,EAAE,SAAS,CAAC,MAAM,CAAC;aACtD,CAAC;SACL,CAAC;QAEF,OAAO,CAAC,GAAG,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC"}
|
|
@@ -45,7 +45,7 @@ export class PaymentVerifier {
|
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
47
|
// 2. Filter logs for the specified token contract
|
|
48
|
-
const tokenLogs = receipt.logs.filter(log => log.address.toLowerCase() === this.tokenAddress.toLowerCase());
|
|
48
|
+
const tokenLogs = receipt.logs.filter((log) => log.address.toLowerCase() === this.tokenAddress.toLowerCase());
|
|
49
49
|
if (tokenLogs.length === 0) {
|
|
50
50
|
return {
|
|
51
51
|
isValid: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-verifier.js","sourceRoot":"","sources":["../../src/payment/payment-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAkC,MAAM,MAAM,CAAC;AAE1G,MAAM,kBAAkB,GAAG,QAAQ,CAAC,CAAC,yEAAyE,CAAC,CAAC,CAAC;AAiBjH;;;GAGG;AACH,MAAM,OAAO,eAAe;IAChB,YAAY,CAAiC;IAC7C,YAAY,CAAgB;IAEpC;;;OAGG;IACH,YAAY,MAA6B;QACrC,IAAI,CAAC,YAAY,GAAG,kBAAkB,CAAC;YACnC,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;SACjC,CAAC,CAAC;QAEH,2CAA2C;QAC3C,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,4CAA4C,CAAC;IAC5F,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,aAAa,CACf,MAAqB,EACrB,YAA2B,EAC3B,UAAyB,EACzB,aAAqB;QAErB,IAAI,CAAC;YACD,6BAA6B;YAC7B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,qBAAqB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAEhF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACX,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,uBAAuB;iBACjC,CAAC;YACN,CAAC;YAED,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/B,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,oBAAoB;oBAC3B,MAAM;iBACT,CAAC;YACN,CAAC;YAED,kDAAkD;YAClD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,
|
|
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.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/swimmingkiim/a2a-project.git"
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@rhinestone/module-sdk": "^0.4.0",
|
|
13
13
|
"permissionless": "^0.2.14",
|
|
14
|
-
"viem": "
|
|
14
|
+
"viem": "2.7.1",
|
|
15
15
|
"zod": "^3.22.4"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
@@ -43,8 +43,8 @@ export class SmartAccountManager {
|
|
|
43
43
|
estimateFeesPerGas: async () => {
|
|
44
44
|
const fees = await this.publicClient.estimateFeesPerGas();
|
|
45
45
|
return {
|
|
46
|
-
maxFeePerGas: (fees.maxFeePerGas * 20n) / 10n, // 2x (safety margin)
|
|
47
|
-
maxPriorityFeePerGas: (fees.maxPriorityFeePerGas * 20n) / 10n
|
|
46
|
+
maxFeePerGas: ((fees.maxFeePerGas ?? 0n) * 20n) / 10n, // 2x (safety margin)
|
|
47
|
+
maxPriorityFeePerGas: ((fees.maxPriorityFeePerGas ?? 0n) * 20n) / 10n
|
|
48
48
|
} as any;
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -4,6 +4,16 @@ import { http, encodeFunctionData, parseAbi, Hex } from "viem"
|
|
|
4
4
|
const ERC20_ABI = parseAbi(['function transfer(address to, uint256 amount) returns (bool)']);
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Fee configuration for PaymasterManager
|
|
9
|
+
*/
|
|
10
|
+
export interface FeeConfig {
|
|
11
|
+
treasury: string;
|
|
12
|
+
amount: bigint;
|
|
13
|
+
tokenType: 'USDC' | 'COMP';
|
|
14
|
+
tokenAddress?: string; // Optional override for custom token address
|
|
15
|
+
}
|
|
16
|
+
|
|
7
17
|
export class PaymasterManager {
|
|
8
18
|
private client: any
|
|
9
19
|
private apiKey?: string
|
|
@@ -37,29 +47,54 @@ export class PaymasterManager {
|
|
|
37
47
|
|
|
38
48
|
/**
|
|
39
49
|
* Appends a fee transfer transaction to the list of calls.
|
|
50
|
+
*
|
|
51
|
+
* Supports dual-token economy: USDC (default) or COMP.
|
|
52
|
+
*
|
|
40
53
|
* @param calls Array of transaction calls { to, value, data }
|
|
41
|
-
* @param feeConfig Configuration for the fee
|
|
54
|
+
* @param feeConfig Configuration for the fee
|
|
42
55
|
* @returns New array of calls with the fee transaction appended
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // USDC fee (legacy)
|
|
59
|
+
* const calls = PaymasterManager.appendFeeToCalls([], {
|
|
60
|
+
* treasury: '0x...',
|
|
61
|
+
* amount: 100000n, // 0.1 USDC (6 decimals)
|
|
62
|
+
* tokenType: 'USDC'
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // COMP fee (new)
|
|
67
|
+
* const calls = PaymasterManager.appendFeeToCalls([], {
|
|
68
|
+
* treasury: '0x...',
|
|
69
|
+
* amount: 25n * 10n**18n, // 25 COMP (18 decimals)
|
|
70
|
+
* tokenType: 'COMP'
|
|
71
|
+
* });
|
|
43
72
|
*/
|
|
44
|
-
static
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
73
|
+
static TOKEN_ADDRESSES: Record<string, string> = {
|
|
74
|
+
'USDC': '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', // USDC on Base
|
|
75
|
+
'COMP': '0xED175F6ff582318b6DC16FE76e8B5CA7F8fB3Ce3', // ComputeToken on Base Sepolia
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
static appendFeeToCalls(calls: any[], feeConfig: FeeConfig) {
|
|
80
|
+
// Use custom address if provided, otherwise use default from static map
|
|
81
|
+
const tokenAddress = feeConfig.tokenAddress || PaymasterManager.TOKEN_ADDRESSES[feeConfig.tokenType];
|
|
82
|
+
|
|
83
|
+
if (!tokenAddress) {
|
|
84
|
+
throw new Error(`Token address not found for type: ${feeConfig.tokenType}. Please provide tokenAddress in config or update PaymasterManager.TOKEN_ADDRESSES.`);
|
|
85
|
+
}
|
|
51
86
|
|
|
52
|
-
if (
|
|
87
|
+
if (feeConfig.treasury === '0x0000000000000000000000000000000000000000') {
|
|
53
88
|
console.warn("PaymasterManager: Treasury address is not set. Fee transaction might fail validation.");
|
|
54
89
|
}
|
|
55
90
|
|
|
56
91
|
const feeCall = {
|
|
57
|
-
to:
|
|
92
|
+
to: tokenAddress as Hex,
|
|
58
93
|
value: 0n,
|
|
59
94
|
data: encodeFunctionData({
|
|
60
95
|
abi: ERC20_ABI,
|
|
61
96
|
functionName: 'transfer',
|
|
62
|
-
args: [
|
|
97
|
+
args: [feeConfig.treasury as Hex, feeConfig.amount]
|
|
63
98
|
})
|
|
64
99
|
};
|
|
65
100
|
|
|
@@ -73,7 +73,7 @@ export class PaymentVerifier {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
// 2. Filter logs for the specified token contract
|
|
76
|
-
const tokenLogs = receipt.logs.filter(log =>
|
|
76
|
+
const tokenLogs = receipt.logs.filter((log: any) =>
|
|
77
77
|
log.address.toLowerCase() === this.tokenAddress.toLowerCase()
|
|
78
78
|
);
|
|
79
79
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
import { createPublicClient, http } from 'viem';
|
|
3
|
+
import { base } from 'viem/chains';
|
|
4
|
+
|
|
5
|
+
const PAYMASTER_URL = 'https://paymaster.a10m.work/v1/paymaster';
|
|
6
|
+
const API_KEY = process.env.A2A_PAYMASTER_API_KEY;
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
console.log('🏥 Paymaster Service Health Check');
|
|
10
|
+
console.log('='.repeat(40));
|
|
11
|
+
console.log(`URL: ${PAYMASTER_URL}`);
|
|
12
|
+
|
|
13
|
+
if (!API_KEY) {
|
|
14
|
+
console.warn('⚠️ A2A_PAYMASTER_API_KEY not set. Auth tests may fail.');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 1. Health Check (GET /health)
|
|
18
|
+
console.log('\n1. Checking /health endpoint...');
|
|
19
|
+
try {
|
|
20
|
+
const healthRes = await fetch('https://paymaster.a10m.work/health');
|
|
21
|
+
console.log(` Status: ${healthRes.status} ${healthRes.statusText}`);
|
|
22
|
+
if (healthRes.ok) {
|
|
23
|
+
console.log(' ✅ Health check passed');
|
|
24
|
+
} else {
|
|
25
|
+
console.error(' ❌ Health check failed');
|
|
26
|
+
}
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error(' ❌ Connection failed:', e);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 2. Auth Check (Invalid Key)
|
|
32
|
+
console.log('\n2. Testing Invalid API Key...');
|
|
33
|
+
try {
|
|
34
|
+
const badRes = await fetch(PAYMASTER_URL, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: { 'Content-Type': 'application/json', 'x-api-key': 'invalid-key' },
|
|
37
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_chainId', params: [] })
|
|
38
|
+
});
|
|
39
|
+
console.log(` Status: ${badRes.status} ${badRes.statusText}`);
|
|
40
|
+
if (badRes.status === 401) {
|
|
41
|
+
console.log(' ✅ Correctly rejected invalid key');
|
|
42
|
+
} else {
|
|
43
|
+
console.warn(` ⚠️ Unexpected status: ${badRes.status}`);
|
|
44
|
+
}
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error(' ❌ Auth test failed:', e);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 3. Chain ID Check (Valid Key)
|
|
50
|
+
console.log('\n3. Testing Valid API Key (eth_chainId)...');
|
|
51
|
+
try {
|
|
52
|
+
const res = await fetch(PAYMASTER_URL, {
|
|
53
|
+
method: 'POST',
|
|
54
|
+
headers: { 'Content-Type': 'application/json', 'x-api-key': API_KEY || '' },
|
|
55
|
+
body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_chainId', params: [] })
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (res.ok) {
|
|
59
|
+
const data = await res.json();
|
|
60
|
+
console.log(' Response:', JSON.stringify(data));
|
|
61
|
+
if (data.result === '0x2105' || data.result === '8453') { // Base Mainnet Chain ID
|
|
62
|
+
console.log(' ✅ Chain ID matched (Base Mainnet)');
|
|
63
|
+
} else {
|
|
64
|
+
console.log(` ℹ️ Chain ID: ${data.result}`);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
console.error(` ❌ Request failed: ${res.status}`);
|
|
68
|
+
const text = await res.text();
|
|
69
|
+
console.error(' Body:', text);
|
|
70
|
+
}
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.error(' ❌ Chain ID test failed:', e);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log('\n' + '='.repeat(40));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { PaymasterManager, FeeConfig } from '../src/paymaster/paymaster';
|
|
3
|
+
import { encodeFunctionData, parseAbi } from 'viem';
|
|
4
|
+
|
|
5
|
+
describe('PaymasterManager.appendFeeToCalls', () => {
|
|
6
|
+
it('should append USDC fee call correctly', () => {
|
|
7
|
+
const calls: any[] = [];
|
|
8
|
+
const feeConfig: FeeConfig = {
|
|
9
|
+
treasury: '0x1234567890123456789012345678901234567890',
|
|
10
|
+
amount: 100000n, // 0.1 USDC
|
|
11
|
+
tokenType: 'USDC'
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const result = PaymasterManager.appendFeeToCalls(calls, feeConfig);
|
|
15
|
+
|
|
16
|
+
expect(result.length).toBe(1);
|
|
17
|
+
expect(result[0].to).toBe('0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'); // USDC on Base
|
|
18
|
+
expect(result[0].value).toBe(0n);
|
|
19
|
+
|
|
20
|
+
// Verify transfer encoding
|
|
21
|
+
const ERC20_ABI = parseAbi(['function transfer(address to, uint256 amount) returns (bool)']);
|
|
22
|
+
const expectedData = encodeFunctionData({
|
|
23
|
+
abi: ERC20_ABI,
|
|
24
|
+
functionName: 'transfer',
|
|
25
|
+
args: [feeConfig.treasury, feeConfig.amount]
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(result[0].data).toBe(expectedData);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should append COMP fee call correctly', () => {
|
|
32
|
+
const calls: any[] = [];
|
|
33
|
+
const feeConfig: FeeConfig = {
|
|
34
|
+
treasury: '0x1234567890123456789012345678901234567890',
|
|
35
|
+
amount: 25n * 10n ** 18n, // 25 COMP
|
|
36
|
+
tokenType: 'COMP'
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const result = PaymasterManager.appendFeeToCalls(calls, feeConfig);
|
|
40
|
+
|
|
41
|
+
expect(result.length).toBe(1);
|
|
42
|
+
expect(result[0].to).toBe('0xED175F6ff582318b6DC16FE76e8B5CA7F8fB3Ce3'); // COMP on Base Sepolia
|
|
43
|
+
expect(result[0].value).toBe(0n);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should support custom token address override', () => {
|
|
47
|
+
const customTokenAddress = '0x9999999999999999999999999999999999999999';
|
|
48
|
+
const calls: any[] = [];
|
|
49
|
+
const feeConfig: FeeConfig = {
|
|
50
|
+
treasury: '0x1234567890123456789012345678901234567890',
|
|
51
|
+
amount: 100000n,
|
|
52
|
+
tokenType: 'USDC',
|
|
53
|
+
tokenAddress: customTokenAddress
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const result = PaymasterManager.appendFeeToCalls(calls, feeConfig);
|
|
57
|
+
|
|
58
|
+
expect(result.length).toBe(1);
|
|
59
|
+
expect(result[0].to).toBe(customTokenAddress);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should preserve existing calls', () => {
|
|
63
|
+
const existingCall = {
|
|
64
|
+
to: '0xabcd...',
|
|
65
|
+
value: 0n,
|
|
66
|
+
data: '0x1234'
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const calls = [existingCall];
|
|
70
|
+
|
|
71
|
+
const feeConfig: FeeConfig = {
|
|
72
|
+
treasury: '0x1234567890123456789012345678901234567890',
|
|
73
|
+
amount: 100000n,
|
|
74
|
+
tokenType: 'USDC'
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const result = PaymasterManager.appendFeeToCalls(calls, feeConfig);
|
|
78
|
+
|
|
79
|
+
expect(result.length).toBe(2);
|
|
80
|
+
expect(result[0]).toBe(existingCall); // Original call preserved
|
|
81
|
+
expect(result[1].to).toBe('0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'); // Fee call appended
|
|
82
|
+
});
|
|
83
|
+
});
|