@brninpay/sdk 0.1.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.
Files changed (95) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/LICENSE +203 -0
  3. package/README.md +5 -0
  4. package/dist/actor-client.d.ts +13 -0
  5. package/dist/actor-client.d.ts.map +1 -0
  6. package/dist/actor-client.js +44 -0
  7. package/dist/actor-client.js.map +1 -0
  8. package/dist/bundler/client.d.ts +20 -0
  9. package/dist/bundler/client.d.ts.map +1 -0
  10. package/dist/bundler/client.js +228 -0
  11. package/dist/bundler/client.js.map +1 -0
  12. package/dist/bundler/providers/alchemy.d.ts +3 -0
  13. package/dist/bundler/providers/alchemy.d.ts.map +1 -0
  14. package/dist/bundler/providers/alchemy.js +15 -0
  15. package/dist/bundler/providers/alchemy.js.map +1 -0
  16. package/dist/bundler/providers/pimlico.d.ts +3 -0
  17. package/dist/bundler/providers/pimlico.d.ts.map +1 -0
  18. package/dist/bundler/providers/pimlico.js +12 -0
  19. package/dist/bundler/providers/pimlico.js.map +1 -0
  20. package/dist/client.d.ts +24 -0
  21. package/dist/client.d.ts.map +1 -0
  22. package/dist/client.js +352 -0
  23. package/dist/client.js.map +1 -0
  24. package/dist/conversion.d.ts +3 -0
  25. package/dist/conversion.d.ts.map +1 -0
  26. package/dist/conversion.js +27 -0
  27. package/dist/conversion.js.map +1 -0
  28. package/dist/erc4337/builder.d.ts +15 -0
  29. package/dist/erc4337/builder.d.ts.map +1 -0
  30. package/dist/erc4337/builder.js +144 -0
  31. package/dist/erc4337/builder.js.map +1 -0
  32. package/dist/erc4337/providers/kernel.d.ts +23 -0
  33. package/dist/erc4337/providers/kernel.d.ts.map +1 -0
  34. package/dist/erc4337/providers/kernel.js +120 -0
  35. package/dist/erc4337/providers/kernel.js.map +1 -0
  36. package/dist/erc4337/providers/safe.d.ts +23 -0
  37. package/dist/erc4337/providers/safe.d.ts.map +1 -0
  38. package/dist/erc4337/providers/safe.js +117 -0
  39. package/dist/erc4337/providers/safe.js.map +1 -0
  40. package/dist/erc4337/providers/types.d.ts +88 -0
  41. package/dist/erc4337/providers/types.d.ts.map +1 -0
  42. package/dist/erc4337/providers/types.js +35 -0
  43. package/dist/erc4337/providers/types.js.map +1 -0
  44. package/dist/erc4337/smart-wallet.d.ts +16 -0
  45. package/dist/erc4337/smart-wallet.d.ts.map +1 -0
  46. package/dist/erc4337/smart-wallet.js +86 -0
  47. package/dist/erc4337/smart-wallet.js.map +1 -0
  48. package/dist/index.d.ts +16 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +15 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/modules/payment-intents.d.ts +99 -0
  53. package/dist/modules/payment-intents.d.ts.map +1 -0
  54. package/dist/modules/payment-intents.js +118 -0
  55. package/dist/modules/payment-intents.js.map +1 -0
  56. package/dist/modules/policies.d.ts +87 -0
  57. package/dist/modules/policies.d.ts.map +1 -0
  58. package/dist/modules/policies.js +61 -0
  59. package/dist/modules/policies.js.map +1 -0
  60. package/dist/paymaster/client.d.ts +11 -0
  61. package/dist/paymaster/client.d.ts.map +1 -0
  62. package/dist/paymaster/client.js +119 -0
  63. package/dist/paymaster/client.js.map +1 -0
  64. package/dist/runtimee.d.ts +4 -0
  65. package/dist/runtimee.d.ts.map +1 -0
  66. package/dist/runtimee.js +4 -0
  67. package/dist/runtimee.js.map +1 -0
  68. package/dist/types.d.ts +389 -0
  69. package/dist/types.d.ts.map +1 -0
  70. package/dist/types.js +2 -0
  71. package/dist/types.js.map +1 -0
  72. package/package.json +29 -0
  73. package/src/actor-client.ts +57 -0
  74. package/src/bundler/client.ts +306 -0
  75. package/src/bundler/providers/alchemy.ts +21 -0
  76. package/src/bundler/providers/pimlico.ts +17 -0
  77. package/src/client.ts +472 -0
  78. package/src/conversion.ts +25 -0
  79. package/src/erc4337/builder.ts +181 -0
  80. package/src/erc4337/providers/kernel.ts +136 -0
  81. package/src/erc4337/providers/safe.ts +133 -0
  82. package/src/erc4337/providers/types.ts +73 -0
  83. package/src/erc4337/smart-wallet.ts +115 -0
  84. package/src/index.ts +60 -0
  85. package/src/modules/payment-intents.ts +156 -0
  86. package/src/modules/policies.ts +79 -0
  87. package/src/paymaster/client.ts +155 -0
  88. package/src/runtimee.ts +3 -0
  89. package/src/types.ts +469 -0
  90. package/test/architecture/architecture-invariants.test.ts +61 -0
  91. package/test/client.test.ts +180 -0
  92. package/test/conversion.test.ts +42 -0
  93. package/test/runtimee.test.ts +30 -0
  94. package/tsconfig.json +9 -0
  95. package/vitest.config.ts +8 -0
