gokite-aa-sdk 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,7 @@ import { ethers } from 'ethers';
18
18
  const sdk = new GokiteAASDK(
19
19
  'kite_testnet',
20
20
  'https://rpc-testnet.gokite.ai',
21
- 'https://bundler-service.staging.gokite.ai/rpc/' // bundler URL
21
+ 'http://localhost:14337/rpc/' // bundler URL
22
22
  );
23
23
 
24
24
  // Owner address (from your social login SDK)
package/dist/config.d.ts CHANGED
@@ -5,5 +5,10 @@ export interface NetworkConfig {
5
5
  accountImplementation: string;
6
6
  bundlerUrl?: string;
7
7
  paymaster?: string;
8
+ supportedTokens: {
9
+ address: string;
10
+ symbol: string;
11
+ decimals: number;
12
+ }[];
8
13
  }
9
14
  export declare const NETWORKS: Record<string, NetworkConfig>;
package/dist/config.js CHANGED
@@ -7,6 +7,10 @@ exports.NETWORKS = {
7
7
  entryPoint: '0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108',
8
8
  accountFactory: '0xF0Fc19F0dc393867F19351d25EDfc5E099561cb7',
9
9
  accountImplementation: '0x93F5310eFd0f09db0666CA5146E63CA6Cdc6FC21',
10
- paymaster: '0x122E0e1F7fFc0f5d64F5470CF42c6bA0abdF7158',
10
+ paymaster: '0x9Adcbf85D5c724611a490Ba9eDc4d38d6F39e92d',
11
+ supportedTokens: [
12
+ { address: '0x0000000000000000000000000000000000000000', symbol: 'KITE', decimals: 18 },
13
+ { address: '0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63', symbol: 'Test USD', decimals: 18 },
14
+ ],
11
15
  },
12
16
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ethers_1 = require("ethers");
4
+ const gokite_aa_sdk_1 = require("./gokite-aa-sdk");
5
+ async function simpleExample() {
6
+ const sdk = new gokite_aa_sdk_1.GokiteAASDK('kite_testnet', 'https://rpc-testnet.gokite.ai', 'https://bundler-service.staging.gokite.ai/rpc/');
7
+ const signer = new ethers_1.ethers.Wallet(process.env.PRIVATE_KEY);
8
+ const request = {
9
+ target: '0x0000000000000000000000000000000000000000',
10
+ value: BigInt(0),
11
+ callData: '0x'
12
+ };
13
+ console.log('📊 Estimate transaction...');
14
+ const estimate = await sdk.estimateUserOperation(signer.address, request);
15
+ console.log('Total cost:', estimate.totalCostKITEFormatted);
16
+ console.log('Cost with token:', estimate.supportedTokens);
17
+ console.log('Sponsorship available:', estimate.sponsorshipAvailable);
18
+ console.log('Remaining sponsorships:', estimate.remainingSponsorships);
19
+ console.log('Payment options:', estimate.supportedTokens.map(t => `${t.tokenSymbol}: ${t.formattedCost}`));
20
+ // Step 2: Select payment method and execute
21
+ const tokenAddress = estimate.sponsorshipAvailable
22
+ ? '0x0000000000000000000000000000000000000000' // Use sponsorship/KITE
23
+ : '0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63'; // Use Test USD
24
+ console.log('\n🚀 Execute transaction...');
25
+ const result = await sdk.sendUserOperationWithPayment(signer.address, request, estimate.userOp, tokenAddress, async (hash) => signer.signMessage(ethers_1.ethers.getBytes(hash)));
26
+ console.log('✅ Done!');
27
+ console.log('UserOp Hash:', result.userOpHash);
28
+ console.log('Status:', result.status.status);
29
+ }
30
+ // Run
31
+ if (require.main === module) {
32
+ simpleExample().catch(console.error);
33
+ }
package/dist/example.d.ts CHANGED
@@ -1,47 +1,181 @@
1
1
  import { GokiteAASDK } from './gokite-aa-sdk';
2
2
  import "dotenv/config";
3
+ declare function initializeSDK(): GokiteAASDK;
3
4
  declare function handleAAError(error: any): {
4
5
  type: string;
5
6
  message: string;
6
7
  details?: any;
7
8
  };
8
9
  /**
9
- * ClientAgentVault Integration Tests
10
+ * Transfer ERC20 tokens from AA wallet to another address
11
+ * 从AA钱包转账ERC20代币到其他地址
10
12
  *
11
- * these tests show how to use the AA wallet to:
12
- * 1. deploy the ClientAgentVault proxy contract (via performCreate)
13
- * 2. configure spending rules (Spending Rules)
14
- * 3. view spending rules (read-only)
15
- * 4. withdraw funds (withdrawFunds)
16
- * 5. check token balance (read-only)
13
+ * @param eoa - User's EOA address (from Privy)
14
+ * @param to - Recipient address
15
+ * @param amount - Amount to transfer
16
+ * @param tokenAddress - Token contract address
17
+ * @param tokenDecimals - Token decimals (usually 18)
18
+ * @param signFunction - Signing function from Privy
19
+ */
20
+ export declare function transferERC20(eoa: string, to: string, amount: string, tokenAddress: string, tokenDecimals: number | undefined, signFunction: (userOpHash: string) => Promise<string>): Promise<{
21
+ success: boolean;
22
+ transactionHash: string | undefined;
23
+ message: string;
24
+ error?: undefined;
25
+ } | {
26
+ success: boolean;
27
+ error: string | undefined;
28
+ message: string;
29
+ transactionHash?: undefined;
30
+ } | {
31
+ success: boolean;
32
+ error: {
33
+ type: string;
34
+ message: string;
35
+ details?: any;
36
+ };
37
+ message: string;
38
+ transactionHash?: undefined;
39
+ }>;
40
+ /**
41
+ * 部署KitePass合约
17
42
  *
18
- * how to use:
19
- * - modify the contract addresses and parameters as needed
43
+ * @param eoa - User's EOA address
44
+ * @param signFunction - Signing function from Privy
45
+ * @returns Deployed KitePass address
20
46
  */
21
- declare function clientAgentVaultIntegrationTests(): Promise<void>;
47
+ export declare function deployKitePass(eoa: string, signFunction: (userOpHash: string) => Promise<string>): Promise<{
48
+ success: boolean;
49
+ proxyAddress?: string;
50
+ error?: any;
51
+ }>;
22
52
  /**
23
- * Test 1: Deploy ClientAgentVault Proxy via AA wallet's performCreate
53
+ * Configure spending rules for KitePass
54
+ * setSpendingRules方法会先清除现有的rules,然后设置新的rules
55
+ * 1. 新增/修改:需要先获取现有的rules,然后append新的rules,或者在现有rules的基础上修改
56
+ * 2. 删除:需要先获取现有的rules,然后删除对应的rules
57
+ *
58
+ * @param eoa - User's EOA address
59
+ * @param kitepassAddress - KitePass proxy address
60
+ * @param rules - Spending rules to configure
61
+ * @param signFunction - Signing function
62
+ */
63
+ export declare function configureSpendingRules(eoa: string, kitepassAddress: string, signFunction: (userOpHash: string) => Promise<string>): Promise<{
64
+ success: boolean;
65
+ transactionHash: string | undefined;
66
+ error?: undefined;
67
+ } | {
68
+ success: boolean;
69
+ error: string | undefined;
70
+ transactionHash?: undefined;
71
+ } | {
72
+ success: boolean;
73
+ error: {
74
+ type: string;
75
+ message: string;
76
+ details?: any;
77
+ };
78
+ transactionHash?: undefined;
79
+ }>;
80
+ /**
81
+ * View current spending rules (read-only)
82
+ * 查看当前消费规则(只读)
24
83
  */
25
- declare function DeployClientAgentVaultProxy(sdk: GokiteAASDK, eoa: string, aa: string, signFunction: any): Promise<string | null>;
84
+ export declare function viewSpendingRules(kitepassAddress: string): Promise<{
85
+ success: boolean;
86
+ rules: any;
87
+ error?: undefined;
88
+ } | {
89
+ success: boolean;
90
+ error: string;
91
+ rules?: undefined;
92
+ }>;
26
93
  /**
27
- * Test 2: Configure Spending Rules
94
+ * Withdraw funds from KitePass
95
+ * 从KitePass提取资金
28
96
  */
29
- declare function ConfigureSpendingRules(sdk: GokiteAASDK, owner: string, proxyAddress: string, signFunction: any): Promise<void>;
97
+ export declare function withdrawFunds(eoa: string, kitepassAddress: string, amount: string, tokenAddress: string | undefined, signFunction: (userOpHash: string) => Promise<string>): Promise<{
98
+ success: boolean;
99
+ transactionHash: string | undefined;
100
+ error?: undefined;
101
+ } | {
102
+ success: boolean;
103
+ error: string | undefined;
104
+ transactionHash?: undefined;
105
+ } | {
106
+ success: boolean;
107
+ error: {
108
+ type: string;
109
+ message: string;
110
+ details?: any;
111
+ };
112
+ transactionHash?: undefined;
113
+ }>;
30
114
  /**
31
- * Test 3: View Spending Rules (Read-only, no transaction sent)
115
+ * Check token balance (read-only)
116
+ * 查看代币余额(只读)
32
117
  */
