/
HttpRpcClient.ts
70 lines (62 loc) · 2.66 KB
/
HttpRpcClient.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { JsonRpcProvider } from '@ethersproject/providers'
import { ethers } from 'ethers'
import { resolveProperties } from 'ethers/lib/utils'
import Debug from 'debug'
import { deepHexlify, UserOperation } from '@account-abstraction/utils'
const debug = Debug('aa.rpc')
export class HttpRpcClient {
private readonly userOpJsonRpcProvider: JsonRpcProvider
initializing: Promise<void>
constructor (
readonly bundlerUrl: string,
readonly entryPointAddress: string,
readonly chainId: number
) {
this.userOpJsonRpcProvider = new ethers.providers.JsonRpcProvider(this.bundlerUrl, {
name: 'Connected bundler network',
chainId
})
this.initializing = this.validateChainId()
}
async validateChainId (): Promise<void> {
// validate chainId is in sync with expected chainid
const chain = await this.userOpJsonRpcProvider.send('eth_chainId', [])
const bundlerChain = parseInt(chain)
if (bundlerChain !== this.chainId) {
throw new Error(`bundler ${this.bundlerUrl} is on chainId ${bundlerChain}, but provider is on chainId ${this.chainId}`)
}
}
/**
* send a UserOperation to the bundler
* @param userOp1
* @return userOpHash the id of this operation, for getUserOperationTransaction
*/
async sendUserOpToBundler (userOp1: UserOperation): Promise<string> {
await this.initializing
const hexifiedUserOp = deepHexlify(await resolveProperties(userOp1))
const jsonRequestData: [UserOperation, string] = [hexifiedUserOp, this.entryPointAddress]
await this.printUserOperation('eth_sendUserOperation', jsonRequestData)
return await this.userOpJsonRpcProvider
.send('eth_sendUserOperation', [hexifiedUserOp, this.entryPointAddress])
}
/**
* estimate gas requirements for UserOperation
* @param userOp1
* @returns latest gas suggestions made by the bundler.
*/
async estimateUserOpGas (userOp1: Partial<UserOperation>): Promise<{callGasLimit: number, preVerificationGas: number, verificationGasLimit: number}> {
await this.initializing
const hexifiedUserOp = deepHexlify(userOp1)
const jsonRequestData: [UserOperation, string] = [hexifiedUserOp, this.entryPointAddress]
await this.printUserOperation('eth_estimateUserOperationGas', jsonRequestData)
return await this.userOpJsonRpcProvider
.send('eth_estimateUserOperationGas', [hexifiedUserOp, this.entryPointAddress])
}
private async printUserOperation (method: string, [userOp, entryPointAddress]: [UserOperation, string]): Promise<void> {
debug('sending', method, {
...userOp
// initCode: (userOp.initCode ?? '').length,
// callData: (userOp.callData ?? '').length
}, entryPointAddress)
}
}