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 +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 +4 -6
- package/dist/utils.js +2 -2
- 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
|
@@ -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
|
-
|
|
432
|
-
|
|
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 = '
|
|
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(
|
|
133
|
+
return BigInt(5);
|
|
134
134
|
}
|
|
135
135
|
exports.generateSalt = generateSalt;
|
|
136
136
|
/**
|