33
- declare function ViewSpendingRules(sdk: GokiteAASDK, proxyAddress: string): Promise<void>;
118
+ export declare function checkTokenBalance(address: string, tokenAddress?: string): Promise<{
119
+ success: boolean;
120
+ balance: string;
121
+ symbol: any;
122
+ decimals: any;
123
+ address: string;
124
+ error?: undefined;
125
+ } | {
126
+ success: boolean;
127
+ error: string;
128
+ balance?: undefined;
129
+ symbol?: undefined;
130
+ decimals?: undefined;
131
+ address?: undefined;
132
+ }>;
133
+ export interface ServiceInfo {
134
+ serviceOwner: string;
135
+ priceModel: number;
136
+ unitPrice: number;
137
+ provider: string;
138
+ metadata: string;
139
+ name: string;
140
+ isPublic: boolean;
141
+ }
34
142
  /**
35
- * Test 4: Withdraw Funds
143
+ * Register a service in the service registry
144
+ * 在服务注册表中注册服务
145
+ *
146
+ * @param eoa - Service owner's EOA address
147
+ * @param serviceId - Service ID (bytes32)
148
+ * @param serviceInfo - Service information
149
+ * @param signFunction - Signing function
36
150
  */
37
- declare function WithdrawFunds(sdk: GokiteAASDK, owner: string, proxyAddress: string, signFunction: any): Promise<void>;
151
+ export declare function registerService(eoa: string, serviceId: string, serviceInfo: ServiceInfo, signFunction: (userOpHash: string) => Promise<string>): Promise<{
152
+ success: boolean;
153
+ transactionHash: string | undefined;
154
+ serviceId: string;
155
+ error?: undefined;
156
+ } | {
157
+ success: boolean;
158
+ error: string | undefined;
159
+ transactionHash?: undefined;
160
+ serviceId?: undefined;
161
+ } | {
162
+ success: boolean;
163
+ error: {
164
+ type: string;
165
+ message: string;
166
+ details?: any;
167
+ };
168
+ transactionHash?: undefined;
169
+ serviceId?: undefined;
170
+ }>;
38
171
  /**
39
- * Test 5: Check Token Balance (Read-only)
172
+ * Get TransparentUpgradeableProxy bytecode
173
+ * 获取透明可升级代理字节码
40
174
  */
41
- declare function CheckTokenBalance(sdk: GokiteAASDK, proxyAddress: string): Promise<void>;
175
+ declare function getTransparentProxyBytecode(): string;
42
176
  /**
43
- * Legacy example for basic AA operations
177
+ * Parse ContractCreated event from transaction logs
178
+ * 从交易日志中解析合约创建事件
44
179
  */
45
- declare function basicExample(): Promise<void>;
46
- export { clientAgentVaultIntegrationTests, basicExample, DeployClientAgentVaultProxy, ConfigureSpendingRules, ViewSpendingRules, WithdrawFunds, CheckTokenBalance, handleAAError, };
47
- export declare const example: typeof basicExample;
180
+ declare function parseContractCreatedEvent(transactionHash: string): Promise<string | null>;
181
+ export { initializeSDK, handleAAError, getTransparentProxyBytecode, parseContractCreatedEvent };
package/dist/example.js CHANGED
@@ -1,16 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.example = exports.handleAAError = exports.CheckTokenBalance = exports.WithdrawFunds = exports.ViewSpendingRules = exports.ConfigureSpendingRules = exports.DeployClientAgentVaultProxy = exports.basicExample = exports.clientAgentVaultIntegrationTests = void 0;
3
+ exports.parseContractCreatedEvent = exports.getTransparentProxyBytecode = exports.handleAAError = exports.initializeSDK = exports.registerService = exports.checkTokenBalance = exports.withdrawFunds = exports.viewSpendingRules = exports.configureSpendingRules = exports.deployKitePass = exports.transferERC20 = void 0;
4
4
  const gokite_aa_sdk_1 = require("./gokite-aa-sdk");
5
5
  const types_1 = require("./types");
6
6
  const ethers_1 = require("ethers");
7
7
  require("dotenv/config");
8
+ /**
9
+ * Sections:
10
+ * 1. General Use - ERC20 Token Transfer (通用功能 - ERC20代币转账)
11
+ * 2. KitePass Related - ClientAgentVault Operations (KitePass相关 - 客户端代理金库操作)
12
+ * 3. Subnet Related - Subnet Management (子网相关 - 子网管理)
13
+ * 4. Service Related - Service Registry Operations (服务相关 - 服务注册表操作)
14
+ */
8
15
  // Contract addresses on kite_testnet
9
16
  const ADDRESSES = {
10
17
  SETTLEMENT_TOKEN: '0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63',
11
18
  SETTLEMENT_CONTRACT: '0x8d9FaD78d5Ce247aA01C140798B9558fd64a63E3',
12
- CLIENT_AGENT_VAULT_IMPL: '0xB5AAFCC6DD4DFc2B80fb8BCcf406E1a2Fd559e23'
19
+ CLIENT_AGENT_VAULT_IMPL: '0xB5AAFCC6DD4DFc2B80fb8BCcf406E1a2Fd559e23',
20
+ SERVICE_REGISTRY: '0xF727EDE22C9e338a7d1d57B930dcEBbC6a66c008'
13
21
  };
