gokite-aa-sdk 1.0.7 ā 1.0.9
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 +2 -2
- package/dist/example-token-paymaster.d.ts +1 -1
- package/dist/example-token-paymaster.js +119 -45
- package/dist/gokite-aa-sdk.js +10 -7
- package/dist/utils.js +1 -1
- package/package.json +1 -1
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: '
|
|
9
|
-
accountImplementation: '
|
|
8
|
+
accountFactory: '0xAba80c4c8748c114Ba8b61cda3b0112333C3b96E',
|
|
9
|
+
accountImplementation: '0xc033eC55a6c6fa7aDe6EcE95835113fC64Fc2e3F',
|
|
10
10
|
paymaster: '0x9Adcbf85D5c724611a490Ba9eDc4d38d6F39e92d',
|
|
11
11
|
supportedTokens: [
|
|
12
12
|
{ address: '0x0000000000000000000000000000000000000000', symbol: 'KITE', decimals: 18 },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
49
|
+
target,
|
|
30
50
|
value: 0n,
|
|
31
|
-
callData
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
+
});
|
package/dist/gokite-aa-sdk.js
CHANGED
|
@@ -78,8 +78,10 @@ class BundlerProvider {
|
|
|
78
78
|
callGasLimit: BigInt(result.result.callGasLimit),
|
|
79
79
|
verificationGasLimit: BigInt(result.result.verificationGasLimit),
|
|
80
80
|
preVerificationGas: BigInt(result.result.preVerificationGas),
|
|
81
|
-
maxFeePerGas: BigInt(result.result.maxFeePerGas || 1000000000n),
|
|
82
|
-
maxPriorityFeePerGas: BigInt(result.result.maxPriorityFeePerGas || 1000000000n), // 1 gwei
|
|
81
|
+
// maxFeePerGas: BigInt(result.result.maxFeePerGas || 1000000000n), // 1 gwei
|
|
82
|
+
// maxPriorityFeePerGas: BigInt(result.result.maxPriorityFeePerGas || 1000000000n), // 1 gwei
|
|
83
|
+
maxFeePerGas: BigInt(1000000000n),
|
|
84
|
+
maxPriorityFeePerGas: BigInt(1000000000n),
|
|
83
85
|
};
|
|
84
86
|
}
|
|
85
87
|
catch (error) {
|
|
@@ -91,7 +93,7 @@ class BundlerProvider {
|
|
|
91
93
|
async sendUserOperation(userOp, entryPoint) {
|
|
92
94
|
try {
|
|
93
95
|
const serializedUserOp = (0, utils_1.serializeUserOperation)(userOp);
|
|
94
|
-
console.log('Sending UserOp to bundler:', JSON.stringify(serializedUserOp, null, 2));
|
|
96
|
+
// console.log('Sending UserOp to bundler:', JSON.stringify(serializedUserOp, null, 2));
|
|
95
97
|
const response = await fetch(this.bundlerUrl, {
|
|
96
98
|
method: 'POST',
|
|
97
99
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -219,9 +221,7 @@ class GokiteAASDK {
|
|
|
219
221
|
userOp.paymasterAndData,
|
|
220
222
|
'0x' // signature (empty for hash calculation)
|
|
221
223
|
];
|
|
222
|
-
console.log('getUserOpHash packedUserOp:', packedUserOp);
|
|
223
224
|
const hash = await entryPoint.getUserOpHash(packedUserOp);
|
|
224
|
-
console.log('Raw hash from contract:', hash);
|
|
225
225
|
return hash;
|
|
226
226
|
}
|
|
227
227
|
/**
|
|
@@ -316,6 +316,7 @@ class GokiteAASDK {
|
|
|
316
316
|
// Update gas fields in packed format (verificationGasLimit first, callGasLimit second)
|
|
317
317
|
userOp.accountGasLimits = (0, utils_1.packAccountGasLimits)(gasEstimate.verificationGasLimit, gasEstimate.callGasLimit);
|
|
318
318
|
userOp.preVerificationGas = gasEstimate.preVerificationGas;
|
|
319
|
+
userOp.gasFees = (0, utils_1.packAccountGasLimits)(gasEstimate.maxPriorityFeePerGas, gasEstimate.maxFeePerGas);
|
|
319
320
|
const userOpHash = await this.getUserOpHash(userOp);
|
|
320
321
|
// Sign user operation
|
|
321
322
|
const signature = await signFn(userOpHash);
|
|
@@ -428,8 +429,10 @@ class GokiteAASDK {
|
|
|
428
429
|
gasEstimate.callGasLimit = gasEstimate.callGasLimit + 5000000n;
|
|
429
430
|
gasEstimate.verificationGasLimit = gasEstimate.verificationGasLimit + 1000000n;
|
|
430
431
|
gasEstimate.preVerificationGas = gasEstimate.preVerificationGas + 1000000n;
|
|
431
|
-
gasEstimate.maxFeePerGas = BigInt(
|
|
432
|
-
gasEstimate.maxPriorityFeePerGas = BigInt(
|
|
432
|
+
// gasEstimate.maxFeePerGas = BigInt(gasEstimate.maxFeePerGas || 1000000000n); // 1 gwei
|
|
433
|
+
// gasEstimate.maxPriorityFeePerGas = BigInt(gasEstimate.maxPriorityFeePerGas || 1000000000n); // 1 gwei
|
|
434
|
+
gasEstimate.maxFeePerGas = BigInt(1000000000n);
|
|
435
|
+
gasEstimate.maxPriorityFeePerGas = BigInt(1000000000n);
|
|
433
436
|
userOp.gasFees = (0, utils_1.packAccountGasLimits)(gasEstimate.maxPriorityFeePerGas, gasEstimate.maxFeePerGas);
|
|
434
437
|
// Pack gas limits and fees (note: verificationGasLimit first, callGasLimit second)
|
|
435
438
|
userOp.accountGasLimits = (0, utils_1.packAccountGasLimits)(gasEstimate.verificationGasLimit, gasEstimate.callGasLimit);
|
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 = '
|
|
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
|