Skip to content

Commit 4f55840

Browse files
Fixes RPC request for hd wallets: (#1072)
* Handles case where result is undefined or null
1 parent ff01445 commit 4f55840

File tree

8 files changed

+94
-102
lines changed

8 files changed

+94
-102
lines changed

packages/common/src/hdwallets.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type Common from '@ethereumjs/common'
22
import type { BigNumber } from 'ethers'
3-
import type { CustomNetwork } from './types'
3+
import type { CustomNetwork, EIP1193Provider, RPCResponse } from './types'
44
import type { TransactionRequest } from '@ethersproject/providers'
55

66
/**
@@ -77,3 +77,30 @@ export const bigNumberFieldsToStrings = (
7777
}),
7878
transaction
7979
) as StringifiedTransactionRequest
80+
81+
/**
82+
* Helper method for hardware wallets to build an object
83+
* with a request method used for making rpc requests.
84+
* @param getRpcUrl - callback used to get the current chain's rpc url
85+
* @returns An object with a request method
86+
* to be called when making rpc requests
87+
*/
88+
export const getHardwareWalletProvider = (
89+
getRpcUrl: () => string
90+
): { request: EIP1193Provider['request'] } => ({
91+
request: ({ method, params }) =>
92+
fetch(getRpcUrl(), {
93+
method: 'POST',
94+
body: JSON.stringify({
95+
id: '42',
96+
method,
97+
params
98+
})
99+
}).then(async res => {
100+
const response = (await res.json()) as RPCResponse
101+
if ('error' in response) {
102+
throw response.error
103+
}
104+
return response.result
105+
})
106+
})

packages/common/src/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ import type {
5353
Chain,
5454
TokenSymbol,
5555
CustomNetwork,
56-
TransactionObject
56+
TransactionObject,
57+
RPCResponse
5758
} from './types'
5859

5960
export { ProviderRpcErrorCode } from './types'
@@ -62,7 +63,7 @@ export { createEIP1193Provider } from './eip-1193'
6263
export { default as accountSelect } from './account-select'
6364
export { entryModal } from './entry-modal'
6465
export { SofiaProLight, SofiaProRegular, SofiaProSemiBold } from './fonts'
65-
export { getCommon, bigNumberFieldsToStrings } from './hdwallets'
66+
export { getCommon, bigNumberFieldsToStrings, getHardwareWalletProvider } from './hdwallets'
6667

6768
export type {
6869
RequestPatch,
@@ -119,5 +120,6 @@ export type {
119120
Chain,
120121
TokenSymbol,
121122
CustomNetwork,
122-
TransactionObject
123+
TransactionObject,
124+
RPCResponse
123125
}

packages/common/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,3 +466,10 @@ export interface BootstrapNode {
466466
location: string
467467
comment: string
468468
}
469+
470+
export interface RPCResponse {
471+
id: number,
472+
jsonrpc: string
473+
error?: { code: number, message: string}
474+
result?: any
475+
}

packages/demo/src/App.svelte

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,27 @@
220220
221221
const signature = await signer.signTransaction({
222222
to: '',
223-
value: 1000000000000000
223+
value: 100000000000000
224224
})
225+
225226
console.log(signature)
226227
}
227228
229+
let toAddress
230+
const sendTransaction = async (provider) => {
231+
const ethersProvider = new ethers.providers.Web3Provider(provider, 'any')
232+
233+
const signer = ethersProvider.getSigner()
234+
235+
const txn = await signer.sendTransaction({
236+
to: toAddress,
237+
value: 100000000000000
238+
})
239+
240+
const receipt = await txn.wait()
241+
console.log(receipt)
242+
}
243+
228244
const signMessage = async (provider, address) => {
229245
const ethersProvider = new ethers.providers.Web3Provider(provider, 'any')
230246
@@ -441,6 +457,20 @@
441457
</button>
442458
</div>
443459
460+
<div>
461+
<input
462+
type="text"
463+
class="text-input"
464+
placeholder="0x..."
465+
bind:value={toAddress}
466+
/>
467+
<button
468+
on:click={sendTransaction(provider)}
469+
>
470+
Send Transaction
471+
</button>
472+
</div>
473+
444474
<div class="sign-transaction">
445475
<textarea
446476
bind:value={transactionObject}

packages/keepkey/src/index.ts

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import type {
33
Account,
44
Asset,
55
Chain,
6-
WalletInit,
7-
EIP1193Provider
6+
WalletInit
87
} from '@web3-onboard/common'
98

109
import type { StaticJsonRpcProvider } from '@ethersproject/providers'
@@ -65,7 +64,8 @@ function keepkey(): WalletInit {
6564
createEIP1193Provider,
6665
ProviderRpcError,
6766
entryModal,
68-
bigNumberFieldsToStrings
67+
bigNumberFieldsToStrings,
68+
getHardwareWalletProvider
6969
} = await import('@web3-onboard/common')
7070

7171
const { utils } = await import('ethers')
@@ -282,27 +282,9 @@ function keepkey(): WalletInit {
282282
return signature
283283
}
284284

285-
const request: EIP1193Provider['request'] = async ({
286-
method,
287-
params
288-
}) => {
289-
const response = await fetch(currentChain.rpcUrl, {
290-
method: 'POST',
291-
body: JSON.stringify({
292-
id: '42',
293-
method,
294-
params
295-
})
296-
}).then(res => res.json())
297-
298-
if (response.result) {
299-
return response.result
300-
} else {
301-
throw response.error
302-
}
303-
}
304-
305-
const keepKeyProvider = { request }
285+
const keepKeyProvider = getHardwareWalletProvider(
286+
() => currentChain.rpcUrl
287+
)
306288

307289
const provider = createEIP1193Provider(keepKeyProvider, {
308290
eth_requestAccounts: async () => {

packages/keystone/src/index.ts

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ function keystone({
101101
ProviderRpcError,
102102
ProviderRpcErrorCode,
103103
getCommon,
104-
bigNumberFieldsToStrings
104+
bigNumberFieldsToStrings,
105+
getHardwareWalletProvider
105106
} = await import('@web3-onboard/common')
106107

107108
const keyring = AirGappedKeyring.getEmptyKeyring()
@@ -150,30 +151,9 @@ function keystone({
150151
return keyring.signMessage(account.address, message)
151152
}
152153

153-
const request = async ({
154-
method,
155-
params
156-
}: {
157-
method: string
158-
params: any
159-
}) => {
160-
const response = await fetch(currentChain.rpcUrl, {
161-
method: 'POST',
162-
body: JSON.stringify({
163-
id: '42',
164-
method,
165-
params
166-
})
167-
}).then(res => res.json())
168-
169-
if (response.result) {
170-
return response.result
171-
} else {
172-
throw response.error
173-
}
174-
}
175-
176-
const keystoneProvider = { request }
154+
const keystoneProvider = getHardwareWalletProvider(
155+
() => currentChain.rpcUrl
156+
)
177157

178158
const provider = createEIP1193Provider(keystoneProvider, {
179159
eth_requestAccounts: async () => {

packages/ledger/src/index.ts

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import type {
55
Chain,
66
CustomNetwork,
77
WalletInit,
8-
GetInterfaceHelpers,
9-
EIP1193Provider
8+
GetInterfaceHelpers
109
} from '@web3-onboard/common'
1110

1211
// these cannot be dynamically imported
@@ -130,7 +129,8 @@ function ledger({
130129
createEIP1193Provider,
131130
ProviderRpcError,
132131
getCommon,
133-
bigNumberFieldsToStrings
132+
bigNumberFieldsToStrings,
133+
getHardwareWalletProvider
134134
} = await import('@web3-onboard/common')
135135

136136
const { TransactionFactory: Transaction, Capability } = await import(
@@ -222,28 +222,10 @@ function ledger({
222222
return `0x${result['r']}${result['s']}${v}`
223223
})
224224
}
225-
226-
const request: EIP1193Provider['request'] = async ({
227-
method,
228-
params
229-
}) => {
230-
const response = await fetch(currentChain.rpcUrl, {
231-
method: 'POST',
232-
body: JSON.stringify({
233-
id: '42',
234-
method,
235-
params
236-
})
237-
}).then(res => res.json())
238-
239-
if (response.result) {
240-
return response.result
241-
} else {
242-
throw response.error
243-
}
244-
}
245-
246-
const ledgerProvider = { request }
225+
226+
const ledgerProvider = getHardwareWalletProvider(
227+
() => currentChain?.rpcUrl
228+
)
247229

248230
const provider = createEIP1193Provider(ledgerProvider, {
249231
eth_requestAccounts: async () => {

packages/trezor/src/index.ts

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type {
33
Asset,
44
Chain,
55
CustomNetwork,
6-
EIP1193Provider,
76
ScanAccountsOptions,
87
TransactionObject,
98
WalletInit
@@ -123,7 +122,8 @@ function trezor(options: TrezorOptions): WalletInit {
123122
bigNumberFieldsToStrings,
124123
createEIP1193Provider,
125124
ProviderRpcError,
126-
getCommon
125+
getCommon,
126+
getHardwareWalletProvider
127127
} = await import('@web3-onboard/common')
128128
const ethUtil = await import('ethereumjs-util')
129129
const { compress } = (await import('eth-crypto')).publicKey
@@ -443,27 +443,9 @@ function trezor(options: TrezorOptions): WalletInit {
443443
})
444444
}
445445

446-
const request: EIP1193Provider['request'] = async ({
447-
method,
448-
params
449-
}) => {
450-
const response = await fetch(currentChain.rpcUrl, {
451-
method: 'POST',
452-
body: JSON.stringify({
453-
id: '42',
454-
method,
455-
params
456-
})
457-
}).then(res => res.json())
458-
459-
if (response.result) {
460-
return response.result
461-
} else {
462-
throw response.error
463-
}
464-
}
465-
466-
const trezorProvider = { request }
446+
const trezorProvider = getHardwareWalletProvider(
447+
() => currentChain?.rpcUrl
448+
)
467449

468450
const provider = createEIP1193Provider(trezorProvider, {
469451
eth_requestAccounts: async () => {

0 commit comments

Comments
 (0)