22
+ // SDK initialization - 初始化SDK
23
+ function initializeSDK() {
24
+ return new gokite_aa_sdk_1.GokiteAASDK('kite_testnet', 'https://rpc-testnet.gokite.ai', 'https://bundler-service.staging.gokite.ai/rpc/');
25
+ }
26
+ exports.initializeSDK = initializeSDK;
14
27
  function handleAAError(error) {
15
28
  if (error instanceof types_1.AASDKError) {
16
29
  return {
@@ -19,7 +32,6 @@ function handleAAError(error) {
19
32
  details: error.details
20
33
  };
21
34
  }
22
- // Fallback for other errors
23
35
  return {
24
36
  type: 'UNKNOWN_ERROR',
25
37
  message: error.message || 'An unknown error occurred',
@@ -27,142 +39,146 @@ function handleAAError(error) {
27
39
  };
28
40
  }
29
41
  exports.handleAAError = handleAAError;
42
+ // =============================================================================
43
+ // 1. GENERAL USE - ERC20 Token Transfer
44
+ // 通用功能 - ERC20代币转账
45
+ // =============================================================================
30
46
  /**
31
- * Get TransparentUpgradeableProxy bytecode
32
- */
33
- function getTransparentProxyBytecode() {
34
- // This is the bytecode for TransparentUpgradeableProxy
35
- return '0x60a0604052610b278038038061001481610293565b928339810160608282031261028e5761002c826102b8565b610038602084016102b8565b604084015190936001600160401b03821161028e570182601f8201121561028e5780519061006d610068836102cc565b610293565b938285526020838301011161028e5760005b828110610279575050602060009184010152803b15610258577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0383169081179091557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a281511561023f5760008083602061013595519101845af43d15610237573d91610125610068846102cc565b9283523d6000602085013e6102e7565b505b604051906104918083016001600160401b0381118482101761022157602092849261067684396001600160a01b031681520301906000f080156102155760018060a01b031680608052600080516020610b07833981519152547f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6040805160018060a01b0384168152846020820152a181156101ff576001600160a01b03191617600080516020610b078339815191525560405161032d908161034982396080518160070152f35b633173bdd160e11b600052600060045260246000fd5b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b6060916102e7565b505034156101375763b398979f60e01b60005260046000fd5b634c9c8ce360e01b60009081526001600160a01b0391909116600452602490fd5b8060208092840101518282880101520161007f565b600080fd5b6040519190601f01601f191682016001600160401b0381118382101761022157604052565b51906001600160a01b038216820361028e57565b6001600160401b03811161022157601f01601f191660200190565b9061030d57508051156102fc57805190602001fd5b630a12f52160e11b60005260046000fd5b8151158061033f575b61031e575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561031656fe6080604052337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603610069576000356001600160e01b03191663278f794360e11b1461005f576334ad5dbb60e21b60005260046000fd5b610067610113565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460009081906001600160a01b0316368280378136915af43d6000803e156100b1573d6000f35b3d6000fd5b634e487b7160e01b600052604160045260246000fd5b6040519190601f01601f1916820167ffffffffffffffff8111838210176100f257604052565b6100b6565b67ffffffffffffffff81116100f257601f01601f191660200190565b3660041161019d57604036600319011261019d576004356001600160a01b0381169081900361019d576024359067ffffffffffffffff821161019d573660238301121561019d5781600401359061017161016c836100f7565b6100cc565b91808352366024828601011161019d57602081600092602461019b970183870137840101526101a2565b565b600080fd5b90813b15610239577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0384169081179091557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a280511561021f5761021c9161025b565b50565b50503461022857565b63b398979f60e01b60005260046000fd5b50634c9c8ce360e01b60009081526001600160a01b0391909116600452602490fd5b60008061028f93602081519101845af43d15610292573d9161027f61016c846100f7565b9283523d6000602085013e610296565b90565b6060915b906102bc57508051156102ab57805190602001fd5b630a12f52160e11b60005260046000fd5b815115806102ee575b6102cd575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b156102c556fea2646970667358221220597147005a6fe654561cbab25a93153cc233180473a65a90bd427f0c1f41018764736f6c634300081c003360803460bc57601f61049138819003918201601f19168301916001600160401b0383118484101760c15780849260209460405283398101031260bc57516001600160a01b0381169081900360bc57801560a657600080546001600160a01b031981168317825560405192916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36103b990816100d88239f35b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604052600436101561001257600080fd5b6000803560e01c8063715018a6146102875780638da5cb5b146102605780639623609d1461012f578063ad3cb1cc146100e25763f2fde38b1461005457600080fd5b346100df5760203660031901126100df576004356001600160a01b038116908190036100dd5761008261035a565b80156100c95781546001600160a01b03198116821783556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b631e4fbdf760e01b82526004829052602482fd5b505b80fd5b50346100df57806003193601126100df575061012b6040516101056040826102e1565b60058152640352e302e360dc1b6020820152604051918291602083526020830190610319565b0390f35b5060603660031901126100df576004356001600160a01b038116908190036100dd576024356001600160a01b038116908190036102405760443567ffffffffffffffff811161025c573660238201121561025c57806004013567ffffffffffffffff8111610248576040518593929091906101b4601f8301601f1916602001846102e1565b81835236602483830101116102445781859260246020930183860137830101526101dc61035a565b833b156102405761021293839260405180968194829363278f794360e11b84526004840152604060248401526044830190610319565b039134905af18015610233576102255780f35b61022e916102e1565b388180f35b50604051903d90823e3d90fd5b8280fd5b8480fd5b634e487b7160e01b85526041600452602485fd5b8380fd5b50346100df57806003193601126100df57546040516001600160a01b039091168152602090f35b50346100df57806003193601126100df576102a061035a565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b90601f8019910116810190811067ffffffffffffffff82111761030357604052565b634e487b7160e01b600052604160045260246000fd5b919082519283825260005b848110610345575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201610324565b6000546001600160a01b0316330361036e57565b63118cdaa760e01b6000523360045260246000fdfea26469706673582212207bc32ec723f6be34b228b59aef2ef61b4e6a8eb5bc67fcdd495248566e3b6e0c64736f6c634300081c0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103';
36
- }
37
- /**
38
- * ClientAgentVault Integration Tests
47
+ * Transfer ERC20 tokens from AA wallet to another address
48
+ * 从AA钱包转账ERC20代币到其他地址
39
49
  *
40
- * these tests show how to use the AA wallet to:
41
- * 1. deploy the ClientAgentVault proxy contract (via performCreate)
42
- * 2. configure spending rules (Spending Rules)
43
- * 3. view spending rules (read-only)
44
- * 4. withdraw funds (withdrawFunds)
45
- * 5. check token balance (read-only)
46
- *
47
- * how to use:
48
- * - modify the contract addresses and parameters as needed
50
+ * @param eoa - User's EOA address (from Privy)
51
+ * @param to - Recipient address
52
+ * @param amount - Amount to transfer
53
+ * @param tokenAddress - Token contract address
54
+ * @param tokenDecimals - Token decimals (usually 18)
55
+ * @param signFunction - Signing function from Privy
49
56
  */
50
- async function clientAgentVaultIntegrationTests() {
51
- console.log('\n=== ClientAgentVault Integration Tests ===');
52
- // Initialize SDK
53
- const sdk = new gokite_aa_sdk_1.GokiteAASDK('kite_testnet', 'https://rpc-testnet.gokite.ai', 'https://bundler-service.staging.gokite.ai/rpc/');
54
- // user's EOA address and AA wallet address
55
- const eoa = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
56
- const aa = sdk.getAccountAddress(eoa);
57
- console.log('AA Wallet Address:', aa);
58
- // Sign function, replace with particle or privy sdk
59
- const signFunction = async (userOpHash) => {
60
- const signer_pk = process.env.PRIVATE_KEY;
61
- const signer = new ethers_1.ethers.Wallet(signer_pk);
62
- return signer.signMessage(ethers_1.ethers.getBytes(userOpHash));
63
- };
64
- // 1. Deploy ClientAgentVault Proxy via performCreate
65
- console.log('\n--- Test 1: Deploy ClientAgentVault Proxy ---');
66
- const deployedProxyAddress = await DeployClientAgentVaultProxy(sdk, eoa, aa, signFunction);
67
- if (!deployedProxyAddress) {
68
- console.log('❌ Failed to deploy proxy, cannot continue with other tests');
69
- return;
57
+ async function transferERC20(eoa, to, amount, tokenAddress, tokenDecimals = 18, signFunction) {
58
+ const sdk = initializeSDK();
59
+ try {
60
+ const transferRequest = {
61
+ target: tokenAddress,
62
+ value: 0n,
63
+ callData: ethers_1.ethers.Interface.from([
64
+ 'function transfer(address to, uint256 amount)'
65
+ ]).encodeFunctionData('transfer', [
66
+ to,
67
+ ethers_1.ethers.parseUnits(amount, tokenDecimals)
68
+ ])
69
+ };
70
+ console.log(`Transferring ${amount} tokens to ${to}...`);
71
+ const result = await sdk.sendUserOperationAndWait(eoa, transferRequest, signFunction);
72
+ if (result.status.status === 'success') {
73
+ return {
74
+ success: true,
75
+ transactionHash: result.status.transactionHash,
76
+ message: 'Transfer successful'
77
+ };
78
+ }
79
+ else {
80
+ return {
81
+ success: false,
82
+ error: result.status.reason,
83
+ message: 'Transfer failed'
84
+ };
85
+ }
86
+ }
87
+ catch (error) {
88
+ const aaError = handleAAError(error);
89
+ return {
90
+ success: false,
91
+ error: aaError,
92
+ message: 'Transfer failed'
93
+ };
70
94
  }
71
- console.log(`✅ Using deployed proxy address: ${deployedProxyAddress}`);
72
- // 2. Configure Spending Rules
73
- console.log('\n--- Test 2: Configure Spending Rules ---');
74
- await ConfigureSpendingRules(sdk, eoa, deployedProxyAddress, signFunction);
75
- // 3. View Spending Rules
76
- console.log('\n--- Test 3: View Spending Rules ---');
77
- await ViewSpendingRules(sdk, deployedProxyAddress);
78
- // 4. Withdraw Funds
79
- console.log('\n--- Test 4: Withdraw Funds ---');
80
- await WithdrawFunds(sdk, eoa, deployedProxyAddress, signFunction);
81
- // 5. Check Token Balance
82
- console.log('\n--- Test 5: Check Token Balance ---');
83
- await CheckTokenBalance(sdk, deployedProxyAddress);
84
95
  }
85
- exports.clientAgentVaultIntegrationTests = clientAgentVaultIntegrationTests;
96
+ exports.transferERC20 = transferERC20;
97
+ // =============================================================================
98
+ // 2. KITEPASS RELATED - ClientAgentVault Operations
99
+ // KitePass相关 - 客户端代理金库操作
100
+ // =============================================================================
86
101
  /**
87
- * Test 1: Deploy ClientAgentVault Proxy via AA wallet's performCreate
102
+ * 部署KitePass合约
103
+ *
104
+ * @param eoa - User's EOA address
105
+ * @param signFunction - Signing function from Privy
106
+ * @returns Deployed KitePass address
88
107
  */
89
- async function DeployClientAgentVaultProxy(sdk, eoa, aa, signFunction) {
108
+ async function deployKitePass(eoa, signFunction) {
109
+ const sdk = initializeSDK();
110
+ const aa = sdk.getAccountAddress(eoa);
90
111
  try {
91
- // Prepare initialization data for ClientAgentVault
112
+ // Prepare initialization data
92
113
  const initializeCallData = ethers_1.ethers.Interface.from([
93
114
  'function initialize(address allowedToken, address owner)'
94
115
  ]).encodeFunctionData('initialize', [
95
116
  ADDRESSES.SETTLEMENT_TOKEN,
96
- aa // owner (AA wallet address)
97
- ]);
98
- // Create TransparentUpgradeableProxy deployment bytecode
99
- // constructor(address _logic, address admin_, bytes memory _data)
100
- const proxyConstructorData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['address', 'address', 'bytes'], [
101
- ADDRESSES.CLIENT_AGENT_VAULT_IMPL,
102
- aa,
103
- initializeCallData // initialization data
117
+ aa
104
118
  ]);
105
- // Full deployment bytecode = creation code + constructor params
119
+ // Create KitePass deployment bytecode
120
+ const proxyConstructorData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['address', 'address', 'bytes'], [ADDRESSES.CLIENT_AGENT_VAULT_IMPL, aa, initializeCallData]);
106
121
  const transparentProxyBytecode = getTransparentProxyBytecode();
107
122
  const fullInitCode = transparentProxyBytecode + proxyConstructorData.slice(2);
108
- // Create UserOperation to call performCreate
109
123
  const deployRequest = {
110
124
  target: aa,
111
125
  value: 0n,
112
126
  callData: ethers_1.ethers.Interface.from([
113
127
  'function performCreate(uint256 value, bytes calldata initCode) returns (address)'
114
- ]).encodeFunctionData('performCreate', [
115
- 0n,
116
- fullInitCode // proxy deployment bytecode + constructor params
117
- ])
128
+ ]).encodeFunctionData('performCreate', [0n, fullInitCode])
118
129
  };
119
- console.log('Deploying ClientAgentVault proxy...');
120
- console.log('- Implementation:', ADDRESSES.CLIENT_AGENT_VAULT_IMPL);
121
- console.log('- AllowedToken:', ADDRESSES.SETTLEMENT_TOKEN);
130
+ console.log('Deploying KitePass proxy...');
122
131
  const result = await sdk.sendUserOperationAndWait(eoa, deployRequest, signFunction);
123
132
  if (result.status.status === 'success') {
124
- console.log('✅ Proxy deployed successfully!');
125
- console.log('Transaction hash:', result.status.transactionHash);
126
- // Parse the deployed proxy address from transaction logs
127
133
  const proxyAddress = await parseContractCreatedEvent(result.status.transactionHash);
128
- if (proxyAddress) {
129
- console.log('🎯 Deployed proxy address:', proxyAddress);
130
- return proxyAddress; // Return the actual proxy address
131
- }
132
- else {
133
- console.log('⚠️ Could not parse proxy address from logs');
134
- }
134
+ return {
135
+ success: true,
136
+ proxyAddress: proxyAddress || undefined
137
+ };
135
138
  }
136
139
  else {
137
- console.log('❌ Deployment failed:', result.status.reason);
140
+ return {
141
+ success: false,
142
+ error: result.status.reason
143
+ };
138
144
  }
139
145
  }
140
146
  catch (error) {
141
- console.error('❌ Test 1 failed:', error);
147
+ return {
148
+ success: false,
149
+ error: handleAAError(error)
150
+ };
142
151
  }
143
- return null;
144
152
  }
145
- exports.DeployClientAgentVaultProxy = DeployClientAgentVaultProxy;
153
+ exports.deployKitePass = deployKitePass;
146
154
  /**
147
- * Test 2: Configure Spending Rules
155
+ * Configure spending rules for KitePass
156
+ * setSpendingRules方法会先清除现有的rules,然后设置新的rules
157
+ * 1. 新增/修改:需要先获取现有的rules,然后append新的rules,或者在现有rules的基础上修改
158
+ * 2. 删除:需要先获取现有的rules,然后删除对应的rules
159
+ *
160
+ * @param eoa - User's EOA address
161
+ * @param kitepassAddress - KitePass proxy address
162
+ * @param rules - Spending rules to configure
163
+ * @param signFunction - Signing function
148
164
  */
149
- async function ConfigureSpendingRules(sdk, owner, proxyAddress, signFunction) {
150
- // get today's 00:00:00 timestamp
151
- const today = new Date();
152
- const todayStart = new Date(today.getFullYear(), today.getMonth(), today.getDate());
153
- const todayStartTimestamp = Math.floor(todayStart.getTime() / 1000);
154
- // get current week's monday 00:00:00 timestamp
155
- const dayOfWeek = today.getDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday
156
- const daysFromMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Convert Sunday=0 to Sunday=6
157
- const currentWeekStartTimestamp = todayStartTimestamp - (daysFromMonday * 86400); // 86400 = seconds in a day
158
- // rules fields:
159
- // - TimeWindow: time window in seconds, 0 means per transaction, >0 means per time window
160
- // - Budget: budget in wei, 18 decimals, like 1e18 means 1 token
161
- // - InitialWindowStartTime: start time of the time window in unix timestamp
162
- // should be set to the start time of the day/week/month in local time (or utc) 00:00:00
163
- // - TargetProviders: target service providers array, empty array means applies to all providers
165
+ async function configureSpendingRules(eoa, kitepassAddress, signFunction) {
166
+ const sdk = initializeSDK();
164
167
  try {
165
- // Define spending rules
168
+ // Convert rules to contract format
169
+ const today = new Date();
170
+ const todayStart = new Date(today.getFullYear(), today.getMonth(), today.getDate());
171
+ const todayStartTimestamp = Math.floor(todayStart.getTime() / 1000);
172
+ // get current week's monday 00:00:00 timestamp
173
+ const dayOfWeek = today.getDay(); // 0=Sunday, 1=Monday, ..., 6=Saturday
174
+ const daysFromMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Convert Sunday=0 to Sunday=6
175
+ const currentWeekStartTimestamp = todayStartTimestamp - (daysFromMonday * 86400); // 86400 = seconds in a day
176
+ // rules fields:
177
+ // - TimeWindow: time window in seconds, 0 means per transaction, >0 means per time window
178
+ // - Budget: budget in wei, 18 decimals, like 1e18 means 1 token
179
+ // - InitialWindowStartTime: start time of the time window in unix timestamp
180
+ // should be set to the start time of the day/week/month in local time (or utc) 00:00:00
181
+ // - TargetProviders: target service providers array, empty array means applies to all providers
166
182
  const rulesToAdd = [
167
183
  {
168
184
  timeWindow: 86400n,
@@ -183,201 +199,218 @@ async function ConfigureSpendingRules(sdk, owner, proxyAddress, signFunction) {
183
199
  targetProviders: [ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes('provider1'))]
184
200
  }
185
201
  ];
202
+ // 获取现有的rules
203
+ const existingRules = await viewSpendingRules(kitepassAddress);
204
+ const existingRulesArray = existingRules.rules;
205
+ // append new rules
206
+ const newRules = [...existingRulesArray, ...rulesToAdd];
186
207
  const configureRequest = {
187
- target: proxyAddress,
208
+ target: kitepassAddress,
188
209
  value: 0n,
189
210
  callData: ethers_1.ethers.Interface.from([
190
- 'function configureSpendingRule(uint256[] calldata indicesToRemove, tuple(uint256 timeWindow, uint160 budget, uint96 initialWindowStartTime, bytes32[] targetProviders)[] calldata rulesToAdd)'
191
- ]).encodeFunctionData('configureSpendingRule', [
192
- [],
193
- rulesToAdd // rules to add
194
- ])
211
+ 'function setSpendingRules(tuple(uint256 timeWindow, uint160 budget, uint96 initialWindowStartTime, bytes32[] targetProviders)[] calldata rules)'
212
+ ]).encodeFunctionData('setSpendingRules', [newRules])
195
213
  };
196
214
  console.log('Configuring spending rules...');
197
- console.log('- Rule 1: 100 tokens per 24 hours (all providers)');
198
- console.log('- Rule 2: 10 tokens per hour (specific provider)');
199
- const result = await sdk.sendUserOperationAndWait(owner, configureRequest, signFunction);
215
+ const result = await sdk.sendUserOperationAndWait(eoa, configureRequest, signFunction);
200
216
  if (result.status.status === 'success') {
201
- console.log('✅ Spending rules configured successfully!');
202
- console.log('Transaction hash:', result.status.transactionHash);
217
+ return {
218
+ success: true,
219
+ transactionHash: result.status.transactionHash
220
+ };
203
221
  }
204
222
  else {
205
- console.log('❌ Configuration failed:', result.status.reason);
223
+ return {
224
+ success: false,
225
+ error: result.status.reason
226
+ };
206
227
  }
207
228
  }
208
229
  catch (error) {
209
- const aaError = handleAAError(error);
210
- console.error('❌ Test 2 failed:', {
211
- type: aaError.type,
212
- message: aaError.message
213
- });
214
- // Frontend can handle different error types
215
- switch (aaError.type) {
216
- case 'ESTIMATE_GAS_FAILED':
217
- console.log('Suggestion: Check if the contract call is valid');
218
- break;
219
- case 'SEND_USEROP_FAILED':
220
- console.log('Suggestion: Try again or check bundler status');
221
- break;
222
- case 'NETWORK_ERROR':
223
- console.log('Suggestion: Check your internet connection');
224
- break;
225
- default:
226
- console.log('Suggestion: Check console for more details');
227
- }
230
+ return {
231
+ success: false,
232
+ error: handleAAError(error)
233
+ };
228
234
  }
229
235
  }
