gokite-aa-sdk 1.0.0

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.
@@ -0,0 +1,70 @@
1
+ import { UserOperation, UserOperationRequest, BatchUserOperationRequest, UserOperationGasEstimate, UserOperationStatus, SignFunction, PollingOptions } from './types';
2
+ /**
3
+ * Main Gokite AA SDK class
4
+ */
5
+ export declare class GokiteAASDK {
6
+ private config;
7
+ private provider;
8
+ private ethersProvider;
9
+ constructor(network: string, rpcUrl: string, bundlerUrl?: string);
10
+ /**
11
+ * Calculate account address for a given owner and salt
12
+ */
13
+ getAccountAddress(owner: string, salt?: bigint): string;
14
+ /**
15
+ * Get account nonce
16
+ */
17
+ getAccountNonce(accountAddress: string): Promise<bigint>;
18
+ /**
19
+ * Get user operation hash from EntryPoint contract
20
+ */
21
+ getUserOpHash(userOp: any): Promise<string>;
22
+ /**
23
+ * Check if account is deployed
24
+ */
25
+ isAccountDeloyed(accountAddress: string): Promise<boolean>;
26
+ /**
27
+ * Build init code for account creation
28
+ */
29
+ buildInitCode(owner: string, salt: bigint): string;
30
+ /**
31
+ * Build call data for single transaction
32
+ */
33
+ buildCallData(request: UserOperationRequest): string;
34
+ /**
35
+ * Build call data for batch transactions
36
+ */
37
+ buildBatchCallData(request: BatchUserOperationRequest): string;
38
+ /**
39
+ * Create user operation
40
+ */
41
+ createUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest, salt?: bigint, paymasterAddress?: string): Promise<Partial<UserOperation>>;
42
+ /**
43
+ * Estimate gas for user operation
44
+ */
45
+ estimateGas(userOp: Partial<UserOperation>): Promise<UserOperationGasEstimate>;
46
+ /**
47
+ * Sign and send user operation
48
+ */
49
+ sendUserOperation(owner: string, request: UserOperationRequest | BatchUserOperationRequest, signFn: SignFunction, salt?: bigint, paymasterAddress?: string): Promise<string>;
50
+ /**
51
+ * Send user operation directly to EntryPoint contract (bypassing bundler)
52
+ * Note: This requires a signer to pay for gas. For now, we'll try with the read-only provider.
53
+ */
54
+ sendUserOperationDirectly(owner: string, userOp: UserOperation): Promise<string>;
55
+ /**
56
+ * Get user operation status
57
+ */
58
+ getUserOperationStatus(userOpHash: string): Promise<UserOperationStatus>;
59
+ /**
60
+ * Enhanced polling for user operation status with detailed result parsing
61
+ */
62
+ pollUserOperationStatus(userOpHash: string, options?: PollingOptions): Promise<UserOperationStatus>;
63
+ /**
64
+ * Send user operation and wait for completion with detailed status
65
+ */
66
+ sendUserOperationAndWait(owner: string, request: UserOperationRequest | BatchUserOperationRequest, signFn: SignFunction, salt?: bigint, paymasterAddress?: string, pollingOptions?: PollingOptions): Promise<{
67
+ userOpHash: string;
68
+ status: UserOperationStatus;
69
+ }>;
70
+ }
@@ -0,0 +1,428 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GokiteAASDK = void 0;
7
+ const ethers_1 = require("ethers");
8
+ const types_1 = require("./types");
9
+ const config_1 = require("./config");
10
+ const utils_1 = require("./utils");
11
+ const dotenv_1 = __importDefault(require("dotenv"));
12
+ dotenv_1.default.config();
13
+ // Error classification helper
14
+ function classifyError(error, context) {
15
+ // Network/fetch errors
16
+ if (error.name === 'TypeError' || error.message?.includes('fetch')) {
17
+ return {
18
+ type: 'NETWORK_ERROR',
19
+ message: `Network error during ${context}: ${error.message}`,
20
+ details: error
21
+ };
22
+ }
23
+ // Bundler RPC errors
24
+ if (error.code) {
25
+ const errorType = context.includes('estimate') ? 'ESTIMATE_GAS_FAILED' : 'SEND_USEROP_FAILED';
26
+ let specificType = errorType;
27
+ // Common error codes mapping
28
+ if (error.code === -32602 || error.message?.includes('insufficient funds')) {
29
+ specificType = 'INSUFFICIENT_FUNDS';
30
+ }
31
+ else if (error.code === -32602 || error.message?.includes('signature')) {
32
+ specificType = 'INVALID_SIGNATURE';
33
+ }
34
+ else if (error.code < 0) {
35
+ specificType = 'BUNDLER_ERROR';
36
+ }
37
+ return {
38
+ type: specificType,
39
+ message: error.message || `${context} failed`,
40
+ code: error.code,
41
+ details: error
42
+ };
43
+ }
44
+ // Generic error
45
+ return {
46
+ type: 'UNKNOWN_ERROR',
47
+ message: error.message || `Unknown error during ${context}`,
48
+ details: error
49
+ };
50
+ }
51
+ class BundlerProvider {
52
+ constructor(bundlerUrl) {
53
+ this.bundlerUrl = bundlerUrl;
54
+ }
55
+ async estimateUserOperationGas(userOp, entryPoint) {
56
+ try {
57
+ const response = await fetch(this.bundlerUrl, {
58
+ method: 'POST',
59
+ headers: { 'Content-Type': 'application/json' },
60
+ body: JSON.stringify({
61
+ jsonrpc: '2.0',
62
+ id: Date.now(),
63
+ method: 'eth_estimateUserOperationGas',
64
+ params: [(0, utils_1.serializeUserOperation)(userOp), entryPoint]
65
+ })
66
+ });
67
+ const result = await response.json();
68
+ if (result.error) {
69
+ throw new types_1.AASDKError(classifyError(result.error, 'estimate gas'));
70
+ }
71
+ if (!result.result) {
72
+ throw new types_1.AASDKError({
73
+ type: 'ESTIMATE_GAS_FAILED',
74
+ message: 'No gas estimate result returned from bundler'
75
+ });
76
+ }
77
+ return {
78
+ callGasLimit: BigInt(result.result.callGasLimit),
79
+ verificationGasLimit: BigInt(result.result.verificationGasLimit),
80
+ preVerificationGas: BigInt(result.result.preVerificationGas),
81
+ maxFeePerGas: BigInt(result.result.maxFeePerGas || 1000000000n),
82
+ maxPriorityFeePerGas: BigInt(result.result.maxPriorityFeePerGas || 1000000000n), // 1 gwei
83
+ };
84
+ }
85
+ catch (error) {
86
+ if (error instanceof types_1.AASDKError)
87
+ throw error;
88
+ throw new types_1.AASDKError(classifyError(error, 'estimate gas'));
89
+ }
90
+ }
91
+ async sendUserOperation(userOp, entryPoint) {
92
+ try {
93
+ const serializedUserOp = (0, utils_1.serializeUserOperation)(userOp);
94
+ console.log('Sending UserOp to bundler:', JSON.stringify(serializedUserOp, null, 2));
95
+ const response = await fetch(this.bundlerUrl, {
96
+ method: 'POST',
97
+ headers: { 'Content-Type': 'application/json' },
98
+ body: JSON.stringify({
99
+ jsonrpc: '2.0',
100
+ id: Date.now(),
101
+ method: 'eth_sendUserOperation',
102
+ params: [serializedUserOp, entryPoint]
103
+ })
104
+ });
105
+ const result = await response.json();
106
+ if (result.error) {
107
+ throw new types_1.AASDKError(classifyError(result.error, 'send user operation'));
108
+ }
109
+ if (!result.result) {
110
+ throw new types_1.AASDKError({
111
+ type: 'SEND_USEROP_FAILED',
112
+ message: 'No user operation hash returned from bundler'
113
+ });
114
+ }
115
+ return result.result;
116
+ }
117
+ catch (error) {
118
+ if (error instanceof types_1.AASDKError)
119
+ throw error;
120
+ throw new types_1.AASDKError(classifyError(error, 'send user operation'));
121
+ }
122
+ }
123
+ async getUserOperationStatus(userOpHash) {
124
+ const response = await fetch(this.bundlerUrl, {
125
+ method: 'POST',
126
+ headers: { 'Content-Type': 'application/json' },
127
+ body: JSON.stringify({
128
+ jsonrpc: '2.0',
129
+ id: Date.now(),
130
+ method: 'eth_getUserOperationReceipt',
131
+ params: [userOpHash]
132
+ })
133
+ });
134
+ const result = await response.json();
135
+ // If error or no result, operation is still pending
136
+ if (result.error || !result.result) {
137
+ return { userOpHash, status: 'pending' };
138
+ }
139
+ const receipt = result.result;
140
+ // Determine status based on success field
141
+ let status;
142
+ if (receipt.success) {
143
+ status = 'success';
144
+ }
145
+ else {
146
+ status = 'reverted';
147
+ }
148
+ return {
149
+ userOpHash,
150
+ status,
151
+ transactionHash: receipt.receipt.transactionHash,
152
+ blockNumber: parseInt(receipt.receipt.blockNumber, 16),
153
+ gasUsed: receipt.receipt.gasUsed,
154
+ actualGasCost: receipt.actualGasCost,
155
+ reason: receipt.reason,
156
+ receipt
157
+ };
158
+ }
159
+ async getUserOperationByHash(userOpHash) {
160
+ const response = await fetch(this.bundlerUrl, {
161
+ method: 'POST',
162
+ headers: { 'Content-Type': 'application/json' },
163
+ body: JSON.stringify({
164
+ jsonrpc: '2.0',
165
+ id: Date.now(),
166
+ method: 'eth_getUserOperationByHash',
167
+ params: [userOpHash]
168
+ })
169
+ });
170
+ const result = await response.json();
171
+ return result.result || null;
172
+ }
173
+ }
174
+ /**
175
+ * Main Gokite AA SDK class
176
+ */
177
+ class GokiteAASDK {
178
+ constructor(network, rpcUrl, bundlerUrl) {
179
+ this.config = config_1.NETWORKS[network];
180
+ if (!this.config) {
181
+ throw new Error(`Unsupported network: ${network}`);
182
+ }
183
+ this.ethersProvider = new ethers_1.ethers.JsonRpcProvider(rpcUrl);
184
+ if (bundlerUrl) {
185
+ this.provider = new BundlerProvider(bundlerUrl);
186
+ }
187
+ else {
188
+ throw new Error('Bundler URL is required');
189
+ }
190
+ }
191
+ /**
192
+ * Calculate account address for a given owner and salt
193
+ */
194
+ getAccountAddress(owner, salt) {
195
+ const actualSalt = salt || (0, utils_1.generateSalt)();
196
+ return (0, utils_1.getAccountAddress)(this.config.accountFactory, this.config.accountImplementation, owner, actualSalt);
197
+ }
198
+ /**
199
+ * Get account nonce
200
+ */
201
+ async getAccountNonce(accountAddress) {
202
+ const entryPoint = new ethers_1.ethers.Contract(this.config.entryPoint, ['function getNonce(address,uint192) view returns (uint256)'], this.ethersProvider);
203
+ return await entryPoint.getNonce(accountAddress, 0);
204
+ }
205
+ /**
206
+ * Get user operation hash from EntryPoint contract
207
+ */
208
+ async getUserOpHash(userOp) {
209
+ const entryPoint = new ethers_1.ethers.Contract(this.config.entryPoint, ['function getUserOpHash((address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes)) view returns (bytes32)'], this.ethersProvider);
210
+ // Convert userOp to the format expected by the contract - ensure proper types
211
+ const packedUserOp = [
212
+ userOp.sender,
213
+ userOp.nonce,
214
+ userOp.initCode,
215
+ userOp.callData,
216
+ userOp.accountGasLimits,
217
+ userOp.preVerificationGas,
218
+ userOp.gasFees,
219
+ userOp.paymasterAndData,
220
+ '0x' // signature (empty for hash calculation)
221
+ ];
222
+ console.log('getUserOpHash packedUserOp:', packedUserOp);
223
+ const hash = await entryPoint.getUserOpHash(packedUserOp);
224
+ console.log('Raw hash from contract:', hash);
225
+ return hash;
226
+ }
227
+ /**
228
+ * Check if account is deployed
229
+ */
230
+ async isAccountDeloyed(accountAddress) {
231
+ const code = await this.ethersProvider.getCode(accountAddress);
232
+ return code !== '0x';
233
+ }
234
+ /**
235
+ * Build init code for account creation
236
+ */
237
+ buildInitCode(owner, salt) {
238
+ const initCallData = (0, utils_1.encodeFunctionCall)(['function createAccount(address,uint256) returns (address)'], 'createAccount', [owner, salt]);
239
+ return this.config.accountFactory + initCallData.slice(2);
240
+ }
241
+ /**
242
+ * Build call data for single transaction
243
+ */
244
+ buildCallData(request) {
245
+ return (0, utils_1.encodeFunctionCall)(['function execute(address,uint256,bytes)'], 'execute', [request.target, request.value || 0n, request.callData]);
246
+ }
247
+ /**
248
+ * Build call data for batch transactions
249
+ */
250
+ buildBatchCallData(request) {
251
+ const values = request.values || new Array(request.targets.length).fill(0n);
252
+ return (0, utils_1.encodeFunctionCall)(['function executeBatch(address[],uint256[],bytes[])'], 'executeBatch', [request.targets, values, request.callDatas]);
253
+ }
254
+ /**
255
+ * Create user operation
256
+ */
257
+ async createUserOperation(owner, request, salt, paymasterAddress) {
258
+ const actualSalt = salt || (0, utils_1.generateSalt)();
259
+ const accountAddress = this.getAccountAddress(owner, actualSalt);
260
+ const isDeployed = await this.isAccountDeloyed(accountAddress);
261
+ const callData = 'targets' in request
262
+ ? this.buildBatchCallData(request)
263
+ : this.buildCallData(request);
264
+ // Gas settings (matching Go implementation)
265
+ const callGasLimit = BigInt(300000);
266
+ const verificationGasLimit = BigInt(300000);
267
+ const preVerificationGas = BigInt(1000000);
268
+ const maxFeePerGas = BigInt(10000000); // 0.001 gwei
269
+ const maxPriorityFeePerGas = BigInt(1); // 1 wei
270
+ // Pack gas limits and fees (note: verificationGasLimit first, callGasLimit second)
271
+ const accountGasLimits = (0, utils_1.packAccountGasLimits)(verificationGasLimit, callGasLimit);
272
+ const gasFees = (0, utils_1.packAccountGasLimits)(maxPriorityFeePerGas, maxFeePerGas);
273
+ if (!paymasterAddress) {
274
+ paymasterAddress = this.config.paymaster;
275
+ }
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';
280
+ return {
281
+ sender: accountAddress,
282
+ nonce: await this.getAccountNonce(accountAddress),
283
+ initCode: isDeployed ? '0x' : this.buildInitCode(owner, actualSalt),
284
+ callData,
285
+ accountGasLimits,
286
+ preVerificationGas,
287
+ gasFees,
288
+ paymasterAndData,
289
+ signature: '0x', // Will be set later
290
+ };
291
+ }
292
+ /**
293
+ * Estimate gas for user operation
294
+ */
295
+ async estimateGas(userOp) {
296
+ // Create a version with dummy signature for estimation
297
+ const userOpForEstimation = (0, utils_1.createUserOpForEstimation)(userOp);
298
+ return await this.provider.estimateUserOperationGas(userOpForEstimation, this.config.entryPoint);
299
+ }
300
+ /**
301
+ * Sign and send user operation
302
+ */
303
+ async sendUserOperation(owner, request, signFn, salt, paymasterAddress) {
304
+ // Create user operation
305
+ const userOp = await this.createUserOperation(owner, request, salt, paymasterAddress);
306
+ // Add dummy signature for gas estimation
307
+ const userOpWithDummy = (0, utils_1.createUserOpForEstimation)(userOp);
308
+ // Estimate gas using bundler
309
+ const gasEstimate = await this.provider.estimateUserOperationGas(userOpWithDummy, this.config.entryPoint);
310
+ console.log('gasEstimate:', gasEstimate);
311
+ // Update gas fields in packed format (verificationGasLimit first, callGasLimit second)
312
+ userOp.accountGasLimits = (0, utils_1.packAccountGasLimits)(gasEstimate.verificationGasLimit, gasEstimate.callGasLimit);
313
+ userOp.preVerificationGas = gasEstimate.preVerificationGas;
314
+ const userOpHash = await this.getUserOpHash(userOp);
315
+ // Sign user operation
316
+ const signature = await signFn(userOpHash);
317
+ userOp.signature = signature;
318
+ // // Send user operation directly to EntryPoint contract (bypassing bundler)
319
+ // return await this.sendUserOperationDirectly(owner, userOp as UserOperation);
320
+ return await this.provider.sendUserOperation(userOp, this.config.entryPoint);
321
+ }
322
+ /**
323
+ * Send user operation directly to EntryPoint contract (bypassing bundler)
324
+ * Note: This requires a signer to pay for gas. For now, we'll try with the read-only provider.
325
+ */
326
+ async sendUserOperationDirectly(owner, userOp) {
327
+ // TODO: We need a signer here to pay for gas
328
+ // For now, let's see what error we get with the read-only provider
329
+ const entryPoint = new ethers_1.ethers.Contract(this.config.entryPoint, [
330
+ 'function handleOps((address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes)[] calldata ops, address payable beneficiary) external'
331
+ ], this.ethersProvider);
332
+ // Convert userOp to the format expected by the contract
333
+ const packedUserOp = [
334
+ userOp.sender,
335
+ userOp.nonce,
336
+ userOp.initCode,
337
+ userOp.callData,
338
+ userOp.accountGasLimits,
339
+ userOp.preVerificationGas,
340
+ userOp.gasFees,
341
+ userOp.paymasterAndData,
342
+ userOp.signature
343
+ ];
344
+ // Create operations array (only one operation)
345
+ const ops = [packedUserOp];
346
+ // Set beneficiary (use owner address)
347
+ const beneficiary = owner;
348
+ console.log('Calling EntryPoint.handleOps directly...');
349
+ console.log('ops:', ops);
350
+ console.log('beneficiary:', beneficiary);
351
+ const signer_pk = process.env.PRIVATE_KEY;
352
+ const signer = new ethers_1.ethers.Wallet(signer_pk, this.ethersProvider);
353
+ console.log('signer:', signer.address);
354
+ try {
355
+ // Call handleOps on EntryPoint contract
356
+ const tx = await entryPoint.connect(signer).handleOps(ops, beneficiary, {
357
+ gasLimit: 1000000,
358
+ });
359
+ console.log('Transaction sent:', tx.hash);
360
+ // Wait for transaction confirmation
361
+ const receipt = await tx.wait();
362
+ console.log('Transaction confirmed:', receipt.hash);
363
+ return tx.hash;
364
+ }
365
+ catch (error) {
366
+ console.error('EntryPoint.handleOps failed:', error);
367
+ throw error;
368
+ }
369
+ }
370
+ /**
371
+ * Get user operation status
372
+ */
373
+ async getUserOperationStatus(userOpHash) {
374
+ return await this.provider.getUserOperationStatus(userOpHash);
375
+ }
376
+ /**
377
+ * Enhanced polling for user operation status with detailed result parsing
378
+ */
379
+ async pollUserOperationStatus(userOpHash, options = {}) {
380
+ const { interval = 2000, timeout = 60000, maxRetries = 30 } = options;
381
+ const startTime = Date.now();
382
+ let retryCount = 0;
383
+ while (Date.now() - startTime < timeout && retryCount < maxRetries) {
384
+ try {
385
+ const status = await this.getUserOperationStatus(userOpHash);
386
+ // Check if operation is completed (either success or failed)
387
+ if (status.status === 'success' || status.status === 'reverted' || status.status === 'failed') {
388
+ console.log(`UserOp completed:`, {
389
+ status: status.status,
390
+ transactionHash: status.transactionHash,
391
+ gasUsed: status.gasUsed,
392
+ actualGasCost: status.actualGasCost,
393
+ reason: status.reason
394
+ });
395
+ return status;
396
+ }
397
+ retryCount++;
398
+ if (retryCount < maxRetries) {
399
+ await new Promise(resolve => setTimeout(resolve, interval));
400
+ }
401
+ }
402
+ catch (error) {
403
+ console.error(`polling error (attempt ${retryCount + 1}):`, error);
404
+ retryCount++;
405
+ if (retryCount < maxRetries) {
406
+ await new Promise(resolve => setTimeout(resolve, interval));
407
+ }
408
+ }
409
+ }
410
+ throw new Error(`UserOp polling timeout: ${userOpHash} (attempt ${retryCount})`);
411
+ }
412
+ /**
413
+ * Send user operation and wait for completion with detailed status
414
+ */
415
+ async sendUserOperationAndWait(owner, request, signFn, salt, paymasterAddress, pollingOptions) {
416
+ console.log('Sending UserOp and waiting for completion...');
417
+ // Step 1: Send user operation
418
+ const userOpHash = await this.sendUserOperation(owner, request, signFn, salt, paymasterAddress);
419
+ console.log(`UserOp sent: ${userOpHash}`);
420
+ // Step 2: Poll for status until completion
421
+ const status = await this.pollUserOperationStatus(userOpHash, pollingOptions);
422
+ return {
423
+ userOpHash,
424
+ status
425
+ };
426
+ }
427
+ }
428
+ exports.GokiteAASDK = GokiteAASDK;
@@ -0,0 +1,4 @@
1
+ export { GokiteAASDK } from './gokite-aa-sdk';
2
+ export * from './types';
3
+ export * from './config';
4
+ export * from './utils';
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.GokiteAASDK = void 0;
18
+ // Gokite AA SDK - Entry point
19
+ var gokite_aa_sdk_1 = require("./gokite-aa-sdk");
20
+ Object.defineProperty(exports, "GokiteAASDK", { enumerable: true, get: function () { return gokite_aa_sdk_1.GokiteAASDK; } });
21
+ __exportStar(require("./types"), exports);
22
+ __exportStar(require("./config"), exports);
23
+ __exportStar(require("./utils"), exports);
@@ -0,0 +1,95 @@
1
+ export interface UserOperation {
2
+ sender: string;
3
+ nonce: bigint;
4
+ initCode: string;
5
+ callData: string;
6
+ accountGasLimits: string;
7
+ preVerificationGas: bigint;
8
+ gasFees: string;
9
+ paymasterAndData: string;
10
+ signature: string;
11
+ }
12
+ export interface UserOperationGasEstimate {
13
+ callGasLimit: bigint;
14
+ verificationGasLimit: bigint;
15
+ preVerificationGas: bigint;
16
+ maxFeePerGas: bigint;
17
+ maxPriorityFeePerGas: bigint;
18
+ }
19
+ export interface UserOperationRequest {
20
+ target: string;
21
+ value?: bigint;
22
+ callData: string;
23
+ }
24
+ export interface BatchUserOperationRequest {
25
+ targets: string[];
26
+ values?: bigint[];
27
+ callDatas: string[];
28
+ }
29
+ export interface UserOperationStatus {
30
+ userOpHash: string;
31
+ status: 'pending' | 'included' | 'failed' | 'success' | 'reverted';
32
+ transactionHash?: string;
33
+ blockNumber?: number;
34
+ gasUsed?: string;
35
+ actualGasCost?: string;
36
+ reason?: string;
37
+ receipt?: UserOperationReceipt;
38
+ }
39
+ export interface PollingOptions {
40
+ interval?: number;
41
+ timeout?: number;
42
+ maxRetries?: number;
43
+ }
44
+ export interface AAError {
45
+ type: 'ESTIMATE_GAS_FAILED' | 'SEND_USEROP_FAILED' | 'INSUFFICIENT_FUNDS' | 'INVALID_SIGNATURE' | 'BUNDLER_ERROR' | 'NETWORK_ERROR' | 'UNKNOWN_ERROR';
46
+ message: string;
47
+ code?: number;
48
+ details?: any;
49
+ }
50
+ export declare class AASDKError extends Error {
51
+ readonly type: AAError['type'];
52
+ readonly code?: number;
53
+ readonly details?: any;
54
+ constructor(error: AAError);
55
+ }
56
+ export interface SignFunction {
57
+ (userOpHash: string): Promise<string>;
58
+ }
59
+ export interface AAProvider {
60
+ estimateUserOperationGas(userOp: Partial<UserOperation>, entryPoint: string): Promise<UserOperationGasEstimate>;
61
+ sendUserOperation(userOp: UserOperation, entryPoint: string): Promise<string>;
62
+ getUserOperationStatus(userOpHash: string): Promise<UserOperationStatus>;
63
+ getUserOperationByHash(userOpHash: string): Promise<UserOperation | null>;
64
+ }
65
+ export interface BundlerResponse<T = any> {
66
+ jsonrpc: string;
67
+ id: number;
68
+ result?: T;
69
+ error?: {
70
+ code: number;
71
+ message: string;
72
+ };
73
+ }
74
+ export interface GasEstimateResult {
75
+ callGasLimit: string;
76
+ verificationGasLimit: string;
77
+ preVerificationGas: string;
78
+ maxFeePerGas?: string;
79
+ maxPriorityFeePerGas?: string;
80
+ }
81
+ export interface UserOperationReceipt {
82
+ userOpHash: string;
83
+ sender: string;
84
+ nonce: string;
85
+ actualGasCost: string;
86
+ actualGasUsed: string;
87
+ success: boolean;
88
+ receipt: {
89
+ transactionHash: string;
90
+ blockNumber: string;
91
+ gasUsed: string;
92
+ logs: any[];
93
+ };
94
+ reason?: string;
95
+ }
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AASDKError = void 0;
4
+ class AASDKError extends Error {
5
+ constructor(error) {
6
+ super(error.message);
7
+ this.name = 'AASDKError';
8
+ this.type = error.type;
9
+ this.code = error.code;
10
+ this.details = error.details;
11
+ }
12
+ }
13
+ exports.AASDKError = AASDKError;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Calculate the counterfactual address of a GokiteAccount
3
+ * This matches the logic in GokiteAccountFactory.getAddress()
4
+ */
5
+ export declare function getAccountAddress(factoryAddress: string, implementationAddress: string, owner: string, salt: bigint): string;
6
+ /**
7
+ * Encode function call data
8
+ */
9
+ export declare function encodeFunctionCall(abi: string[], functionName: string, params: any[]): string;
10
+ /**
11
+ * Pack user operation for hashing
12
+ */
13
+ export declare function packUserOperation(userOp: any): string;
14
+ /**
15
+ * Pack account gas limits into 32 bytes
16
+ * @param verificationGasLimit Verification gas limit (16 bytes, first half)
17
+ * @param callGasLimit Call gas limit (16 bytes, second half)
18
+ * @returns 32 bytes packed data as hex string
19
+ */
20
+ export declare function packAccountGasLimits(verificationGasLimit: bigint, callGasLimit: bigint): string;
21
+ /**
22
+ * Pack paymaster and data
23
+ * @param paymasterAddress Paymaster contract address (20 bytes)
24
+ * @param paymasterVerificationGasLimit Paymaster verification gas limit (16 bytes)
25
+ * @param postOpGasLimit Post operation gas limit (16 bytes)
26
+ * @param paymasterData Additional paymaster data (variable length)
27
+ * @returns Packed paymaster and data as hex string
28
+ */
29
+ export declare function packPaymasterAndData(paymasterAddress: string, paymasterVerificationGasLimit: bigint, postOpGasLimit: bigint, paymasterData?: string): string;
30
+ /**
31
+ * Get user operation hash
32
+ */
33
+ export declare function getUserOperationHash(userOp: any, entryPointAddress: string, chainId: number): string;
34
+ /**
35
+ * Convert bigint values to hex strings for JSON serialization
36
+ * Also unpacks PackedUserOperation format to legacy format for bundler compatibility
37
+ */
38
+ export declare function serializeUserOperation(userOp: any): any;
39
+ export declare function generateSalt(): bigint;
40
+ /**
41
+ * Generate a dummy signature for gas estimation
42
+ * The signature needs to be the correct length but doesn't need to be valid
43
+ * Using a format that won't cause ECDSA.recover to revert
44
+ */
45
+ export declare function generateDummySignature(): string;
46
+ /**
47
+ * Create a user operation with dummy signature for gas estimation
48
+ */
49
+ export declare function createUserOpForEstimation(userOp: any): any;