gokite-aa-sdk 1.0.3 → 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/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.js CHANGED
@@ -437,42 +437,58 @@ async function exampleUsage() {
437
437
  const userEoa = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
438
438
  // actual token recipient address
439
439
  const toAddress = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
440
- // 1. Transfer ERC20 tokens
441
- console.log('\n=== 1. ERC20 Transfer ===');
442
- const transferResult = await transferERC20(userEoa, toAddress, '10', ADDRESSES.SETTLEMENT_TOKEN, 18, signFunction);
443
- console.log('Transfer result:', transferResult);
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);
444
451
  // 2. Deploy KitePass
445
452
  console.log('\n=== 2. Deploy KitePass ===');
446
453
  const deployResult = await deployKitePass(userEoa, signFunction);
447
454
  console.log('Deploy result:', deployResult);
448
- if (deployResult.success && deployResult.proxyAddress) {
449
- // 3. Configure spending rules
450
- console.log('\n=== 3. Configure Spending Rules ===');
451
- const configResult = await configureSpendingRules(userEoa, deployResult.proxyAddress, signFunction);
452
- console.log('Config result:', configResult);
453
- // 4. View spending rules
454
- console.log('\n=== 4. View Spending Rules ===');
455
- const rulesResult = await viewSpendingRules(deployResult.proxyAddress);
456
- console.log('Rules result:', rulesResult);
457
- }
458
- // 5. Register service
459
- console.log('\n=== 5. Register Service ===');
460
- // serviceId, get from backend
461
- const serviceId = ethers_1.ethers.hexlify((0, ethers_1.randomBytes)(32));
462
- const sdk = initializeSDK();
463
- const serviceOwner = sdk.getAccountAddress(userEoa);
464
- const serviceResult = await registerService(userEoa, serviceId, {
465
- serviceOwner: serviceOwner,
466
- priceModel: 0,
467
- unitPrice: 100,
468
- // provider Id, bytes32
469
- provider: ethers_1.ethers.hexlify((0, ethers_1.randomBytes)(32)),
470
- // service metadata, currently not used
471
- metadata: '0x',
472
- name: 'Test Service',
473
- isPublic: true
474
- }, signFunction);
475
- console.log('Service result:', serviceResult);
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);
476
492
  }
477
493
  // Run example if executed directly
478
494
  if (require.main === module) {
@@ -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,9 +304,9 @@ 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
@@ -410,9 +414,150 @@ class GokiteAASDK {
410
414
  }
411
415
  throw new Error(`UserOp polling timeout: ${userOpHash} (attempt ${retryCount})`);
412
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
+ }
413
500
  /**
414
501
  * Send user operation and wait for completion with detailed status
415
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
+ }
416
561
  async sendUserOperationAndWait(owner, request, signFn, salt, paymasterAddress, pollingOptions) {
417
562
  console.log('Sending UserOp and waiting for completion...');
418
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gokite-aa-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "Simple and clean Account Abstraction SDK for Gokite",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,47 +0,0 @@
1
- import { GokiteAASDK } from './gokite-aa-sdk';
2
- import "dotenv/config";
3
- declare function handleAAError(error: any): {
4
- type: string;
5
- message: string;
6
- details?: any;
7
- };
8
- /**
9
- * ClientAgentVault Integration Tests
10
- *
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)
17
- *
18
- * how to use:
19
- * - modify the contract addresses and parameters as needed
20
- */
21
- declare function clientAgentVaultIntegrationTests(): Promise<void>;
22
- /**
23
- * Test 1: Deploy ClientAgentVault Proxy via AA wallet's performCreate
24
- */
25
- declare function DeployClientAgentVaultProxy(sdk: GokiteAASDK, eoa: string, aa: string, signFunction: any): Promise<string | null>;
26
- /**
27
- * Test 2: Configure Spending Rules
28
- */
29
- declare function ConfigureSpendingRules(sdk: GokiteAASDK, owner: string, proxyAddress: string, signFunction: any): Promise<void>;
30
- /**
31
- * Test 3: View Spending Rules (Read-only, no transaction sent)
32
- */
33
- declare function ViewSpendingRules(sdk: GokiteAASDK, proxyAddress: string): Promise<void>;
34
- /**
35
- * Test 4: Withdraw Funds
36
- */
37
- declare function WithdrawFunds(sdk: GokiteAASDK, owner: string, proxyAddress: string, signFunction: any): Promise<void>;
38
- /**
39
- * Test 5: Check Token Balance (Read-only)
40
- */
41
- declare function CheckTokenBalance(sdk: GokiteAASDK, proxyAddress: string): Promise<void>;
42
- /**
43
- * Legacy example for basic AA operations
44
- */
45
- declare function basicExample(): Promise<void>;
46
- export { clientAgentVaultIntegrationTests, basicExample, DeployClientAgentVaultProxy, ConfigureSpendingRules, ViewSpendingRules, WithdrawFunds, CheckTokenBalance, handleAAError, };
47
- export declare const example: typeof basicExample;
@@ -1,426 +0,0 @@
1
- "use strict";
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;
4
- const gokite_aa_sdk_1 = require("./gokite-aa-sdk");
5
- const types_1 = require("./types");
6
- const ethers_1 = require("ethers");
7
- require("dotenv/config");
8
- // Contract addresses on kite_testnet
9
- const ADDRESSES = {
10
- SETTLEMENT_TOKEN: '0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63',
11
- SETTLEMENT_CONTRACT: '0x8d9FaD78d5Ce247aA01C140798B9558fd64a63E3',
12
- CLIENT_AGENT_VAULT_IMPL: '0xB5AAFCC6DD4DFc2B80fb8BCcf406E1a2Fd559e23'
13
- };
14
- function handleAAError(error) {
15
- if (error instanceof types_1.AASDKError) {
16
- return {
17
- type: error.type,
18
- message: error.message,
19
- details: error.details
20
- };
21
- }
22
- // Fallback for other errors
23
- return {
24
- type: 'UNKNOWN_ERROR',
25
- message: error.message || 'An unknown error occurred',
26
- details: error
27
- };
28
- }
29
- exports.handleAAError = handleAAError;
30
- /**
31
- * Get TransparentUpgradeableProxy bytecode
32
- */
33
- function getTransparentProxyBytecode() {
34
- // This is the bytecode for TransparentUpgradeableProxy
35
- return '0x60a0604052610b278038038061001481610293565b928339810160608282031261028e5761002c826102b8565b610038602084016102b8565b604084015190936001600160401b03821161028e570182601f8201121561028e5780519061006d610068836102cc565b610293565b938285526020838301011161028e5760005b828110610279575050602060009184010152803b15610258577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0383169081179091557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a281511561023f5760008083602061013595519101845af43d15610237573d91610125610068846102cc565b9283523d6000602085013e6102e7565b505b604051906104918083016001600160401b0381118482101761022157602092849261067684396001600160a01b031681520301906000f080156102155760018060a01b031680608052600080516020610b07833981519152547f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6040805160018060a01b0384168152846020820152a181156101ff576001600160a01b03191617600080516020610b078339815191525560405161032d908161034982396080518160070152f35b633173bdd160e11b600052600060045260246000fd5b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b6060916102e7565b505034156101375763b398979f60e01b60005260046000fd5b634c9c8ce360e01b60009081526001600160a01b0391909116600452602490fd5b8060208092840101518282880101520161007f565b600080fd5b6040519190601f01601f191682016001600160401b0381118382101761022157604052565b51906001600160a01b038216820361028e57565b6001600160401b03811161022157601f01601f191660200190565b9061030d57508051156102fc57805190602001fd5b630a12f52160e11b60005260046000fd5b8151158061033f575b61031e575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561031656fe6080604052337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031603610069576000356001600160e01b03191663278f794360e11b1461005f576334ad5dbb60e21b60005260046000fd5b610067610113565b005b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460009081906001600160a01b0316368280378136915af43d6000803e156100b1573d6000f35b3d6000fd5b634e487b7160e01b600052604160045260246000fd5b6040519190601f01601f1916820167ffffffffffffffff8111838210176100f257604052565b6100b6565b67ffffffffffffffff81116100f257601f01601f191660200190565b3660041161019d57604036600319011261019d576004356001600160a01b0381169081900361019d576024359067ffffffffffffffff821161019d573660238301121561019d5781600401359061017161016c836100f7565b6100cc565b91808352366024828601011161019d57602081600092602461019b970183870137840101526101a2565b565b600080fd5b90813b15610239577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0384169081179091557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a280511561021f5761021c9161025b565b50565b50503461022857565b63b398979f60e01b60005260046000fd5b50634c9c8ce360e01b60009081526001600160a01b0391909116600452602490fd5b60008061028f93602081519101845af43d15610292573d9161027f61016c846100f7565b9283523d6000602085013e610296565b90565b6060915b906102bc57508051156102ab57805190602001fd5b630a12f52160e11b60005260046000fd5b815115806102ee575b6102cd575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b156102c556fea2646970667358221220597147005a6fe654561cbab25a93153cc233180473a65a90bd427f0c1f41018764736f6c634300081c003360803460bc57601f61049138819003918201601f19168301916001600160401b0383118484101760c15780849260209460405283398101031260bc57516001600160a01b0381169081900360bc57801560a657600080546001600160a01b031981168317825560405192916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a36103b990816100d88239f35b631e4fbdf760e01b600052600060045260246000fd5b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604052600436101561001257600080fd5b6000803560e01c8063715018a6146102875780638da5cb5b146102605780639623609d1461012f578063ad3cb1cc146100e25763f2fde38b1461005457600080fd5b346100df5760203660031901126100df576004356001600160a01b038116908190036100dd5761008261035a565b80156100c95781546001600160a01b03198116821783556001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b631e4fbdf760e01b82526004829052602482fd5b505b80fd5b50346100df57806003193601126100df575061012b6040516101056040826102e1565b60058152640352e302e360dc1b6020820152604051918291602083526020830190610319565b0390f35b5060603660031901126100df576004356001600160a01b038116908190036100dd576024356001600160a01b038116908190036102405760443567ffffffffffffffff811161025c573660238201121561025c57806004013567ffffffffffffffff8111610248576040518593929091906101b4601f8301601f1916602001846102e1565b81835236602483830101116102445781859260246020930183860137830101526101dc61035a565b833b156102405761021293839260405180968194829363278f794360e11b84526004840152604060248401526044830190610319565b039134905af18015610233576102255780f35b61022e916102e1565b388180f35b50604051903d90823e3d90fd5b8280fd5b8480fd5b634e487b7160e01b85526041600452602485fd5b8380fd5b50346100df57806003193601126100df57546040516001600160a01b039091168152602090f35b50346100df57806003193601126100df576102a061035a565b80546001600160a01b03198116825581906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b90601f8019910116810190811067ffffffffffffffff82111761030357604052565b634e487b7160e01b600052604160045260246000fd5b919082519283825260005b848110610345575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201610324565b6000546001600160a01b0316330361036e57565b63118cdaa760e01b6000523360045260246000fdfea26469706673582212207bc32ec723f6be34b228b59aef2ef61b4e6a8eb5bc67fcdd495248566e3b6e0c64736f6c634300081c0033b53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103';
36
- }
37
- /**
38
- * ClientAgentVault Integration Tests
39
- *
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
49
- */
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;
70
- }
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
- }
85
- exports.clientAgentVaultIntegrationTests = clientAgentVaultIntegrationTests;
86
- /**
87
- * Test 1: Deploy ClientAgentVault Proxy via AA wallet's performCreate
88
- */
89
- async function DeployClientAgentVaultProxy(sdk, eoa, aa, signFunction) {
90
- try {
91
- // Prepare initialization data for ClientAgentVault
92
- const initializeCallData = ethers_1.ethers.Interface.from([
93
- 'function initialize(address allowedToken, address owner)'
94
- ]).encodeFunctionData('initialize', [
95
- 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
104
- ]);
105
- // Full deployment bytecode = creation code + constructor params
106
- const transparentProxyBytecode = getTransparentProxyBytecode();
107
- const fullInitCode = transparentProxyBytecode + proxyConstructorData.slice(2);
108
- // Create UserOperation to call performCreate
109
- const deployRequest = {
110
- target: aa,
111
- value: 0n,
112
- callData: ethers_1.ethers.Interface.from([
113
- 'function performCreate(uint256 value, bytes calldata initCode) returns (address)'
114
- ]).encodeFunctionData('performCreate', [
115
- 0n,
116
- fullInitCode // proxy deployment bytecode + constructor params
117
- ])
118
- };
119
- console.log('Deploying ClientAgentVault proxy...');
120
- console.log('- Implementation:', ADDRESSES.CLIENT_AGENT_VAULT_IMPL);
121
- console.log('- AllowedToken:', ADDRESSES.SETTLEMENT_TOKEN);
122
- const result = await sdk.sendUserOperationAndWait(eoa, deployRequest, signFunction);
123
- 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
- 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
- }
135
- }
136
- else {
137
- console.log('āŒ Deployment failed:', result.status.reason);
138
- }
139
- }
140
- catch (error) {
141
- console.error('āŒ Test 1 failed:', error);
142
- }
143
- return null;
144
- }
145
- exports.DeployClientAgentVaultProxy = DeployClientAgentVaultProxy;
146
- /**
147
- * Test 2: Configure Spending Rules
148
- */
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
164
- try {
165
- // Define spending rules
166
- const rulesToAdd = [
167
- {
168
- timeWindow: 86400n,
169
- budget: ethers_1.ethers.parseUnits('100', 18),
170
- initialWindowStartTime: todayStartTimestamp,
171
- targetProviders: [] // Empty means applies to all providers
172
- },
173
- {
174
- timeWindow: 604800n,
175
- budget: ethers_1.ethers.parseUnits('1000', 18),
176
- initialWindowStartTime: currentWeekStartTimestamp,
177
- targetProviders: []
178
- },
179
- {
180
- timeWindow: 0,
181
- budget: ethers_1.ethers.parseUnits('10', 18),
182
- initialWindowStartTime: 0n,
183
- targetProviders: [ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes('provider1'))]
184
- }
185
- ];
186
- const configureRequest = {
187
- target: proxyAddress,
188
- value: 0n,
189
- 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
- ])
195
- };
196
- 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);
200
- if (result.status.status === 'success') {
201
- console.log('āœ… Spending rules configured successfully!');
202
- console.log('Transaction hash:', result.status.transactionHash);
203
- }
204
- else {
205
- console.log('āŒ Configuration failed:', result.status.reason);
206
- }
207
- }
208
- 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
- }
228
- }
229
- }
230
- exports.ConfigureSpendingRules = ConfigureSpendingRules;
231
- /**
232
- * Test 3: View Spending Rules (Read-only, no transaction sent)
233
- */
234
- async function ViewSpendingRules(sdk, proxyAddress) {
235
- try {
236
- const provider = new ethers_1.ethers.JsonRpcProvider('https://rpc-testnet.gokite.ai');
237
- const contract = new ethers_1.ethers.Contract(proxyAddress, [
238
- 'function getSpendingRules() view returns (tuple(tuple(uint256 timeWindow, uint160 budget, uint96 initialWindowStartTime, bytes32[] targetProviders) rule, tuple(uint128 amountUsed, uint128 currentTimeWindowStartTime) usage)[])'
239
- ], provider);
240
- console.log('Fetching spending rules...');
241
- 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
- });
250
- }
251
- catch (error) {
252
- console.error('āŒ Test 3 failed:', error);
253
- }
254
- }
255
- exports.ViewSpendingRules = ViewSpendingRules;
256
- // transfer erc20 tokens from aa to another address
257
- async function transferERC20(sdk, owner, proxyAddress, signFunction, to, amount, token, tokenDecimals) {
258
- try {
259
- const transferRequest = {
260
- target: proxyAddress,
261
- value: 0n,
262
- callData: ethers_1.ethers.Interface.from([
263
- 'function transfer(address to, uint256 amount)'
264
- ]).encodeFunctionData('transfer', [
265
- to,
266
- ethers_1.ethers.parseUnits(amount.toString(), tokenDecimals) // amount
267
- ])
268
- };
269
- console.log('Transferring ERC20 tokens...');
270
- console.log(`- Token: ${token}`);
271
- console.log(`- Amount: ${ethers_1.ethers.formatUnits(amount, tokenDecimals)} tokens`);
272
- const result = await sdk.sendUserOperationAndWait(owner, transferRequest, signFunction);
273
- if (result.status.status === 'success') {
274
- console.log('āœ… ERC20 transfer successful!');
275
- console.log('Transaction hash:', result.status.transactionHash);
276
- }
277
- else {
278
- console.log('āŒ ERC20 transfer failed:', result.status.reason);
279
- }
280
- }
281
- catch (error) {
282
- console.error('āŒ Test 4 failed:', error);
283
- }
284
- }
285
- /**
286
- * Test 4: Withdraw Funds
287
- */
288
- async function WithdrawFunds(sdk, owner, proxyAddress, signFunction) {
289
- try {
290
- const withdrawAmount = ethers_1.ethers.parseUnits('50', 18); // Withdraw 50 tokens
291
- const withdrawRequest = {
292
- target: proxyAddress,
293
- value: 0n,
294
- callData: ethers_1.ethers.Interface.from([
295
- 'function withdrawFunds(address token, uint256 amount)'
296
- ]).encodeFunctionData('withdrawFunds', [
297
- ADDRESSES.SETTLEMENT_TOKEN,
298
- withdrawAmount // amount to withdraw
299
- ])
300
- };
301
- console.log('Withdrawing funds...');
302
- console.log(`- Token: ${ADDRESSES.SETTLEMENT_TOKEN}`);
303
- console.log(`- Amount: ${ethers_1.ethers.formatUnits(withdrawAmount, 18)} tokens`);
304
- const result = await sdk.sendUserOperationAndWait(owner, withdrawRequest, signFunction);
305
- if (result.status.status === 'success') {
306
- console.log('āœ… Funds withdrawn successfully!');
307
- console.log('Transaction hash:', result.status.transactionHash);
308
- }
309
- else {
310
- console.log('āŒ Withdrawal failed:', result.status.reason);
311
- }
312
- }
313
- catch (error) {
314
- console.error('āŒ Test 4 failed:', error);
315
- }
316
- }
317
- exports.WithdrawFunds = WithdrawFunds;
318
- /**
319
- * Test 5: Check Token Balance (Read-only)
320
- */
321
- async function CheckTokenBalance(sdk, proxyAddress) {
322
- try {
323
- const provider = new ethers_1.ethers.JsonRpcProvider('https://rpc-testnet.gokite.ai');
324
- const tokenContract = new ethers_1.ethers.Contract(ADDRESSES.SETTLEMENT_TOKEN, [
325
- 'function balanceOf(address account) view returns (uint256)',
326
- 'function symbol() view returns (string)',
327
- 'function decimals() view returns (uint8)'
328
- ], provider);
329
- console.log('Checking token balance...');
330
- const [balance, symbol, decimals] = await Promise.all([
331
- tokenContract.balanceOf(proxyAddress),
332
- tokenContract.symbol(),
333
- tokenContract.decimals()
334
- ]);
335
- console.log('āœ… Token Balance:');
336
- console.log(` - Address: ${proxyAddress}`);
337
- console.log(` - Token: ${symbol} (${ADDRESSES.SETTLEMENT_TOKEN})`);
338
- console.log(` - Balance: ${ethers_1.ethers.formatUnits(balance, decimals)} ${symbol}`);
339
- }
340
- catch (error) {
341
- console.error('āŒ Test 5 failed:', error);
342
- }
343
- }
344
- exports.CheckTokenBalance = CheckTokenBalance;
345
- /**
346
- * Legacy example for basic AA operations
347
- */
348
- async function basicExample() {
349
- console.log('\n=== Basic AA SDK Example ===');
350
- // Initialize SDK
351
- const sdk = new gokite_aa_sdk_1.GokiteAASDK('kite_testnet', 'https://rpc-testnet.gokite.ai', 'http://localhost:14337/rpc/');
352
- const owner = '0x4A50DCA63d541372ad36E5A36F1D542d51164F19';
353
- const accountAddress = sdk.getAccountAddress(owner);
354
- console.log('Account address:', accountAddress);
355
- // Simple ETH transfer example
356
- const sendEthRequest = {
357
- target: '0x4A50DCA63d541372ad36E5A36F1D542d51164F19',
358
- value: ethers_1.ethers.parseEther('0.001'),
359
- callData: '0x'
360
- };
361
- const signFunction = async (userOpHash) => {
362
- const signer_pk = process.env.PRIVATE_KEY;
363
- const signer = new ethers_1.ethers.Wallet(signer_pk);
364
- return signer.signMessage(ethers_1.ethers.getBytes(userOpHash));
365
- };
366
- try {
367
- const result = await sdk.sendUserOperationAndWait(owner, sendEthRequest, signFunction);
368
- if (result.status.status === 'success') {
369
- console.log('āœ… ETH transfer successful!');
370
- console.log('Transaction hash:', result.status.transactionHash);
371
- }
372
- else {
373
- console.log('āŒ ETH transfer failed:', result.status.reason);
374
- }
375
- }
376
- catch (error) {
377
- console.error('āŒ Basic example failed:', error);
378
- }
379
- }
380
- exports.basicExample = basicExample;
381
- /**
382
- * Parse ContractCreated event from transaction logs to get deployed proxy address
383
- * Event: ContractCreated(address indexed contractAddress)
384
- */
385
- async function parseContractCreatedEvent(transactionHash) {
386
- try {
387
- const provider = new ethers_1.ethers.JsonRpcProvider('https://rpc-testnet.gokite.ai');
388
- const receipt = await provider.getTransactionReceipt(transactionHash);
389
- if (!receipt) {
390
- console.error('Transaction receipt not found');
391
- return null;
392
- }
393
- // ContractCreated event signature: ContractCreated(address indexed contractAddress)
394
- const contractCreatedEventSignature = ethers_1.ethers.id('ContractCreated(address)');
395
- console.log('Parsing transaction logs...');
396
- console.log(`Total logs: ${receipt.logs.length}`);
397
- for (const log of receipt.logs) {
398
- // Check if this log matches the ContractCreated event
399
- if (log.topics[0] === contractCreatedEventSignature) {
400
- // The first topic is the event signature
401
- // The second topic is the indexed contractAddress
402
- const contractAddress = ethers_1.ethers.AbiCoder.defaultAbiCoder().decode(['address'], log.topics[1])[0];
403
- console.log('Found ContractCreated event:');
404
- console.log('- Contract Address:', contractAddress);
405
- console.log('- From Address:', log.address);
406
- return contractAddress;
407
- }
408
- }
409
- console.log('No ContractCreated event found in transaction logs');
410
- return null;
411
- }
412
- catch (error) {
413
- console.error('Error parsing ContractCreated event:', error);
414
- return null;
415
- }
416
- }
417
- async function main() {
418
- // Run ClientAgentVault integration tests
419
- await clientAgentVaultIntegrationTests();
420
- // // Run basic AA example
421
- // await basicExample();
422
- console.log('\nāœ… All examples completed!');
423
- }
424
- // Legacy export for backwards compatibility
425
- exports.example = basicExample;
426
- main().catch(console.error);