@@ -0,0 +1,79 @@
1
+ import { deserializeBigInts, parsePolicyDefinition, ValidationError } from '@brninpay/core'
2
+ import type {
3
+ ClientTransport,
4
+ CreatePolicyParams,
5
+ ListPoliciesParams,
6
+ PaginatedResult,
7
+ UpdatePolicyParams,
8
+ } from '../types.js'
9
+
10
+ export class PolicyClient {
11
+ constructor(private readonly transport: ClientTransport) {}
12
+
13
+ async createPolicy(params: CreatePolicyParams) {
14
+ const response = await this.transport.request<unknown>({
15
+ path: '/v1/policies',
16
+ method: 'POST',
17
+ body: params,
18
+ })
19
+
20
+ return parsePolicyDefinition(deserializeBigInts(response))
21
+ }
22
+
23
+ async getPolicy(id: string) {
24
+ if (!id.trim()) {
25
+ throw new ValidationError('getPolicy requires a policy id')
26
+ }
27
+
28
+ const response = await this.transport.request<unknown>({
29
+ path: `/v1/policies/${encodeURIComponent(id)}`,
30
+ method: 'GET',
31
+ })
32
+
33
+ return parsePolicyDefinition(deserializeBigInts(response))
34
+ }
35
+
36
+ async listPolicies(params: ListPoliciesParams = {}): Promise<PaginatedResult<ReturnType<typeof parsePolicyDefinition>>> {
37
+ const response = await this.transport.request<{
38
+ items: unknown[]
39
+ nextCursor?: string | null
40
+ }>({
41
+ path: '/v1/policies',
42
+ method: 'GET',
43
+ query: {
44
+ cursor: params.cursor,
45
+ limit: params.limit,
46
+ workspaceId: params.workspaceId,
47
+ actorId: params.actorId,
48
+ enabled: params.enabled,
49
+ kind: params.kind,
50
+ },
51
+ })
52
+
53
+ return {
54
+ items: response.items.map((item) => parsePolicyDefinition(deserializeBigInts(item))),
55
+ nextCursor: response.nextCursor ?? null,
56
+ }
57
+ }
58
+
59
+ async updatePolicy(params: UpdatePolicyParams) {
60
+ const response = await this.transport.request<unknown>({
61
+ path: `/v1/policies/${encodeURIComponent(params.id)}`,
62
+ method: 'PATCH',
63
+ body: params.patch,
64
+ })
65
+
66
+ return parsePolicyDefinition(deserializeBigInts(response))
67
+ }
68
+
69
+ async deletePolicy(id: string): Promise<{ deleted: true; id: string }> {
70
+ if (!id.trim()) {
71
+ throw new ValidationError('deletePolicy requires a policy id')
72
+ }
73
+
74
+ return this.transport.request<{ deleted: true; id: string }>({
75
+ path: `/v1/policies/${encodeURIComponent(id)}`,
76
+ method: 'DELETE',
77
+ })
78
+ }
79
+ }
@@ -0,0 +1,155 @@
1
+ import { AuthorizationError, ValidationError } from '@brninpay/core'
2
+ import type {
3
+ PaymasterClientConfig,
4
+ SdkLogger,
5
+ SponsorshipContext,
6
+ SponsorshipData,
7
+ UserOperation,
8
+ } from '../types.js'
9
+
10
+ const defaultLogger: SdkLogger = {
11
+ debug: () => undefined,
12
+ info: () => undefined,
13
+ warn: () => undefined,
14
+ error: () => undefined,
15
+ }
16
+
17
+ function serializeUserOperation(userOperation: UserOperation): Record<string, string> {
18
+ if (userOperation.version === 'v0.6') {
19
+ return {
20
+ version: userOperation.version,
21
+ sender: userOperation.sender,
22
+ nonce: userOperation.nonce.toString(),
23
+ initCode: userOperation.initCode,
24
+ callData: userOperation.callData,
25
+ callGasLimit: userOperation.callGasLimit.toString(),
26
+ verificationGasLimit: userOperation.verificationGasLimit.toString(),
27
+ preVerificationGas: userOperation.preVerificationGas.toString(),
28
+ maxFeePerGas: userOperation.maxFeePerGas.toString(),
29
+ maxPriorityFeePerGas: userOperation.maxPriorityFeePerGas.toString(),
30
+ paymasterAndData: userOperation.paymasterAndData,
31
+ signature: userOperation.signature,
32
+ }
33
+ }
34
+
35
+ return {
36
+ version: userOperation.version,
37
+ sender: userOperation.sender,
38
+ nonce: userOperation.nonce.toString(),
39
+ factory: userOperation.factory,
40
+ factoryData: userOperation.factoryData,
41
+ callData: userOperation.callData,
42
+ callGasLimit: userOperation.callGasLimit.toString(),
43
+ verificationGasLimit: userOperation.verificationGasLimit.toString(),
44
+ preVerificationGas: userOperation.preVerificationGas.toString(),
45
+ maxFeePerGas: userOperation.maxFeePerGas.toString(),
46
+ maxPriorityFeePerGas: userOperation.maxPriorityFeePerGas.toString(),
47
+ paymaster: userOperation.paymaster,
48
+ paymasterVerificationGasLimit: userOperation.paymasterVerificationGasLimit.toString(),
49
+ paymasterPostOpGasLimit: userOperation.paymasterPostOpGasLimit.toString(),
50
+ paymasterData: userOperation.paymasterData,
51
+ signature: userOperation.signature,
52
+ }
53
+ }
54
+
55
+ export class PaymasterClient {
56
+ private readonly timeoutMs: number
57
+ private readonly maxRetries: number
58
+ private readonly logger: SdkLogger
59
+ private readonly fetchImplementation: typeof fetch
60
+
61
+ constructor(private readonly config: PaymasterClientConfig) {
62
+ this.timeoutMs = config.timeoutMs ?? 15_000
63
+ this.maxRetries = config.maxRetries ?? 1
64
+ this.logger = config.logger ?? defaultLogger
65
+ this.fetchImplementation = config.fetchImplementation ?? fetch.bind(globalThis)
66
+ }
67
+
68
+ async requestSponsorship(
69
+ userOperation: UserOperation,
70
+ context?: SponsorshipContext
71
+ ): Promise<SponsorshipData> {
72
+ let attempt = 0
73
+ while (true) {
74
+ attempt += 1
75
+ const controller = new AbortController()
76
+ const timeoutId = setTimeout(() => controller.abort('Paymaster request timed out'), this.timeoutMs)
77
+
78
+ try {
79
+ const response = await this.fetchImplementation(this.config.url, {
80
+ method: 'POST',
81
+ headers: {
82
+ 'Content-Type': 'application/json',
83
+ ...(this.config.apiKey ? { Authorization: `Bearer ${this.config.apiKey}` } : {}),
84
+ ...(this.config.headers ?? {}),
85
+ },
86
+ body: JSON.stringify({
87
+ userOperation: serializeUserOperation(userOperation),
88
+ context,
89
+ }),
90
+ signal: controller.signal,
91
+ })
92
+
93
+ const payload = (await response.json().catch(() => null)) as
94
+ | {
95
+ version?: 'v0.6' | 'v0.7'
96
+ paymasterAndData?: `0x${string}`
97
+ paymaster?: `0x${string}`
98
+ paymasterData?: `0x${string}`
99
+ paymasterVerificationGasLimit?: string
100
+ paymasterPostOpGasLimit?: string
101
+ code?: string
102
+ message?: string
103
+ }
104
+ | null
105
+
106
+ if (!response.ok) {
107
+ throw new AuthorizationError(
108
+ payload?.code ?? 'paymaster_rejected',
109
+ payload?.message ?? `Paymaster rejected sponsorship with status ${response.status}`,
110
+ payload
111
+ )
112
+ }
113
+
114
+ if (userOperation.version === 'v0.6') {
115
+ if (!payload?.paymasterAndData) {
116
+ throw new ValidationError('Paymaster response missing paymasterAndData for v0.6 user operation')
117
+ }
118
+
119
+ return {
120
+ version: 'v0.6',
121
+ paymasterAndData: payload.paymasterAndData,
122
+ }
123
+ }
124
+
125
+ if (
126
+ !payload?.paymaster ||
127
+ !payload.paymasterData ||
128
+ !payload.paymasterVerificationGasLimit ||
129
+ !payload.paymasterPostOpGasLimit
130
+ ) {
131
+ throw new ValidationError('Paymaster response missing v0.7 sponsorship fields')
132
+ }
133
+
134
+ return {
135
+ version: 'v0.7',
136
+ paymaster: payload.paymaster,
137
+ paymasterData: payload.paymasterData,
138
+ paymasterVerificationGasLimit: BigInt(payload.paymasterVerificationGasLimit),
139
+ paymasterPostOpGasLimit: BigInt(payload.paymasterPostOpGasLimit),
140
+ }
141
+ } catch (error) {
142
+ if (attempt > this.maxRetries + 1) {
143
+ throw error
144
+ }
145
+
146
+ this.logger.warn('Retrying paymaster sponsorship request', {
147
+ attempt,
148
+ error: error instanceof Error ? error.message : String(error),
149
+ })
150
+ } finally {
151
+ clearTimeout(timeoutId)
152
+ }
153
+ }
154
+ }
155
+ }
@@ -0,0 +1,3 @@
1
+ import { BrninpayClient } from './client.js'
2
+
3
+ export class Runtimee extends BrninpayClient {}
package/src/types.ts ADDED
@@ -0,0 +1,469 @@
1
+ export type {
2
+ Address,
3
+ AggregatedPolicyDecision,
4
+ EntryPointVersion,
5
+ GasEstimate,
6
+ Hex,
7
+ PaymentIntent,
8
+ PaymentIntentStatus,
9
+ PolicyDefinition,
10
+ PolicyEvaluationResult,
11
+ PolicyReason,
12
+ SmartWallet as CoreSmartWallet,
13
+ UserOperation,
14
+ UserOperationCall,
15
+ } from '@brninpay/core'
16
+
17
+ import type {
18
+ Address,
19
+ AggregatedPolicyDecision,
20
+ EntryPointVersion,
21
+ GasEstimate,
22
+ Hex,
23
+ PaymentIntent,
24
+ PaymentIntentStatus,
25
+ PolicyDefinition,
26
+ PolicyEvaluationResult,
27
+ PolicyReason,
28
+ SmartWallet as CoreSmartWallet,
29
+ UserOperation,
30
+ UserOperationCall,
31
+ } from '@brninpay/core'
32
+
33
+ export interface CreateActorParams {
34
+ name: string
35
+ budget: {
36
+ amount: string
37
+ currency: 'USDC'
38
+ period: 'monthly' | 'total'
39
+ }
40
+ policies: {
41
+ type: string
42
+ version?: string
43
+ config?: Record<string, unknown>
44
+ }[]
45
+ }
46
+
47
+ export interface PayParams {
48
+ target: string
49
+ amount: string
50
+ purpose: {
51
+ type: string
52
+ id: string
53
+ description?: string
54
+ }
55
+ idempotencyKey?: string
56
+ }
57
+
58
+ export interface PreviewPayParams {
59
+ target: string
60
+ amount: string
61
+ purpose: {
62
+ type: string
63
+ id: string
64
+ description?: string
65
+ }
66
+ }
67
+
68
+ export interface ActorStatus {
69
+ budget: {
70
+ total: string
71
+ used: string
72
+ remaining: string
73
+ period: string
74
+ currency: string
75
+ }
76
+ txCount: number
77
+ }
78
+
79
+ export interface ActorSummary {
80
+ id: string
81
+ name: string
82
+ status: 'active' | 'frozen' | 'depleted'
83
+ createdAt: string
84
+ }
85
+
86
+ export interface ExecutionReceipt {
87
+ executionId: string
88
+ status: 'pending' | 'confirmed' | 'failed'
89
+ txHash?: string
90
+ }
91
+
92
+ export interface SdkLogger {
93
+ debug(message: string, context?: Record<string, unknown>): void
94
+ info(message: string, context?: Record<string, unknown>): void
95
+ warn(message: string, context?: Record<string, unknown>): void
96
+ error(message: string, context?: Record<string, unknown>): void
97
+ }
98
+
99
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
100
+
101
+ export interface RequestContext {
102
+ url: URL
103
+ method: HttpMethod
104
+ headers: Headers
105
+ bodyText?: string
106
+ timeoutMs: number
107
+ attempt: number
108
+ }
109
+
110
+ export interface ResponseContext<T = unknown> {
111
+ request: RequestContext
112
+ response: Response
113
+ data: T
114
+ }
115
+
116
+ export type RequestInterceptor = (
117
+ context: RequestContext
118
+ ) => Promise<RequestContext | void> | RequestContext | void
119
+
120
+ export type ResponseInterceptor<T = unknown> = (
121
+ context: ResponseContext<T>
122
+ ) => Promise<ResponseContext<T> | void> | ResponseContext<T> | void
123
+
124
+ export interface RetryPolicy {
125
+ retries: number
126
+ baseDelayMs: number
127
+ maxDelayMs: number
128
+ retryMethods: readonly HttpMethod[]
129
+ }
130
+
131
+ export interface RuntimeeConfig {
132
+ apiKey: string
133
+ apiSecret?: string
134
+ baseUrl?: string
135
+ timeoutMs?: number
136
+ retryPolicy?: Partial<RetryPolicy>
137
+ headers?: Record<string, string>
138
+ logger?: SdkLogger
139
+ fetchImplementation?: typeof fetch
140
+ requestInterceptors?: RequestInterceptor[]
141
+ responseInterceptors?: ResponseInterceptor[]
142
+ }
143
+
144
+ export interface PaginationParams {
145
+ cursor?: string
146
+ limit?: number
147
+ }
148
+
149
+ export interface PaginatedResult<T> {
150
+ items: T[]
151
+ nextCursor: string | null
152
+ }
153
+
154
+ export interface PaymentIntentRecipientInput {
155
+ address: Address
156
+ chainId: number
157
+ ensName?: string | null
158
+ }
159
+
160
+ export interface CreatePaymentIntentParams {
161
+ workspaceId: string
162
+ actorId: string
163
+ amount: {
164
+ currency: 'USDC'
165
+ value: bigint | string | number
166
+ decimals?: number
167
+ }
168
+ recipient: PaymentIntentRecipientInput
169
+ description?: string
170
+ reference?: string
171
+ expiresAt?: string | null
172
+ metadata?: Record<string, unknown>
173
+ idempotencyKey?: string
174
+ }
175
+
176
+ export interface PaymentIntentPreviewParams {
177
+ workspaceId: string
178
+ actorId: string
179
+ amount: {
180
+ currency: 'USDC'
181
+ value: bigint | string | number
182
+ decimals?: number
183
+ }
184
+ recipient: PaymentIntentRecipientInput
185
+ metadata?: Record<string, unknown>
186
+ }
187
+
188
+ export interface PaymentIntentPreview {
189
+ decision: AggregatedPolicyDecision['decision']
190
+ policyResults: PolicyEvaluationResult[]
191
+ estimatedGas?: bigint
192
+ estimatedTotalCost?: bigint
193
+ }
194
+
195
+ export interface GetPaymentIntentOptions {
196
+ waitForTerminalState?: boolean
197
+ pollIntervalMs?: number
198
+ timeoutMs?: number
199
+ }
200
+
201
+ export interface ListPaymentIntentsParams extends PaginationParams {
202
+ workspaceId?: string
203
+ actorId?: string
204
+ status?: PaymentIntentStatus
205
+ }
206
+
207
+ export interface CancelPaymentIntentParams {
208
+ reason?: string
209
+ }
210
+
211
+ export interface CreatePolicyParams {
212
+ workspaceId: string
213
+ actorId?: string
214
+ policy: PolicyDefinition
215
+ }
216
+
217
+ export interface UpdatePolicyParams {
218
+ id: string
219
+ patch: Partial<Omit<PolicyDefinition, 'kind'>> & {
220
+ enabled?: boolean
221
+ }
222
+ }
223
+
224
+ export interface ListPoliciesParams extends PaginationParams {
225
+ workspaceId?: string
226
+ actorId?: string
227
+ enabled?: boolean
228
+ kind?: PolicyDefinition['kind']
229
+ }
230
+
231
+ export interface ClientRequestOptions {
232
+ path: string
233
+ method?: HttpMethod
234
+ query?: Record<string, string | number | boolean | null | undefined>
235
+ headers?: Record<string, string>
236
+ body?: unknown
237
+ timeoutMs?: number
238
+ signal?: AbortSignal
239
+ retryPolicy?: Partial<RetryPolicy>
240
+ }
241
+
242
+ export interface ClientTransport {
243
+ request<T>(options: ClientRequestOptions): Promise<T>
244
+ }
245
+
246
+ export interface JsonRpcSuccess<T> {
247
+ jsonrpc: '2.0'
248
+ id: number | string | null
249
+ result: T
250
+ }
251
+
252
+ export interface JsonRpcErrorShape {
253
+ code: number
254
+ message: string
255
+ data?: unknown
256
+ }
257
+
258
+ export interface JsonRpcFailure {
259
+ jsonrpc: '2.0'
260
+ id: number | string | null
261
+ error: JsonRpcErrorShape
262
+ }
263
+
264
+ export interface BundlerProviderConfig {
265
+ name: string
266
+ url: string
267
+ headers?: Record<string, string>
268
+ }
269
+
270
+ export interface BundlerClientConfig {
271
+ entryPointAddress: Address
272
+ entryPointVersion: EntryPointVersion
273
+ primary: BundlerProviderConfig
274
+ secondary?: BundlerProviderConfig
275
+ timeoutMs?: number
276
+ pollingIntervalMs?: number
277
+ maxRetries?: number
278
+ logger?: SdkLogger
279
+ fetchImplementation?: typeof fetch
280
+ }
281
+
282
+ export interface UserOperationReceipt {
283
+ userOpHash: Hex
284
+ entryPoint: Address
285
+ sender: Address
286
+ nonce: bigint
287
+ actualGasCost: bigint
288
+ actualGasUsed: bigint
289
+ success: boolean
290
+ receipt: {
291
+ transactionHash: Hex
292
+ blockNumber: bigint
293
+ blockHash: Hex
294
+ }
295
+ logs: readonly unknown[]
296
+ }
297
+
298
+ export interface UserOperationByHash {
299
+ blockHash: Hex
300
+ blockNumber: bigint
301
+ entryPoint: Address
302
+ transactionHash: Hex
303
+ userOperation: UserOperation
304
+ }
305
+
306
+ export interface SponsorshipContext {
307
+ workspaceId?: string
308
+ actorId?: string
309
+ policyIds?: string[]
310
+ metadata?: Record<string, unknown>
311
+ }
312
+
313
+ export type SponsorshipData =
314
+ | {
315
+ version: 'v0.6'
316
+ paymasterAndData: Hex
317
+ }
318
+ | {
319
+ version: 'v0.7'
320
+ paymaster: Address | Hex
321
+ paymasterData: Hex
322
+ paymasterVerificationGasLimit: bigint
323
+ paymasterPostOpGasLimit: bigint
324
+ }
325
+
326
+ export interface PaymasterClientConfig {
327
+ url: string
328
+ apiKey?: string
329
+ timeoutMs?: number
330
+ maxRetries?: number
331
+ headers?: Record<string, string>
332
+ logger?: SdkLogger
333
+ fetchImplementation?: typeof fetch
334
+ }
335
+
336
+ export interface PublicClientLike {
337
+ readContract<T = unknown>(parameters: {
338
+ address: Address
339
+ abi: readonly unknown[]
340
+ functionName: string
341
+ args?: readonly unknown[]
342
+ }): Promise<T>
343
+ getCode(parameters: { address: Address }): Promise<Hex | undefined>
344
+ estimateFeesPerGas?(): Promise<{
345
+ maxFeePerGas?: bigint
346
+ maxPriorityFeePerGas?: bigint
347
+ gasPrice?: bigint
348
+ }>
349
+ getGasPrice?(): Promise<bigint>
350
+ }
351
+
352
+ export interface SmartAccountOwner {
353
+ address: Address
354
+ signMessage(parameters: { message: string | { raw: Hex } }): Promise<Hex>
355
+ signTypedData?<T extends Record<string, unknown>>(parameters: T): Promise<Hex>
356
+ }
357
+
358
+ export interface SmartWalletProviderConfig {
359
+ publicClient: PublicClientLike
360
+ owner: SmartAccountOwner
361
+ entryPointAddress: Address
362
+ entryPointVersion: EntryPointVersion
363
+ factoryAddress: Address
364
+ chainId: number
365
+ saltNonce?: bigint
366
+ }
367
+
368
+ export interface PreparedUserOperationContext {
369
+ walletAddress: Address
370
+ walletDeployed: boolean
371
+ calls: readonly UserOperationCall[]
372
+ nonce?: bigint
373
+ sponsorship?: SponsorshipData
374
+ }
375
+
376
+ export interface SmartWalletAccountProvider {
377
+ readonly kind: CoreSmartWallet['provider']
378
+ readonly chainId: number
379
+ readonly owner: SmartAccountOwner
380
+ readonly entryPointAddress: Address
381
+ readonly entryPointVersion: EntryPointVersion
382
+ readonly factoryAddress: Address
383
+ readonly saltNonce: bigint
384
+ getCounterfactualAddress(): Promise<Address>
385
+ getFactoryArgs(): Promise<{ factory?: Address; factoryData?: Hex }>
386
+ encodeCalls(calls: readonly UserOperationCall[]): Promise<Hex>
387
+ getNonce(address: Address, key?: bigint): Promise<bigint>
388
+ getStubSignature(): Promise<Hex>
389
+ signUserOperation(userOperation: UserOperation): Promise<Hex>
390
+ isDeployed(address: Address): Promise<boolean>
391
+ }
392
+
393
+ export interface UserOperationBuilderConfig {
394
+ chainId: number
395
+ entryPointAddress: Address
396
+ entryPointVersion: EntryPointVersion
397
+ usdcAddress: Address
398
+ bundlerClient?: {
399
+ estimateUserOperationGas(userOperation: UserOperation): Promise<GasEstimate>
400
+ }
401
+ publicClient?: PublicClientLike
402
+ }
403
+
404
+ export interface SmartWalletConfig {
405
+ chainId: number
406
+ usdcAddress: Address
407
+ provider: SmartWalletAccountProvider
408
+ bundlerClient: {
409
+ sendUserOperation(userOperation: UserOperation): Promise<Hex>
410
+ getUserOperationReceipt(
411
+ hash: Hex,
412
+ options?: { pollingIntervalMs?: number; timeoutMs?: number }
413
+ ): Promise<UserOperationReceipt>
414
+ }
415
+ paymasterClient?: {
416
+ requestSponsorship(
417
+ userOperation: UserOperation,
418
+ context?: SponsorshipContext
419
+ ): Promise<SponsorshipData>
420
+ }
421
+ builder: {
422
+ buildUSDCTransfer(parameters: { recipient: Address; amount: bigint }): UserOperationCall
423
+ prepareUserOperation(
424
+ provider: SmartWalletAccountProvider,
425
+ context: PreparedUserOperationContext
426
+ ): Promise<UserOperation>
427
+ }
428
+ }
429
+
430
+ export interface BatchOperationOptions {
431
+ waitForReceipt?: boolean
432
+ pollingIntervalMs?: number
433
+ timeoutMs?: number
434
+ sponsorshipContext?: SponsorshipContext
435
+ }
436
+
437
+ export interface SmartWalletSendResult {
438
+ wallet: CoreSmartWallet
439
+ userOperation: UserOperation
440
+ userOperationHash: Hex
441
+ receipt?: UserOperationReceipt
442
+ }
443
+
444
+ export type SmartWalletInstance = CoreSmartWallet
445
+
446
+ export interface PimlicoBundlerProviderParams {
447
+ chainId: number
448
+ apiKey: string
449
+ url?: string
450
+ }
451
+
452
+ export interface AlchemyBundlerProviderParams {
453
+ apiKey: string
454
+ network?: string
455
+ url?: string
456
+ }
457
+
458
+ export interface ApiErrorPayload {
459
+ code?: string
460
+ message?: string
461
+ details?: unknown
462
+ statusCode?: number
463
+ error?: string
464
+ }
465
+
466
+ export interface PolicyDecisionExplanation {
467
+ decision: AggregatedPolicyDecision['decision']
468
+ reasons: PolicyReason[]
469
+ }