230
- exports.ConfigureSpendingRules = ConfigureSpendingRules;
236
+ exports.configureSpendingRules = configureSpendingRules;
231
237
  /**
232
- * Test 3: View Spending Rules (Read-only, no transaction sent)
238
+ * View current spending rules (read-only)
239
+ * 查看当前消费规则(只读)
233
240
  */
234
- async function ViewSpendingRules(sdk, proxyAddress) {
241
+ async function viewSpendingRules(kitepassAddress) {
235
242
  try {
236
243
  const provider = new ethers_1.ethers.JsonRpcProvider('https://rpc-testnet.gokite.ai');
237
- const contract = new ethers_1.ethers.Contract(proxyAddress, [
244
+ const contract = new ethers_1.ethers.Contract(kitepassAddress, [
238
245
  'function getSpendingRules() view returns (tuple(tuple(uint256 timeWindow, uint160 budget, uint96 initialWindowStartTime, bytes32[] targetProviders) rule, tuple(uint128 amountUsed, uint128 currentTimeWindowStartTime) usage)[])'
239
246
  ], provider);
240
- console.log('Fetching spending rules...');
241
247
  const spendingRules = await contract.getSpendingRules();
242
- console.log('✅ Spending Rules:');
243
- spendingRules.forEach((rule, index) => {
244
- console.log(` Rule ${index + 1}:`);
245
- console.log(` - Time Window: ${rule.rule.timeWindow} seconds`);
246
- console.log(` - Budget: ${ethers_1.ethers.formatUnits(rule.rule.budget, 18)} tokens`);
247
- console.log(` - Used: ${ethers_1.ethers.formatUnits(rule.usage.amountUsed, 18)} tokens`);
248
- console.log(` - Providers: ${rule.rule.targetProviders.length === 0 ? 'All' : rule.rule.targetProviders.length}`);
249
- });
248
+ return {
249
+ success: true,
250
+ rules: spendingRules.map((rule, index) => ({
251
+ index,
252
+ timeWindow: Number(rule.rule.timeWindow),
253
+ budget: ethers_1.ethers.formatUnits(rule.rule.budget, 18),
254
+ used: ethers_1.ethers.formatUnits(rule.usage.amountUsed, 18),
255
+ providersCount: rule.rule.targetProviders.length
256
+ }))
257
+ };
250
258
  }
251
259
  catch (error) {
252
- console.error('❌ Test 3 failed:', error);
260
+ return {
261
+ success: false,
262
+ error: error.message
263
+ };
253
264
  }
254
265
  }
255
- exports.ViewSpendingRules = ViewSpendingRules;
266
+ exports.viewSpendingRules = viewSpendingRules;
256
267
  /**
257
- * Test 4: Withdraw Funds
268
+ * Withdraw funds from KitePass
269
+ * 从KitePass提取资金
258
270
  */
259
- async function WithdrawFunds(sdk, owner, proxyAddress, signFunction) {
271
+ async function withdrawFunds(eoa, kitepassAddress, amount, tokenAddress = ADDRESSES.SETTLEMENT_TOKEN, signFunction) {
272
+ const sdk = initializeSDK();
260
273
  try {
261
- const withdrawAmount = ethers_1.ethers.parseUnits('50', 18); // Withdraw 50 tokens
262
274
  const withdrawRequest = {
263
- target: proxyAddress,
275
+ target: kitepassAddress,
264
276
  value: 0n,
265
277
  callData: ethers_1.ethers.Interface.from([
266
278
  'function withdrawFunds(address token, uint256 amount)'
267
279
  ]).encodeFunctionData('withdrawFunds', [
268
- ADDRESSES.SETTLEMENT_TOKEN,
269
- withdrawAmount // amount to withdraw
280
+ tokenAddress,
281
+ ethers_1.ethers.parseUnits(amount, 18)
270
282
  ])
271
283
  };
272
- console.log('Withdrawing funds...');
273
- console.log(`- Token: ${ADDRESSES.SETTLEMENT_TOKEN}`);
274
- console.log(`- Amount: ${ethers_1.ethers.formatUnits(withdrawAmount, 18)} tokens`);
275
- const result = await sdk.sendUserOperationAndWait(owner, withdrawRequest, signFunction);
284
+ console.log(`Withdrawing ${amount} tokens...`);
285
+ const result = await sdk.sendUserOperationAndWait(eoa, withdrawRequest, signFunction);
276
286
  if (result.status.status === 'success') {
277
- console.log('✅ Funds withdrawn successfully!');
278
- console.log('Transaction hash:', result.status.transactionHash);
287
+ return {
288
+ success: true,
289
+ transactionHash: result.status.transactionHash
290
+ };
279
291
  }
280
292
  else {
281
- console.log('❌ Withdrawal failed:', result.status.reason);
293
+ return {
294
+ success: false,
295
+ error: result.status.reason
296
+ };
282
297
  }
283
298
  }
284
299
  catch (error) {
285
- console.error('❌ Test 4 failed:', error);
300
+ return {
301
+ success: false,
302
+ error: handleAAError(error)
303
+ };
286
304
  }
287
305
  }
288
- exports.WithdrawFunds = WithdrawFunds;
306
+ exports.withdrawFunds = withdrawFunds;
289
307
  /**
290
- * Test 5: Check Token Balance (Read-only)
308
+ * Check token balance (read-only)
309
+ * 查看代币余额(只读)
291
310
  */
292
- async function CheckTokenBalance(sdk, proxyAddress) {
311
+ async function checkTokenBalance(address, tokenAddress = ADDRESSES.SETTLEMENT_TOKEN) {
293
312
  try {
294
313
  const provider = new ethers_1.ethers.JsonRpcProvider('https://rpc-testnet.gokite.ai');
295
- const tokenContract = new ethers_1.ethers.Contract(ADDRESSES.SETTLEMENT_TOKEN, [
314
+ const tokenContract = new ethers_1.ethers.Contract(tokenAddress, [
296
315
  'function balanceOf(address account) view returns (uint256)',
297
316
  'function symbol() view returns (string)',
298
317
  'function decimals() view returns (uint8)'
299
318
  ], provider);
300
- console.log('Checking token balance...');
301
319
  const [balance, symbol, decimals] = await Promise.all([
302
- tokenContract.balanceOf(proxyAddress),
320
+ tokenContract.balanceOf(address),
303
321
  tokenContract.symbol(),
304
322
  tokenContract.decimals()
305
323
  ]);
306
- console.log('✅ Token Balance:');
307
- console.log(` - Address: ${proxyAddress}`);
308
- console.log(` - Token: ${symbol} (${ADDRESSES.SETTLEMENT_TOKEN})`);
309
- console.log(` - Balance: ${ethers_1.ethers.formatUnits(balance, decimals)} ${symbol}`);
324
+ return {
325
+ success: true,
326
+ balance: ethers_1.ethers.formatUnits(balance, decimals),
327
+ symbol,
328
+ decimals,
329
+ address
330
+ };
310
331
  }
311
332
  catch (error) {
312
- console.error('❌ Test 5 failed:', error);
333
+ return {
334
+ success: false,
335
+ error: error.message
336
+ };
313
337
  }
314
338
  }
315
- exports.CheckTokenBalance = CheckTokenBalance;
339
+ exports.checkTokenBalance = checkTokenBalance;
316
340
  /**
317
- * Legacy example for basic AA operations
341
+ * Register a service in the service registry
342
+ * 在服务注册表中注册服务
343
+ *
344
+ * @param eoa - Service owner's EOA address
345
+ * @param serviceId - Service ID (bytes32)
346
+ * @param serviceInfo - Service information
347
+ * @param signFunction - Signing function
318
348
  */
319
- async function basicExample() {
320
- console.log('\n=== Basic AA SDK Example ===');
321
- // Initialize SDK
322
- const sdk = new gokite_aa_sdk_1.GokiteAASDK('kite_testnet', 'https://rpc-testnet.gokite.ai', 'http://localhost:14337/rpc/');
323
- const owner = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
324
- const accountAddress = sdk.getAccountAddress(owner);
325
- console.log('Account address:', accountAddress);
326
- // Simple ETH transfer example
327
- const sendEthRequest = {
328
- target: '0x4A50DCA63d541372ad36E5A36F1D542d51164F19',
329
- value: ethers_1.ethers.parseEther('0.001'),
330
- callData: '0x'
331
- };
332
- const signFunction = async (userOpHash) => {
333
- const signer_pk = process.env.PRIVATE_KEY;
334
- const signer = new ethers_1.ethers.Wallet(signer_pk);
335
- return signer.signMessage(ethers_1.ethers.getBytes(userOpHash));
336
- };
349
+ async function registerService(eoa, serviceId, serviceInfo, signFunction) {
350
+ const sdk = initializeSDK();
337
351
  try {
338
- const result = await sdk.sendUserOperationAndWait(owner, sendEthRequest, signFunction);
352
+ const registerRequest = {
353
+ target: ADDRESSES.SERVICE_REGISTRY,
354
+ value: 0n,
355
+ callData: ethers_1.ethers.Interface.from([
356
+ 'function registerService(bytes32 serviceId, tuple(address serviceOwner, uint8 priceModel, uint256 unitPrice, bytes32 provider, bytes metadata, string name, bool isPublic) service)'
357
+ ]).encodeFunctionData('registerService', [
358
+ serviceId,
359
+ serviceInfo
360
+ ])
361
+ };
362
+ console.log(`Registering service: ${serviceInfo.name}...`);
363
+ const result = await sdk.sendUserOperationAndWait(eoa, registerRequest, signFunction);
339
364
  if (result.status.status === 'success') {
340
- console.log('✅ ETH transfer successful!');
341
- console.log('Transaction hash:', result.status.transactionHash);
365
+ return {
366
+ success: true,
367
+ transactionHash: result.status.transactionHash,
368
+ serviceId
369
+ };
342
370
  }
343
371
  else {
344
- console.log('❌ ETH transfer failed:', result.status.reason);
372
+ return {
373
+ success: false,
374
+ error: result.status.reason
375
+ };
345
376
  }
346
377
  }
347
378
  catch (error) {
348
- console.error('❌ Basic example failed:', error);
379
+ return {
380
+ success: false,
381
+ error: handleAAError(error)
382
+ };
349
383
  }
350
384
  }
351
- exports.basicExample = basicExample;
385
+ exports.registerService = registerService;
386
+ // =============================================================================
387
+ // UTILITY FUNCTIONS - 工具函数
388
+ // =============================================================================
389
+ /**
390
+ * Get TransparentUpgradeableProxy bytecode
391
+ * 获取透明可升级代理字节码
392
+ */
393
+ function getTransparentProxyBytecode() {
394
+ return '0x60a0604052610b278038038061001481610293565b928339810160608282031261028e5761002c826102b8565b610038602084016102b8565b604084015190936001600160401b03821161028e570182601f8201121561028e5780519061006d610068836102cc565b610293565b938285526020838301011161028e5760005b828110610279575050602060009184010152803b15610258577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0383169081179091557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a281511561023f5760008083602061013595519101845af43d15610237573d91610125610068846102cc565b9283523d6000602085013e6102e7565b505b604051906104918083016001600160401b0381118482101761022157602092849261067684396001600160a01b031681520301906000f080156102155760018060a01b031680608052600080516020610b07833981519152547f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6040805160018060a01b0384168152846020820152a181156101ff576001600160a01b03191617600080516020610b078339815191525560405161032d908161034982396080518160070152f35b633173bdd160e11b600052600060045260246000fd5b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b6060916102e7565b505034156101375763b398979f60e01b60005260046000fd5b634c9c8ce360e01b60009081526001600160a01b0391909116600452602490fd5b8060208092840101518282880101520161007f565b600080fd5b6040519190601f01601f191682016001600160401b0381118382101761022157604052565b51906001600160a01b038216820361028e57565b6001600160401b03811161022157601f01601f191660200190565b9061030d57508051156102fc57805190602001fd5b630a12f52160e11b60005260046000fd5b8151158061033f575b61031e575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561031656fe6080604052337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603610069576000356001600160e01b03191663278f794360e11b1461005f576334ad5dbb60e21b60005260046000fd5b610067610113565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460009081906001600160a01b0316368280378136915af43d6000803e156100b1573d6000f35b3d6000fd5b634e487b7160e01b600052604160045260246000fd5b6040519190601f01601f1916820167ffffffffffffffff8111838210176100f257604052565b6100b6565b67ffffffffffffffff81116100f257601f01601f191660200190565b3660041161019d57604036600319011261019d576004356001600160a01b0381169081900361019d576024359067ffffffffffffffff821161019d573660238301121561019d5781600401359061017161016c836100f7565b6100cc565b91808352366024828601011161019d57602081600092602461019b970183870137840101526101a2565b565b600080fd5b90813b15610239577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0384169081179091557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a280511561021f5761021c9161025b565b50565b50503461022857565b63b398979f60e01b60005260046000fd5b50634c9c8ce360e01b60009081526001600160a01b0391909116600452602490fd5b60008061028f93602081519101845af43d15610292573d9161027f61016c846100f7565b9283523d6000602085013e610296565b90565b6060915b906102bc57508051156102ab57805190602001fd5b630a12f52160e11b60005260046000fd5b815115806102ee575b6102cd575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b156102c556fea2646970667358221220597147005a6fe654561cbab25a93153cc233180473a65a90bd427f0c1f41018764736f6c634300081c003360803460bc57601f61049138819003918201601f19168301916001600160401b0383118484101760c15780849260209460405283398101031260bc57516001600160a01b0381169081900360bc57801560a657600080546001600160a01b031981168317825560405192916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36103b990816100d88239f35b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604052600436101561001257600080fd5b6000803560e01c8063715018a6146102875780638da5cb5b146102605780639623609d1461012f578063ad3cb1cc146100e25763f2fde38b1461005457600080fd5b346100df5760203660031901126100df576004356001600160a01b038116908190036100dd5761008261035a565b80156100c95781546001600160a01b03198116821783556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b631e4fbdf760e01b82526004829052602482fd5b505b80fd5b50346100df57806003193601126100df575061012b6040516101056040826102e1565b60058152640352e302e360dc1b6020820152604051918291602083526020830190610319565b0390f35b5060603660031901126100df576004356001600160a01b038116908190036100dd576024356001600160a01b038116908190036102405760443567ffffffffffffffff811161025c573660238201121561025c57806004013567ffffffffffffffff8111610248576040518593929091906101b4601f8301601f1916602001846102e1565b81835236602483830101116102445781859260246020930183860137830101526101dc61035a565b833b156102405761021293839260405180968194829363278f794360e11b84526004840152604060248401526044830190610319565b039134905af18015610233576102255780f35b61022e916102e1565b388180f35b50604051903d90823e3d90fd5b8280fd5b8480fd5b634e487b7160e01b85526041600452602485fd5b8380fd5b50346100df57806003193601126100df57546040516001600160a01b039091168152602090f35b50346100df57806003193601126100df576102a061035a565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b90601f8019910116810190811067ffffffffffffffff82111761030357604052565b634e487b7160e01b600052604160045260246000fd5b919082519283825260005b848110610345575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201610324565b6000546001600160a01b0316330361036e57565b63118cdaa760e01b6000523360045260246000fdfea26469706673582212207bc32ec723f6be34b228b59aef2ef61b4e6a8eb5bc67fcdd495248566e3b6e0c64736f6c634300081c0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103';
395
+ }
396
+ exports.getTransparentProxyBytecode = getTransparentProxyBytecode;
352
397
  /**
353
- * Parse ContractCreated event from transaction logs to get deployed proxy address
354
- * Event: ContractCreated(address indexed contractAddress)
398
+ * Parse ContractCreated event from transaction logs
399
+ * 从交易日志中解析合约创建事件
355
400
  */
356
401
  async function parseContractCreatedEvent(transactionHash) {
357
402
  try {
358
403
  const provider = new ethers_1.ethers.JsonRpcProvider('https://rpc-testnet.gokite.ai');
359
404
  const receipt = await provider.getTransactionReceipt(transactionHash);
360
- if (!receipt) {
361
- console.error('Transaction receipt not found');
405
+ if (!receipt)
362
406
  return null;
363
- }
364
- // ContractCreated event signature: ContractCreated(address indexed contractAddress)
365
407
  const contractCreatedEventSignature = ethers_1.ethers.id('ContractCreated(address)');
366
- console.log('Parsing transaction logs...');
367
- console.log(`Total logs: ${receipt.logs.length}`);
368
408
  for (const log of receipt.logs) {
369
- // Check if this log matches the ContractCreated event
370
409
  if (log.topics[0] === contractCreatedEventSignature) {
371
- // The first topic is the event signature
372
- // The second topic is the indexed contractAddress
373
410
  const contractAddress = ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(['address'], log.topics[1])[0];
374
- console.log('Found ContractCreated event:');
375
- console.log('- Contract Address:', contractAddress);
376
- console.log('- From Address:', log.address);
377
411
  return contractAddress;
378
412
  }
379
413
  }
380
- console.log('No ContractCreated event found in transaction logs');
381
414
  return null;
382
415
  }
383
416
  catch (error) {
@@ -385,13 +418,79 @@ async function parseContractCreatedEvent(transactionHash) {
385
418
  return null;
386
419
  }
387
420
  }
388
- async function main() {
389
- // Run ClientAgentVault integration tests
390
- await clientAgentVaultIntegrationTests();
391
- // // Run basic AA example
392
- // await basicExample();
393
- console.log('\n✅ All examples completed!');
421
+ exports.parseContractCreatedEvent = parseContractCreatedEvent;
422
+ // =============================================================================
423
+ // EXAMPLE USAGE - 使用示例
424
+ // =============================================================================
425
+ /**
426
+ * Example usage for frontend integration
427
+ * 前端集成使用示例
428
+ */
429
+ async function exampleUsage() {
430
+ // Replace with actual signing function from Privy/Particle
431
+ // 替换为实际的Privy/Particle签名函数
432
+ const signFunction = async (userOpHash) => {
433
+ const signer_pk = process.env.PRIVATE_KEY;
434
+ const signer = new ethers_1.ethers.Wallet(signer_pk);
435
+ return signer.signMessage(ethers_1.ethers.getBytes(userOpHash));
436
+ };
437
+ const userEoa = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
438
+ // actual token recipient address
439
+ const toAddress = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
440
+ // // 1. Transfer ERC20 tokens
441
+ // console.log('\n=== 1. ERC20 Transfer ===');
442
+ // const transferResult = await transferERC20(
443
+ // userEoa,
444
+ // toAddress,
445
+ // '10',
446
+ // ADDRESSES.SETTLEMENT_TOKEN,
447
+ // 18,
448
+ // signFunction
449
+ // );
450
+ // console.log('Transfer result:', transferResult);
451
+ // 2. Deploy KitePass
452
+ console.log('\n=== 2. Deploy KitePass ===');
453
+ const deployResult = await deployKitePass(userEoa, signFunction);
454
+ console.log('Deploy result:', deployResult);
455
+ // if (deployResult.success && deployResult.proxyAddress) {
456
+ // // 3. Configure spending rules
457
+ // console.log('\n=== 3. Configure Spending Rules ===');
458
+ // const configResult = await configureSpendingRules(
459
+ // userEoa,
460
+ // deployResult.proxyAddress,
461
+ // signFunction
462
+ // );
463
+ // console.log('Config result:', configResult);
464
+ // // 4. View spending rules
465
+ // console.log('\n=== 4. View Spending Rules ===');
466
+ // const rulesResult = await viewSpendingRules(deployResult.proxyAddress);
467
+ // console.log('Rules result:', rulesResult);
468
+ // }
469
+ // // 5. Register service
470
+ // console.log('\n=== 5. Register Service ===');
471
+ // // serviceId, get from backend
472
+ // const serviceId = ethers.hexlify(randomBytes(32));
473
+ // const sdk = initializeSDK();
474
+ // const serviceOwner = sdk.getAccountAddress(userEoa);
475
+ // const serviceResult = await registerService(
476
+ // userEoa,
477
+ // serviceId,
478
+ // {
479
+ // serviceOwner: serviceOwner,
480
+ // priceModel: 0,
481
+ // unitPrice: 100,
482
+ // // provider Id, bytes32
483
+ // provider: ethers.hexlify(randomBytes(32)),
484
+ // // service metadata, currently not used
485
+ // metadata: '0x',
486
+ // name: 'Test Service',
487
+ // isPublic: true
488
+ // },
489
+ // signFunction
490
+ // );
491
+ // console.log('Service result:', serviceResult);
492
+ }
493
+ // Run example if executed directly
494
+ if (require.main === module) {
495
+ exampleUsage().catch(console.error);
394
496
  }
395
- // Legacy export for backwards compatibility
396
- exports.example = basicExample;
397
- main().catch(console.error);
@@ -1,4 +1,4 @@
1
- import { UserOperation, UserOperationRequest, BatchUserOperationRequest, UserOperationGasEstimate, UserOperationStatus, SignFunction, PollingOptions } from './types';
1
+ import { UserOperation, UserOperationRequest, BatchUserOperationRequest, UserOperationGasEstimate, UserOperationStatus, SignFunction, PollingOptions, UserOperationEstimate } from './types';
2
2
  /**
3
3
  * Main Gokite AA SDK class
4
4
  */
@@ -38,7 +38,7 @@ export declare class GokiteAASDK {
38
38
  /**
39
39
  * Create user operation
40
40
  */
41
- createUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest, salt?: bigint, paymasterAddress?: string): Promise<Partial<UserOperation>>;
41
+ createUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest, salt?: bigint, paymasterAddress?: string, tokenAddress?: string): Promise<Partial<UserOperation>>;
42
42
  /**
43
43
  * Estimate gas for user operation
44
44
  */
@@ -46,7 +46,7 @@ export declare class GokiteAASDK {
46
46
  /**
47
47
  * Sign and send user operation
48
48
  */
49
- sendUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest, signFn: SignFunction, salt?: bigint, paymasterAddress?: string): Promise<string>;
49
+ sendUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest, signFn: SignFunction, salt?: bigint, paymasterAddress?: string, tokenAddress?: string): Promise<string>;
50
50
  /**
51
51
  * Send user operation directly to EntryPoint contract (bypassing bundler)
52
52
  * Note: This requires a signer to pay for gas. For now, we'll try with the read-only provider.
@@ -60,9 +60,30 @@ export declare class GokiteAASDK {
60
60
  * Enhanced polling for user operation status with detailed result parsing
61
61
  */
62
62
  pollUserOperationStatus(userOpHash: string, options?: PollingOptions): Promise<UserOperationStatus>;
63
+ /**
64
+ * Estimate user operation costs and get paymaster information
65
+ */
66
+ estimateUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest): Promise<UserOperationEstimate>;
67
+ /**
68
+ * Get paymaster information including sponsorship status and supported tokens
69
+ */
70
+ private getPaymasterInfo;
63
71
  /**
64
72
  * Send user operation and wait for completion with detailed status
65
73
  */
74
+ /**
75
+ * Send user operation with specified payment token and wait for completion
76
+ */
77
+ sendUserOperationWithPayment(owner: string, request: UserOperationRequest | BatchUserOperationRequest, baseUserOp: Partial<UserOperation>, // base userOp from estimate
78
+ tokenAddress: string, // token address for payment
79
+ signFn: SignFunction, salt?: bigint, pollingOptions?: PollingOptions): Promise<{
80
+ userOpHash: string;
81
+ status: UserOperationStatus;
82
+ }>;
83
+ /**
84
+ * Add ERC20 approve operations to the request (approve 0 first, then max)
85
+ */
86
+ private addApproveOperation;
66
87
  sendUserOperationAndWait(owner: string, request: UserOperationRequest | BatchUserOperationRequest, signFn: SignFunction, salt?: bigint, paymasterAddress?: string, pollingOptions?: PollingOptions): Promise<{
67
88
  userOpHash: string;
68
89
  status: UserOperationStatus;
@@ -254,7 +254,7 @@ class GokiteAASDK {
254
254
  /**
255
255
  * Create user operation
256
256
  */
257
- async createUserOperation(owner, request, salt, paymasterAddress) {
257
+ async createUserOperation(owner, request, salt, paymasterAddress, tokenAddress) {
258
258
  const actualSalt = salt || (0, utils_1.generateSalt)();
259
259
  const accountAddress = this.getAccountAddress(owner, actualSalt);
260
260
  const isDeployed = await this.isAccountDeloyed(accountAddress);
@@ -274,9 +274,13 @@ class GokiteAASDK {
274
274
  paymasterAddress = this.config.paymaster;
275
275
  }
276
276
  // Pack paymaster data (paymasterAddress, paymasterVerificationGasLimit, postOpGasLimit, paymasterData)
277
- const paymasterAndData = paymasterAddress
278
- ? (0, utils_1.packPaymasterAndData)(paymasterAddress, BigInt(100000), BigInt(100000), '0x')
279
- : '0x';
277
+ let paymasterAndData = '0x';
278
+ if (paymasterAddress) {
279
+ // For token payments, append token address to paymaster data
280
+ tokenAddress = tokenAddress || this.config.supportedTokens[1].address;
281
+ const paymasterData = ethers_1.ethers.solidityPacked(['address'], [tokenAddress]);
282
+ paymasterAndData = (0, utils_1.packPaymasterAndData)(paymasterAddress, BigInt(500000), BigInt(500000), paymasterData);
283
+ }
280
284
  return {
281
285
  sender: accountAddress,
282
286
  nonce: await this.getAccountNonce(accountAddress),
@@ -300,13 +304,14 @@ class GokiteAASDK {
300
304
  /**
301
305
  * Sign and send user operation
302
306
  */
303
- async sendUserOperation(owner, request, signFn, salt, paymasterAddress) {
307
+ async sendUserOperation(owner, request, signFn, salt, paymasterAddress, tokenAddress) {
304
308
  // Create user operation
305
- const userOp = await this.createUserOperation(owner, request, salt, paymasterAddress);
309
+ const userOp = await this.createUserOperation(owner, request, salt, paymasterAddress, tokenAddress);
306
310
  // Add dummy signature for gas estimation
307
311
  const userOpWithDummy = (0, utils_1.createUserOpForEstimation)(userOp);
308
312
  // Estimate gas using bundler
309
313
  const gasEstimate = await this.provider.estimateUserOperationGas(userOpWithDummy, this.config.entryPoint);
314
+ gasEstimate.callGasLimit = gasEstimate.callGasLimit + 5000000n;
310
315
  console.log('gasEstimate:', gasEstimate);
311
316
  // Update gas fields in packed format (verificationGasLimit first, callGasLimit second)
312
317
  userOp.accountGasLimits = (0, utils_1.packAccountGasLimits)(gasEstimate.verificationGasLimit, gasEstimate.callGasLimit);
@@ -409,9 +414,150 @@ class GokiteAASDK {
409
414
  }
410
415
  throw new Error(`UserOp polling timeout: ${userOpHash} (attempt ${retryCount})`);
411
416
  }
417
+ /**
418
+ * Estimate user operation costs and get paymaster information
419
+ */
420
+ async estimateUserOperation(owner, request) {
421
+ console.log('Estimating UserOp costs...');
422
+ const paymasterAddress = this.config.paymaster;
423
+ try {
424
+ // Always estimate with paymaster for higher gas limits
425
+ const userOp = await this.createUserOperation(owner, request, undefined, paymasterAddress);
426
+ console.log('[estimateUserOperation]userOp:', userOp);
427
+ const gasEstimate = await this.estimateGas(userOp);
428
+ gasEstimate.callGasLimit = gasEstimate.callGasLimit + 5000000n;
429
+ gasEstimate.verificationGasLimit = gasEstimate.verificationGasLimit + 1000000n;
430
+ gasEstimate.preVerificationGas = gasEstimate.preVerificationGas + 1000000n;
431
+ gasEstimate.maxFeePerGas = BigInt(10000000);
432
+ // Calculate total cost in KITE
433
+ const totalGas = gasEstimate.callGasLimit + gasEstimate.verificationGasLimit + gasEstimate.preVerificationGas;
434
+ const totalCostWei = totalGas * gasEstimate.maxFeePerGas;
435
+ const totalCostKITE = totalCostWei.toString();
436
+ const totalCostKITEFormatted = ethers_1.ethers.formatEther(totalCostWei);
437
+ // Get paymaster info
438
+ const { sponsorshipAvailable, remainingSponsorships, supportedTokens } = await this.getPaymasterInfo(paymasterAddress, userOp.sender, totalCostWei);
439
+ return {
440
+ totalCostKITE,
441
+ totalCostKITEFormatted,
442
+ gasEstimate,
443
+ sponsorshipAvailable,
444
+ remainingSponsorships,
445
+ supportedTokens,
446
+ paymasterAddress,
447
+ userOp
448
+ };
449
+ }
450
+ catch (error) {
451
+ throw new types_1.AASDKError(classifyError(error, 'estimate user operation'));
452
+ }
453
+ }
454
+ /**
455
+ * Get paymaster information including sponsorship status and supported tokens
456
+ */
457
+ async getPaymasterInfo(paymasterAddress, userAddress, estimatedCost) {
458
+ const paymasterABI = [
459
+ 'function maxSponsoredTransactions() view returns (uint256)',
460
+ 'function userSponsorship(address user) view returns (uint256)',
461
+ 'function supportedTokens(address token) view returns (uint256)',
462
+ 'function maxCostPerSponsoredTransaction() view returns (uint256)'
463
+ ];
464
+ const paymaster = new ethers_1.ethers.Contract(paymasterAddress, paymasterABI, this.ethersProvider);
465
+ // Get sponsorship info
466
+ const [maxSponsorships, userSponsorships, maxCostPerSponsorship] = await Promise.all([
467
+ paymaster.maxSponsoredTransactions(),
468
+ paymaster.userSponsorship(userAddress),
469
+ paymaster.maxCostPerSponsoredTransaction()
470
+ ]);
471
+ const remainingSponsorships = Math.max(0, Number(maxSponsorships) - Number(userSponsorships));
472
+ const sponsorshipAvailable = remainingSponsorships > 0 && estimatedCost <= maxCostPerSponsorship;
473
+ // Check supported tokens from config
474
+ const supportedTokens = [];
475
+ for (const token of this.config.supportedTokens) {
476
+ try {
477
+ const exchangeRate = await paymaster.supportedTokens(token.address);
478
+ if (exchangeRate > 0) {
479
+ const tokenCost = (estimatedCost * BigInt(1e18)) / exchangeRate;
480
+ const formattedCost = `${ethers_1.ethers.formatUnits(tokenCost, token.decimals)} ${token.symbol}`;
481
+ supportedTokens.push({
482
+ tokenAddress: token.address,
483
+ tokenSymbol: token.symbol,
484
+ tokenDecimals: token.decimals,
485
+ estimatedCost: tokenCost.toString(),
486
+ formattedCost
487
+ });
488
+ }
489
+ }
490
+ catch (error) {
491
+ console.warn(`Failed to check token ${token.symbol}:`, error);
492
+ }
493
+ }
494
+ return {
495
+ sponsorshipAvailable,
496
+ remainingSponsorships,
497
+ supportedTokens
498
+ };
499
+ }
412
500
  /**
413
501
  * Send user operation and wait for completion with detailed status
414
502
  */
503
+ /**
504
+ * Send user operation with specified payment token and wait for completion
505
+ */
506
+ async sendUserOperationWithPayment(owner, request, baseUserOp, // base userOp from estimate
507
+ tokenAddress, // token address for payment
508
+ signFn, salt, pollingOptions) {
509
+ console.log('Sending UserOp with token:', tokenAddress);
510
+ let finalRequest = request;
511
+ let finalUserOp = { ...baseUserOp };
512
+ // If using ERC20 token (not 0x0), add approve operations
513
+ if (tokenAddress !== '0x0000000000000000000000000000000000000000') {
514
+ // Add approve operations to the request
515
+ finalRequest = await this.addApproveOperation(owner, request, tokenAddress, this.config.paymaster);
516
+ // Rebuild userOp with approve operations
517
+ finalUserOp = await this.createUserOperation(owner, finalRequest, salt, this.config.paymaster, tokenAddress);
518
+ // Copy gas estimates from base userOp
519
+ finalUserOp.accountGasLimits = baseUserOp.accountGasLimits;
520
+ finalUserOp.preVerificationGas = baseUserOp.preVerificationGas;
521
+ finalUserOp.gasFees = baseUserOp.gasFees;
522
+ }
523
+ // Get user operation hash
524
+ const userOpHash = await this.getUserOpHash(finalUserOp);
525
+ // Sign user operation
526
+ const signature = await signFn(userOpHash);
527
+ finalUserOp.signature = signature;
528
+ // Send to bundler
529
+ const sentUserOpHash = await this.provider.sendUserOperation(finalUserOp, this.config.entryPoint);
530
+ console.log(`UserOp sent: ${sentUserOpHash}`);
531
+ // Poll for status
532
+ const status = await this.pollUserOperationStatus(sentUserOpHash, pollingOptions);
533
+ return {
534
+ userOpHash: sentUserOpHash,
535
+ status
536
+ };
537
+ }
538
+ /**
539
+ * Add ERC20 approve operations to the request (approve 0 first, then max)
540
+ */
541
+ async addApproveOperation(owner, request, tokenAddress, paymasterAddress) {
542
+ // Create approve call data - first approve 0, then approve max
543
+ const approve0CallData = (0, utils_1.encodeFunctionCall)(['function approve(address,uint256) returns (bool)'], 'approve', [paymasterAddress, '0']);
544
+ const approveMaxCallData = (0, utils_1.encodeFunctionCall)(['function approve(address,uint256) returns (bool)'], 'approve', [paymasterAddress, ethers_1.ethers.MaxUint256.toString()]);
545
+ // Convert single request to batch if needed
546
+ if ('target' in request) {
547
+ return {
548
+ targets: [tokenAddress, tokenAddress, request.target],
549
+ values: [BigInt(0), BigInt(0), request.value || BigInt(0)],
550
+ callDatas: [approve0CallData, approveMaxCallData, request.callData]
551
+ };
552
+ }
553
+ else {
554
+ return {
555
+ targets: [tokenAddress, tokenAddress, ...request.targets],
556
+ values: [BigInt(0), BigInt(0), ...(request.values || [])],
557
+ callDatas: [approve0CallData, approveMaxCallData, ...request.callDatas]
558
+ };
559
+ }
560
+ }
415
561
  async sendUserOperationAndWait(owner, request, signFn, salt, paymasterAddress, pollingOptions) {
416
562
  console.log('Sending UserOp and waiting for completion...');
417
563
  // Step 1: Send user operation
package/dist/types.d.ts CHANGED
@@ -41,6 +41,23 @@ export interface PollingOptions {
41
41
  timeout?: number;
42
42
  maxRetries?: number;
43
43
  }
44
+ export interface PaymasterTokenCost {
45
+ tokenAddress: string;
46
+ tokenSymbol?: string;
47
+ tokenDecimals?: number;
48
+ estimatedCost: string;
49
+ formattedCost: string;
50
+ }
51
+ export interface UserOperationEstimate {
52
+ totalCostKITE: string;
53
+ totalCostKITEFormatted: string;
54
+ gasEstimate: UserOperationGasEstimate;
55
+ sponsorshipAvailable: boolean;
56
+ remainingSponsorships: number;
57
+ supportedTokens: PaymasterTokenCost[];
58
+ paymasterAddress?: string;
59
+ userOp: Partial<UserOperation>;
60
+ }
44
61
  export interface AAError {
45
62
  type: 'ESTIMATE_GAS_FAILED' | 'SEND_USEROP_FAILED' | 'INSUFFICIENT_FUNDS' | 'INVALID_SIGNATURE' | 'BUNDLER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
46
63
  message: string;
package/dist/utils.js CHANGED
@@ -130,7 +130,7 @@ function serializeUserOperation(userOp) {
130
130
  exports.serializeUserOperation = serializeUserOperation;
131
131
  // default salt is 0
132
132
  function generateSalt() {
133
- return BigInt(1);
133
+ return BigInt(0);
134
134
  }
135
135
  exports.generateSalt = generateSalt;
136
136
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gokite-aa-sdk",
3
- "version": "1.0.2",
4
- "description": "Account Abstraction SDK for Gokite",
3
+ "version": "1.0.4",
4
+ "description": "Simple and clean Account Abstraction SDK for Gokite",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {