gokite-aa-sdk 1.0.6 → 1.0.8

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.js CHANGED
@@ -5,8 +5,8 @@ exports.NETWORKS = {
5
5
  kite_testnet: {
6
6
  chainId: 2368,
7
7
  entryPoint: '0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108',
8
- accountFactory: '0xF0Fc19F0dc393867F19351d25EDfc5E099561cb7',
9
- accountImplementation: '0x93F5310eFd0f09db0666CA5146E63CA6Cdc6FC21',
8
+ accountFactory: '0xAba80c4c8748c114Ba8b61cda3b0112333C3b96E',
9
+ accountImplementation: '0xc033eC55a6c6fa7aDe6EcE95835113fC64Fc2e3F',
10
10
  paymaster: '0x9Adcbf85D5c724611a490Ba9eDc4d38d6F39e92d',
11
11
  supportedTokens: [
12
12
  { address: '0x0000000000000000000000000000000000000000', symbol: 'KITE', decimals: 18 },
@@ -1 +1 @@
1
- export {};
1
+ import "dotenv/config";
@@ -2,54 +2,128 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const ethers_1 = require("ethers");
4
4
  const gokite_aa_sdk_1 = require("./gokite-aa-sdk");
5
- const example_1 = require("./example");
6
- // Contract addresses on kite_testnet
7
- const ADDRESSES = {
8
- SETTLEMENT_TOKEN: '0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63',
9
- SETTLEMENT_CONTRACT: '0x8d9FaD78d5Ce247aA01C140798B9558fd64a63E3',
10
- CLIENT_AGENT_VAULT_IMPL: '0xB5AAFCC6DD4DFc2B80fb8BCcf406E1a2Fd559e23',
11
- SERVICE_REGISTRY: '0xF727EDE22C9e338a7d1d57B930dcEBbC6a66c008'
12
- };
13
- async function simpleExample() {
14
- const sdk = new gokite_aa_sdk_1.GokiteAASDK('kite_testnet', 'https://rpc-testnet.gokite.ai', 'https://bundler-service.staging.gokite.ai/rpc/');
15
- const signer = new ethers_1.ethers.Wallet(process.env.PRIVATE_KEY);
16
- const aa = sdk.getAccountAddress(signer.address);
17
- // Prepare initialization data
18
- const initializeCallData = ethers_1.ethers.Interface.from([
19
- 'function initialize(address allowedToken, address owner)'
20
- ]).encodeFunctionData('initialize', [
21
- ADDRESSES.SETTLEMENT_TOKEN,
22
- aa
23
- ]);
24
- // Create KitePass deployment bytecode
25
- const proxyConstructorData = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['address', 'address', 'bytes'], [ADDRESSES.CLIENT_AGENT_VAULT_IMPL, aa, initializeCallData]);
26
- const transparentProxyBytecode = (0, example_1.getTransparentProxyBytecode)();
27
- const fullInitCode = transparentProxyBytecode + proxyConstructorData.slice(2);
5
+ require("dotenv/config");
6
+ const NETWORK = "kite_testnet";
7
+ const RPC_URL = "https://rpc-testnet.gokite.ai";
8
+ const BUNDLER_URL = "https://bundler-service.staging.gokite.ai/rpc/";
9
+ // const BUNDLER_URL = "http://localhost:14337/rpc/";
10
+ const SETTLEMENT_TOKEN = "0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63";
11
+ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
12
+ const sdk = new gokite_aa_sdk_1.GokiteAASDK(NETWORK, RPC_URL, BUNDLER_URL);
13
+ const sessionInterface = new ethers_1.ethers.Interface([
14
+ "function createSession(bytes32 sessionId, address settlementToken, tuple(uint256 timeWindow, uint160 budget, uint96 initialWindowStartTime, bytes32[] targetProviders)[] rules)",
15
+ "function setSpendingRules(bytes32 sessionId, tuple(uint256 timeWindow, uint160 budget, uint96 initialWindowStartTime, bytes32[] targetProviders)[] rules)",
16
+ ]);
17
+ const erc20Interface = new ethers_1.ethers.Interface([
18
+ "function transfer(address to, uint256 amount)",
19
+ ]);
20
+ /**
21
+ * Frontend note:
22
+ * 1. Creates an AA session and seeds it with example spending rules (daily, weekly, per-transaction caps).
23
+ * 2. Updates that session to demonstrate how rule changes propagate on-chain.
24
+ * 3. Executes an ERC20 transfer
25
+ */
26
+ const PRIVATE_KEY = process.env.PRIVATE_KEY;
27
+ const PAYMENT_TOKEN = process.env.PAYMENT_TOKEN ?? SETTLEMENT_TOKEN;
28
+ if (!PRIVATE_KEY)
29
+ throw new Error("Missing PRIVATE_KEY env variable");
30
+ const signer = new ethers_1.ethers.Wallet(PRIVATE_KEY);
31
+ const sessionId = (0, ethers_1.randomBytes)(32);
32
+ const secondsPerDay = 86400;
33
+ function currentDayStart() {
34
+ const now = Math.floor(Date.now() / 1000);
35
+ return BigInt(Math.floor(now / secondsPerDay) * secondsPerDay);
36
+ }
37
+ function currentWeekStart() {
38
+ const now = new Date();
39
+ const dayStart = Number(currentDayStart());
40
+ const weekday = now.getUTCDay();
41
+ const daysFromMonday = (weekday + 6) % 7;
42
+ return BigInt(dayStart - daysFromMonday * secondsPerDay);
43
+ }
44
+ async function signUserOp(hash) {
45
+ return signer.signMessage(ethers_1.ethers.getBytes(hash));
46
+ }
47
+ async function sendWithTokenPayment(target, callData) {
28
48
  const request = {
29
- target: aa,
49
+ target,
30
50
  value: 0n,
31
- callData: ethers_1.ethers.Interface.from([
32
- 'function performCreate(uint256 value, bytes calldata initCode) returns (address)'
33
- ]).encodeFunctionData('performCreate', [0n, fullInitCode])
51
+ callData,
34
52
  };
35
- console.log('šŸ“Š Estimate transaction...');
36
53
  const estimate = await sdk.estimateUserOperation(signer.address, request);
37
- console.log('Total cost:', estimate.totalCostKITEFormatted);
38
- console.log('Cost with token:', estimate.supportedTokens);
39
- console.log('Sponsorship available:', estimate.sponsorshipAvailable);
40
- console.log('Remaining sponsorships:', estimate.remainingSponsorships);
41
- console.log('Payment options:', estimate.supportedTokens.map(t => `${t.tokenSymbol}: ${t.formattedCost}`));
42
- // Step 2: Select payment method and execute
43
- const tokenAddress = estimate.sponsorshipAvailable
44
- ? '0x0000000000000000000000000000000000000000' // Use sponsorship/KITE
45
- : '0x0fF5393387ad2f9f691FD6Fd28e07E3969e27e63'; // Use Test USD
46
- console.log('\nšŸš€ Execute transaction...');
47
- const result = await sdk.sendUserOperationWithPayment(signer.address, request, estimate.userOp, tokenAddress, async (hash) => signer.signMessage(ethers_1.ethers.getBytes(hash)));
48
- console.log('āœ… Done!');
49
- console.log('UserOp Hash:', result.userOpHash);
50
- console.log('Status:', result.status.status);
54
+ const tokenAddress = estimate.sponsorshipAvailable ? ZERO_ADDRESS : PAYMENT_TOKEN;
55
+ const response = await sdk.sendUserOperationWithPayment(signer.address, request, estimate.userOp, tokenAddress, signUserOp);
56
+ if (response.status.status !== "success") {
57
+ throw new Error(response.status.reason ?? "User operation failed");
58
+ }
59
+ return response.status.transactionHash ?? "";
60
+ }
61
+ function initialRules() {
62
+ return [
63
+ {
64
+ timeWindow: 86400n,
65
+ budget: ethers_1.ethers.parseUnits("100", 18),
66
+ initialWindowStartTime: currentDayStart(),
67
+ targetProviders: [],
68
+ },
69
+ {
70
+ timeWindow: 604800n,
71
+ budget: ethers_1.ethers.parseUnits("1000", 18),
72
+ initialWindowStartTime: currentWeekStart(),
73
+ targetProviders: [],
74
+ },
75
+ {
76
+ timeWindow: 0n,
77
+ budget: ethers_1.ethers.parseUnits("10", 18),
78
+ initialWindowStartTime: 0n,
79
+ targetProviders: [
80
+ ethers_1.ethers.keccak256(ethers_1.ethers.toUtf8Bytes("provider1")),
81
+ ],
82
+ },
83
+ ];
51
84
  }
52
- // Run
53
- if (require.main === module) {
54
- simpleExample().catch(console.error);
85
+ function updatedRules() {
86
+ return [
87
+ {
88
+ timeWindow: 86400n,
89
+ budget: ethers_1.ethers.parseUnits("200", 18),
90
+ initialWindowStartTime: currentDayStart(),
91
+ targetProviders: [],
92
+ },
93
+ {
94
+ timeWindow: 0n,
95
+ budget: ethers_1.ethers.parseUnits("5", 18),
96
+ initialWindowStartTime: 0n,
97
+ targetProviders: [],
98
+ },
99
+ ];
100
+ }
101
+ async function main() {
102
+ const aaWallet = sdk.getAccountAddress(signer.address);
103
+ const createSessionData = sessionInterface.encodeFunctionData("createSession", [
104
+ sessionId,
105
+ SETTLEMENT_TOKEN,
106
+ initialRules(),
107
+ ]);
108
+ const createTx = await sendWithTokenPayment(aaWallet, createSessionData);
109
+ console.log(`createSession tx: ${createTx}`);
110
+ await new Promise(resolve => setTimeout(resolve, 10000));
111
+ const updateRulesData = sessionInterface.encodeFunctionData("setSpendingRules", [
112
+ sessionId,
113
+ updatedRules(),
114
+ ]);
115
+ const updateTx = await sendWithTokenPayment(aaWallet, updateRulesData);
116
+ console.log(`setSpendingRules tx: ${updateTx}`);
117
+ await new Promise(resolve => setTimeout(resolve, 10000));
118
+ const RECIPIENT = signer.address;
119
+ const transferData = erc20Interface.encodeFunctionData("transfer", [
120
+ RECIPIENT,
121
+ ethers_1.ethers.parseUnits("0", 18),
122
+ ]);
123
+ const transferTx = await sendWithTokenPayment(SETTLEMENT_TOKEN, transferData);
124
+ console.log(`transfer tx: ${transferTx}`);
55
125
  }
126
+ main().catch((error) => {
127
+ console.error(error);
128
+ process.exit(1);
129
+ });
@@ -91,7 +91,7 @@ class BundlerProvider {
91
91
  async sendUserOperation(userOp, entryPoint) {
92
92
  try {
93
93
  const serializedUserOp = (0, utils_1.serializeUserOperation)(userOp);
94
- console.log('Sending UserOp to bundler:', JSON.stringify(serializedUserOp, null, 2));
94
+ // console.log('Sending UserOp to bundler:', JSON.stringify(serializedUserOp, null, 2));
95
95
  const response = await fetch(this.bundlerUrl, {
96
96
  method: 'POST',
97
97
  headers: { 'Content-Type': 'application/json' },
@@ -219,9 +219,7 @@ class GokiteAASDK {
219
219
  userOp.paymasterAndData,
220
220
  '0x' // signature (empty for hash calculation)
221
221
  ];
222
- console.log('getUserOpHash packedUserOp:', packedUserOp);
223
222
  const hash = await entryPoint.getUserOpHash(packedUserOp);
224
- console.log('Raw hash from contract:', hash);
225
223
  return hash;
226
224
  }
227
225
  /**
@@ -428,9 +426,9 @@ class GokiteAASDK {
428
426
  gasEstimate.callGasLimit = gasEstimate.callGasLimit + 5000000n;
429
427
  gasEstimate.verificationGasLimit = gasEstimate.verificationGasLimit + 1000000n;
430
428
  gasEstimate.preVerificationGas = gasEstimate.preVerificationGas + 1000000n;
431
- const maxFeePerGas = BigInt(10000000); // 0.001 gwei
432
- const maxPriorityFeePerGas = BigInt(1); // 1 wei
433
- userOp.gasFees = (0, utils_1.packAccountGasLimits)(maxPriorityFeePerGas, maxFeePerGas);
429
+ gasEstimate.maxFeePerGas = BigInt(100000000);
430
+ gasEstimate.maxPriorityFeePerGas = BigInt(1);
431
+ userOp.gasFees = (0, utils_1.packAccountGasLimits)(gasEstimate.maxPriorityFeePerGas, gasEstimate.maxFeePerGas);
434
432
  // Pack gas limits and fees (note: verificationGasLimit first, callGasLimit second)
435
433
  userOp.accountGasLimits = (0, utils_1.packAccountGasLimits)(gasEstimate.verificationGasLimit, gasEstimate.callGasLimit);
436
434
  userOp.preVerificationGas = gasEstimate.preVerificationGas;
package/dist/utils.js CHANGED
@@ -7,7 +7,7 @@ const ethers_1 = require("ethers");
7
7
  * This matches the logic in GokiteAccountFactory.getAddress()
8
8
  */
9
9
  function getAccountAddress(factoryAddress, implementationAddress, owner, salt) {
10
- const proxyCreationCode = '0x60806040526102c68038038061001481610188565b928339810190604081830312610183578051906001600160a01b03821690818303610183576020810151906001600160401b038211610183570183601f820112156101835780519061006d610068836101c3565b610188565b94828652602083830101116101835760005b82811061016e575050602060009185010152813b1561015a577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151156101415760008083602061012995519101845af43d15610139573d91610119610068846101c3565b9283523d6000602085013e6101de565b505b604051608690816102408239f35b6060916101de565b5050341561012b5763b398979f60e01b60005260046000fd5b634c9c8ce360e01b60005260045260246000fd5b8060208092840101518282890101520161007f565b600080fd5b6040519190601f01601f191682016001600160401b038111838210176101ad57604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116101ad57601f01601f191660200190565b9061020457508051156101f357805190602001fd5b630a12f52160e11b60005260046000fd5b81511580610236575b610215575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561020d56fe60806040527f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5460009081906001600160a01b0316368280378136915af43d6000803e15604b573d6000f35b3d6000fdfea26469706673582212201d39938ba86a38b154a247ca9c527d397a6a764ffd2fae8535a9595bf97d45a764736f6c634300081c0033';
10
+ const proxyCreationCode = '0x60806040526102a88038038061001481610168565b92833981016040828203126101645781516001600160a01b03811692909190838303610164576020810151906001600160401b03821161016457019281601f8501121561016457835161006e610069826101a1565b610168565b9481865260208601936020838301011161016457815f926020809301865e86010152823b15610152577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a282511561013a575f8091610122945190845af43d15610132573d91610113610069846101a1565b9283523d5f602085013e6101bc565b505b604051608d908161021b8239f35b6060916101bc565b50505034156101245763b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f5260045260245ffd5b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761018d57604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b03811161018d57601f01601f191660200190565b906101e057508051156101d157602081519101fd5b63d6bda27560e01b5f5260045ffd5b81511580610211575b6101f1575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b156101e956fe60806040525f8073ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5416368280378136915af43d5f803e156053573d5ff35b3d5ffdfea2646970667358221220359eac519e2625610420a0e3cfdfe26e6cc711dbb451880735ac4544d4ccdcf264736f6c634300081c0033';
11
11
  const initializeCallData = encodeFunctionCall(['function initialize(address)'], 'initialize', [owner]);
12
12
  const constructorArgs = ethers_1.ethers.AbiCoder.defaultAbiCoder().encode(['address', 'bytes'], [implementationAddress, initializeCallData]);
13
13
  // Full creation code = creation code + constructor args
@@ -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(0);
133
+ return BigInt(5);
134
134
  }
135
135
  exports.generateSalt = generateSalt;
136
136
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gokite-aa-sdk",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "Simple and clean Account Abstraction SDK for Gokite",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",