@0xsequence/provider 1.10.14 → 2.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.
- package/dist/0xsequence-provider.cjs.dev.js +656 -648
- package/dist/0xsequence-provider.cjs.prod.js +656 -648
- package/dist/0xsequence-provider.esm.js +660 -652
- package/dist/declarations/src/client.d.ts +7 -3
- package/dist/declarations/src/provider.d.ts +31 -22
- package/dist/declarations/src/signer.d.ts +15 -14
- package/dist/declarations/src/transports/base-provider-transport.d.ts +6 -2
- package/dist/declarations/src/transports/base-wallet-transport.d.ts +6 -2
- package/dist/declarations/src/transports/mux-transport/mux-message-provider.d.ts +5 -2
- package/dist/declarations/src/transports/wallet-request-handler.d.ts +7 -6
- package/dist/declarations/src/types.d.ts +6 -11
- package/dist/declarations/src/utils/index.d.ts +3 -3
- package/dist/declarations/src/utils.d.ts +7 -7
- package/package.json +12 -12
- package/src/client.ts +29 -51
- package/src/eip191exceptions.ts +2 -2
- package/src/extended.ts +5 -5
- package/src/init.ts +9 -10
- package/src/provider.ts +112 -66
- package/src/signer.ts +38 -43
- package/src/transactions.ts +4 -4
- package/src/transports/base-provider-transport.ts +19 -23
- package/src/transports/base-wallet-transport.ts +22 -13
- package/src/transports/mux-transport/mux-message-provider.ts +5 -6
- package/src/transports/proxy-transport/proxy-message-provider.ts +5 -2
- package/src/transports/wallet-request-handler.ts +91 -130
- package/src/transports/window-transport/window-message-handler.ts +15 -3
- package/src/transports/window-transport/window-message-provider.ts +1 -1
- package/src/types.ts +8 -11
- package/src/utils/index.ts +4 -4
- package/src/utils.ts +16 -18
package/src/extended.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ethers } from 'ethers'
|
|
2
2
|
|
|
3
|
-
export type ExtendedTransactionRequest = ethers.
|
|
4
|
-
auxiliary?: ethers.
|
|
3
|
+
export type ExtendedTransactionRequest = ethers.TransactionRequest & {
|
|
4
|
+
auxiliary?: ethers.TransactionRequest[]
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export function toExtended(transactions: ethers.
|
|
7
|
+
export function toExtended(transactions: ethers.TransactionRequest[]): ExtendedTransactionRequest {
|
|
8
8
|
if (transactions.length === 0) {
|
|
9
9
|
throw new Error('No transaction provided')
|
|
10
10
|
}
|
|
@@ -17,10 +17,10 @@ export function toExtended(transactions: ethers.providers.TransactionRequest[]):
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export function fromExtended(transaction: ExtendedTransactionRequest): ethers.
|
|
20
|
+
export function fromExtended(transaction: ExtendedTransactionRequest): ethers.TransactionRequest[] {
|
|
21
21
|
return [transaction, ...(transaction.auxiliary || [])]
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export function isExtended(transaction: ethers.
|
|
24
|
+
export function isExtended(transaction: ethers.TransactionRequest): transaction is ExtendedTransactionRequest {
|
|
25
25
|
return (transaction as any).auxiliary !== undefined
|
|
26
26
|
}
|
package/src/init.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CachedProvider,
|
|
3
3
|
ChainIdLike,
|
|
4
|
-
JsonRpcRouter,
|
|
5
|
-
JsonRpcSender,
|
|
6
4
|
NetworkConfig,
|
|
7
5
|
allNetworks,
|
|
8
6
|
exceptionProviderMiddleware,
|
|
9
7
|
findNetworkConfig,
|
|
10
|
-
loggingProviderMiddleware
|
|
8
|
+
loggingProviderMiddleware,
|
|
9
|
+
JsonRpcProvider
|
|
11
10
|
} from '@0xsequence/network'
|
|
12
11
|
import { MuxTransportTemplate } from './transports'
|
|
13
12
|
import { ItemStore, useBestStore } from './utils'
|
|
@@ -85,7 +84,7 @@ export const initWallet = (projectAccessKey: string, partialConfig?: Partial<Pro
|
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
const rpcProviders: Record<number, ethers.
|
|
87
|
+
const rpcProviders: Record<number, ethers.JsonRpcProvider> = {}
|
|
89
88
|
|
|
90
89
|
// Find any new networks that aren't already defined in sequence.js
|
|
91
90
|
// and add them to the list of networks, (they must have a rpcUrl and chainId)
|
|
@@ -120,13 +119,13 @@ export const initWallet = (projectAccessKey: string, partialConfig?: Partial<Pro
|
|
|
120
119
|
throw new Error(`no rpcUrl found for chainId: ${chainId}`)
|
|
121
120
|
}
|
|
122
121
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
rpcProviders[chainId] = new JsonRpcProvider(
|
|
123
|
+
rpcUrl,
|
|
124
|
+
{
|
|
125
|
+
middlewares: [loggingProviderMiddleware, exceptionProviderMiddleware, new CachedProvider()]
|
|
126
|
+
},
|
|
127
|
+
{ cacheTimeout: -1 }
|
|
127
128
|
)
|
|
128
|
-
|
|
129
|
-
rpcProviders[chainId] = new ethers.providers.Web3Provider(router, chainId)
|
|
130
129
|
}
|
|
131
130
|
|
|
132
131
|
return rpcProviders[chainId]
|
package/src/provider.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ethers } from 'ethers'
|
|
2
2
|
import { SequenceClient } from './client'
|
|
3
|
-
import { ChainIdLike, NetworkConfig, allNetworks, findNetworkConfig } from '@0xsequence/network'
|
|
4
|
-
import { ConnectDetails, ConnectOptions,
|
|
3
|
+
import { EIP1193Provider, ChainIdLike, NetworkConfig, allNetworks, findNetworkConfig } from '@0xsequence/network'
|
|
4
|
+
import { ConnectDetails, ConnectOptions, OpenWalletIntent, OptionalChainIdLike, WalletSession } from './types'
|
|
5
5
|
import { commons } from '@0xsequence/core'
|
|
6
6
|
import { WalletUtils } from './utils/index'
|
|
7
7
|
import { SequenceSigner, SingleNetworkSequenceSigner } from './signer'
|
|
@@ -46,7 +46,10 @@ export interface ISequenceProvider {
|
|
|
46
46
|
utils: WalletUtils
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
const EIP1193EventTypes = ['connect', 'disconnect', 'chainChanged', 'accountsChanged'] as const
|
|
50
|
+
type EIP1193EventType = (typeof EIP1193EventTypes)[number]
|
|
51
|
+
|
|
52
|
+
export class SequenceProvider extends ethers.AbstractProvider implements ISequenceProvider, EIP1193Provider {
|
|
50
53
|
private readonly singleNetworkProviders: { [chainId: number]: SingleNetworkSequenceProvider } = {}
|
|
51
54
|
|
|
52
55
|
readonly _isSequenceProvider = true
|
|
@@ -54,30 +57,37 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
54
57
|
|
|
55
58
|
readonly signer: SequenceSigner
|
|
56
59
|
|
|
60
|
+
readonly eip1193EventListeners = new Map<EIP1193EventType, Set<ethers.Listener>>()
|
|
61
|
+
|
|
57
62
|
constructor(
|
|
58
63
|
public readonly client: SequenceClient,
|
|
59
|
-
private readonly providerFor: (networkId: number) => ethers.
|
|
60
|
-
public readonly networks: NetworkConfig[] = allNetworks
|
|
64
|
+
private readonly providerFor: (networkId: number) => ethers.JsonRpcProvider,
|
|
65
|
+
public readonly networks: NetworkConfig[] = allNetworks,
|
|
66
|
+
public readonly options?: ethers.AbstractProviderOptions
|
|
61
67
|
) {
|
|
62
68
|
// We support a lot of networks
|
|
63
69
|
// but we start with the default one
|
|
64
|
-
super(client.getChainId())
|
|
70
|
+
super(client.getChainId(), options)
|
|
65
71
|
|
|
66
72
|
// Emit events as defined by EIP-1193
|
|
67
73
|
client.onConnect(details => {
|
|
68
|
-
this.emit('connect', details)
|
|
74
|
+
//this.emit('connect', details)
|
|
75
|
+
this.eip1193EventListeners.get('connect')?.forEach(listener => listener(details))
|
|
69
76
|
})
|
|
70
77
|
|
|
71
78
|
client.onDisconnect(error => {
|
|
72
|
-
this.emit('disconnect', error)
|
|
79
|
+
//this.emit('disconnect', error)
|
|
80
|
+
this.eip1193EventListeners.get('disconnect')?.forEach(listener => listener(error))
|
|
73
81
|
})
|
|
74
82
|
|
|
75
83
|
client.onDefaultChainIdChanged(chainId => {
|
|
76
|
-
this.emit('chainChanged', chainId)
|
|
84
|
+
//this.emit('chainChanged', chainId)
|
|
85
|
+
this.eip1193EventListeners.get('chainChanged')?.forEach(listener => listener(chainId))
|
|
77
86
|
})
|
|
78
87
|
|
|
79
88
|
client.onAccountsChanged(accounts => {
|
|
80
|
-
this.emit('accountsChanged', accounts)
|
|
89
|
+
//this.emit('accountsChanged', accounts)
|
|
90
|
+
this.eip1193EventListeners.get('accountsChanged')?.forEach(listener => listener(accounts))
|
|
81
91
|
})
|
|
82
92
|
|
|
83
93
|
// NOTICE: We don't emit 'open' and 'close' events
|
|
@@ -95,6 +105,36 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
95
105
|
this.utils = new WalletUtils(this.signer)
|
|
96
106
|
}
|
|
97
107
|
|
|
108
|
+
async on(event: ethers.ProviderEvent | EIP1193EventType, listener: ethers.Listener): Promise<this> {
|
|
109
|
+
if (EIP1193EventTypes.includes(event as EIP1193EventType)) {
|
|
110
|
+
const listeners = this.eip1193EventListeners.get(event as EIP1193EventType) || new Set()
|
|
111
|
+
listeners.add(listener)
|
|
112
|
+
this.eip1193EventListeners.set(event as EIP1193EventType, listeners)
|
|
113
|
+
|
|
114
|
+
return this
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return super.on(event, listener) as Promise<this>
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async off(event: ethers.ProviderEvent | EIP1193EventType, listener?: ethers.Listener | undefined): Promise<this> {
|
|
121
|
+
if (EIP1193EventTypes.includes(event as EIP1193EventType)) {
|
|
122
|
+
const listeners = this.eip1193EventListeners.get(event as EIP1193EventType)
|
|
123
|
+
|
|
124
|
+
if (listeners) {
|
|
125
|
+
if (listener) {
|
|
126
|
+
listeners.delete(listener)
|
|
127
|
+
} else {
|
|
128
|
+
listeners.clear()
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return this
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return super.off(event, listener) as Promise<this>
|
|
136
|
+
}
|
|
137
|
+
|
|
98
138
|
getSigner(): SequenceSigner
|
|
99
139
|
getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner
|
|
100
140
|
getSigner(chainId?: ChainIdLike): SequenceSigner | SingleNetworkSequenceSigner
|
|
@@ -206,13 +246,18 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
206
246
|
getProvider(chainId?: ChainIdLike) {
|
|
207
247
|
// The provider without a chainId is... this one
|
|
208
248
|
if (!chainId) {
|
|
209
|
-
return this
|
|
249
|
+
return this as SequenceProvider
|
|
210
250
|
}
|
|
211
251
|
|
|
212
252
|
const useChainId = this.toChainId(chainId)
|
|
213
253
|
|
|
214
254
|
if (!this.singleNetworkProviders[useChainId]) {
|
|
215
|
-
this.singleNetworkProviders[useChainId] = new SingleNetworkSequenceProvider(
|
|
255
|
+
this.singleNetworkProviders[useChainId] = new SingleNetworkSequenceProvider(
|
|
256
|
+
this.client,
|
|
257
|
+
this.providerFor,
|
|
258
|
+
useChainId,
|
|
259
|
+
this.options
|
|
260
|
+
)
|
|
216
261
|
}
|
|
217
262
|
|
|
218
263
|
return this.singleNetworkProviders[useChainId]
|
|
@@ -222,7 +267,7 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
222
267
|
* This returns a subprovider, this is a regular non-sequence provider that
|
|
223
268
|
* can be used to fulfill read only requests on a given network.
|
|
224
269
|
*/
|
|
225
|
-
async _getSubprovider(chainId?: ChainIdLike): Promise<ethers.
|
|
270
|
+
async _getSubprovider(chainId?: ChainIdLike): Promise<ethers.JsonRpcProvider> {
|
|
226
271
|
const useChainId = await this.useChainId(chainId)
|
|
227
272
|
|
|
228
273
|
// Whoever implements providerFrom should memoize the generated provider
|
|
@@ -236,10 +281,23 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
236
281
|
return provider
|
|
237
282
|
}
|
|
238
283
|
|
|
284
|
+
async _perform(req: ethers.PerformActionRequest): Promise<any> {
|
|
285
|
+
const { method, ...args } = req
|
|
286
|
+
|
|
287
|
+
const provider = await this._getSubprovider()
|
|
288
|
+
const prepared = provider.getRpcRequest(req) ?? { method, args: Object.values(args) }
|
|
289
|
+
|
|
290
|
+
if (!prepared) {
|
|
291
|
+
throw new Error(`Unsupported method ${req.method}`)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return provider.send(prepared.method, prepared.args)
|
|
295
|
+
}
|
|
296
|
+
|
|
239
297
|
async perform(method: string, params: any): Promise<any> {
|
|
240
298
|
// First we check if the method should be handled by the client
|
|
241
299
|
if (method === 'eth_chainId') {
|
|
242
|
-
return ethers.
|
|
300
|
+
return ethers.toQuantity(await this.useChainId())
|
|
243
301
|
}
|
|
244
302
|
|
|
245
303
|
if (method === 'eth_accounts') {
|
|
@@ -268,14 +326,10 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
268
326
|
) {
|
|
269
327
|
// We pass the chainId to the client, if we don't pass one
|
|
270
328
|
// the client will use its own default chainId
|
|
271
|
-
return this.client.
|
|
329
|
+
return this.client.request({ method, params, chainId: this.getChainId() })
|
|
272
330
|
}
|
|
273
331
|
|
|
274
|
-
|
|
275
|
-
// we use the provided chainId, or the default one provided by the client
|
|
276
|
-
const provider = await this._getSubprovider()
|
|
277
|
-
const prepared = provider.prepareRequest(method, params) ?? [method, params]
|
|
278
|
-
return provider.send(prepared[0], prepared[1])
|
|
332
|
+
return this._perform({ method, ...params })
|
|
279
333
|
}
|
|
280
334
|
|
|
281
335
|
send(method: string, params: any): Promise<any> {
|
|
@@ -286,17 +340,23 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
286
340
|
return this.perform(request.method, request.params)
|
|
287
341
|
}
|
|
288
342
|
|
|
289
|
-
async
|
|
343
|
+
async _detectNetwork(): Promise<ethers.Network> {
|
|
290
344
|
const chainId = this.client.getChainId()
|
|
291
|
-
const
|
|
345
|
+
const found = findNetworkConfig(this.networks, chainId)
|
|
292
346
|
|
|
293
|
-
if (!
|
|
347
|
+
if (!found) {
|
|
294
348
|
throw new Error(`Unknown network ${chainId}`)
|
|
295
349
|
}
|
|
296
350
|
|
|
351
|
+
const network = new ethers.Network(found.name, found.chainId)
|
|
352
|
+
|
|
297
353
|
return network
|
|
298
354
|
}
|
|
299
355
|
|
|
356
|
+
async detectNetwork(): Promise<ethers.Network> {
|
|
357
|
+
return this._detectNetwork()
|
|
358
|
+
}
|
|
359
|
+
|
|
300
360
|
// Override most of the methods, so we add support for an optional chainId
|
|
301
361
|
// argument, which is used to select the provider to use.
|
|
302
362
|
//
|
|
@@ -314,76 +374,61 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
314
374
|
return provider.getBlockNumber()
|
|
315
375
|
}
|
|
316
376
|
|
|
317
|
-
async
|
|
377
|
+
async getFeeData(optionals?: OptionalChainIdLike) {
|
|
318
378
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
319
|
-
return provider.
|
|
379
|
+
return provider.getFeeData()
|
|
320
380
|
}
|
|
321
381
|
|
|
322
|
-
async getBalance(
|
|
323
|
-
addressOrName: string | Promise<string>,
|
|
324
|
-
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>,
|
|
325
|
-
optionals?: OptionalChainIdLike
|
|
326
|
-
) {
|
|
382
|
+
async getBalance(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike) {
|
|
327
383
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
328
384
|
return provider.getBalance(addressOrName, blockTag)
|
|
329
385
|
}
|
|
330
386
|
|
|
331
387
|
async getTransactionCount(
|
|
332
388
|
addressOrName: string | Promise<string>,
|
|
333
|
-
blockTag?: ethers.
|
|
389
|
+
blockTag?: ethers.BlockTag,
|
|
334
390
|
optionals?: OptionalChainIdLike
|
|
335
391
|
) {
|
|
336
392
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
337
393
|
return provider.getTransactionCount(addressOrName, blockTag)
|
|
338
394
|
}
|
|
339
395
|
|
|
340
|
-
async getCode(
|
|
341
|
-
addressOrName: string | Promise<string>,
|
|
342
|
-
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>,
|
|
343
|
-
optionals?: OptionalChainIdLike
|
|
344
|
-
) {
|
|
396
|
+
async getCode(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike) {
|
|
345
397
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
346
398
|
return provider.getCode(addressOrName, blockTag)
|
|
347
399
|
}
|
|
348
400
|
|
|
349
|
-
async
|
|
401
|
+
async getStorage(
|
|
350
402
|
addressOrName: string | Promise<string>,
|
|
351
|
-
position: ethers.BigNumberish
|
|
352
|
-
blockTag?: ethers.
|
|
403
|
+
position: ethers.BigNumberish,
|
|
404
|
+
blockTag?: ethers.BlockTag,
|
|
353
405
|
optionals?: OptionalChainIdLike
|
|
354
406
|
) {
|
|
355
407
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
356
|
-
return provider.
|
|
408
|
+
return provider.getStorage(addressOrName, position, blockTag)
|
|
357
409
|
}
|
|
358
410
|
|
|
359
|
-
async call(
|
|
360
|
-
transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>,
|
|
361
|
-
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>,
|
|
362
|
-
optionals?: OptionalChainIdLike
|
|
363
|
-
) {
|
|
411
|
+
async call(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike) {
|
|
364
412
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
365
|
-
return provider.call(transaction
|
|
413
|
+
return provider.call(transaction)
|
|
366
414
|
}
|
|
367
415
|
|
|
368
|
-
async estimateGas(transaction: ethers.
|
|
416
|
+
async estimateGas(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike) {
|
|
369
417
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
370
418
|
return provider.estimateGas(transaction)
|
|
371
419
|
}
|
|
372
420
|
|
|
373
|
-
async getBlock(
|
|
374
|
-
blockHashOrBlockTag: ethers.providers.BlockTag | string | Promise<ethers.providers.BlockTag | string>,
|
|
375
|
-
optionals?: OptionalChainIdLike
|
|
376
|
-
) {
|
|
421
|
+
async getBlock(blockHashOrBlockTag: ethers.BlockTag | string, prefetchTxs?: boolean, optionals?: OptionalChainIdLike) {
|
|
377
422
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
378
|
-
return provider.getBlock(blockHashOrBlockTag)
|
|
423
|
+
return provider.getBlock(blockHashOrBlockTag, prefetchTxs)
|
|
379
424
|
}
|
|
380
425
|
|
|
381
|
-
async getTransaction(transactionHash: string
|
|
426
|
+
async getTransaction(transactionHash: string, optionals?: OptionalChainIdLike) {
|
|
382
427
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
383
428
|
return provider.getTransaction(transactionHash)
|
|
384
429
|
}
|
|
385
430
|
|
|
386
|
-
async getLogs(filter: ethers.
|
|
431
|
+
async getLogs(filter: ethers.Filter, optionals?: OptionalChainIdLike) {
|
|
387
432
|
const provider = await this._getSubprovider(optionals?.chainId)
|
|
388
433
|
return provider.getLogs(filter)
|
|
389
434
|
}
|
|
@@ -405,8 +450,8 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
405
450
|
return provider.getResolver(name)
|
|
406
451
|
}
|
|
407
452
|
|
|
408
|
-
async resolveName(name: string
|
|
409
|
-
if (ethers.
|
|
453
|
+
async resolveName(name: string) {
|
|
454
|
+
if (ethers.isAddress(name)) {
|
|
410
455
|
return name
|
|
411
456
|
}
|
|
412
457
|
|
|
@@ -419,7 +464,7 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
419
464
|
return provider.resolveName(name)
|
|
420
465
|
}
|
|
421
466
|
|
|
422
|
-
async lookupAddress(address: string
|
|
467
|
+
async lookupAddress(address: string) {
|
|
423
468
|
if (!(await this.supportsENS())) {
|
|
424
469
|
return null
|
|
425
470
|
}
|
|
@@ -443,9 +488,9 @@ export class SequenceProvider extends ethers.providers.BaseProvider implements I
|
|
|
443
488
|
}
|
|
444
489
|
}
|
|
445
490
|
|
|
446
|
-
function normalizeChainId(chainId:
|
|
491
|
+
function normalizeChainId(chainId: ethers.BigNumberish | { chainId: string }): number {
|
|
447
492
|
if (typeof chainId === 'object') return normalizeChainId(chainId.chainId)
|
|
448
|
-
return
|
|
493
|
+
return Number(chainId)
|
|
449
494
|
}
|
|
450
495
|
|
|
451
496
|
/**
|
|
@@ -462,10 +507,11 @@ export class SingleNetworkSequenceProvider extends SequenceProvider {
|
|
|
462
507
|
|
|
463
508
|
constructor(
|
|
464
509
|
client: SequenceClient,
|
|
465
|
-
providerFor: (networkId: number) => ethers.
|
|
466
|
-
public readonly chainId: ChainIdLike
|
|
510
|
+
providerFor: (networkId: number) => ethers.JsonRpcProvider,
|
|
511
|
+
public readonly chainId: ChainIdLike,
|
|
512
|
+
options?: ethers.AbstractProviderOptions
|
|
467
513
|
) {
|
|
468
|
-
super(client, providerFor)
|
|
514
|
+
super(client, providerFor, undefined, options)
|
|
469
515
|
}
|
|
470
516
|
|
|
471
517
|
private _useChainId(chainId?: ChainIdLike): number {
|
|
@@ -486,15 +532,15 @@ export class SingleNetworkSequenceProvider extends SequenceProvider {
|
|
|
486
532
|
return super.toChainId(this.chainId)
|
|
487
533
|
}
|
|
488
534
|
|
|
489
|
-
async getNetwork(): Promise<
|
|
535
|
+
async getNetwork(): Promise<ethers.Network> {
|
|
490
536
|
const networks = await this.client.getNetworks()
|
|
491
|
-
const
|
|
537
|
+
const found = findNetworkConfig(networks, this.chainId)
|
|
492
538
|
|
|
493
|
-
if (!
|
|
539
|
+
if (!found) {
|
|
494
540
|
throw new Error(`Unsupported network ${this.chainId}`)
|
|
495
541
|
}
|
|
496
542
|
|
|
497
|
-
return
|
|
543
|
+
return new ethers.Network(found.name, found.chainId)
|
|
498
544
|
}
|
|
499
545
|
|
|
500
546
|
/**
|
package/src/signer.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { resolveArrayProperties } from './utils'
|
|
|
8
8
|
import { WalletUtils } from './utils/index'
|
|
9
9
|
import { OptionalChainIdLike, OptionalEIP6492 } from './types'
|
|
10
10
|
|
|
11
|
-
export interface ISequenceSigner extends ethers.Signer {
|
|
11
|
+
export interface ISequenceSigner extends Omit<ethers.Signer, 'connect'> {
|
|
12
12
|
getProvider(): SequenceProvider
|
|
13
13
|
getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider
|
|
14
14
|
getProvider(chainId?: ChainIdLike): SequenceProvider | SingleNetworkSequenceProvider
|
|
@@ -20,6 +20,8 @@ export interface ISequenceSigner extends ethers.Signer {
|
|
|
20
20
|
getWalletConfig(chainId?: ChainIdLike): Promise<commons.config.Config>
|
|
21
21
|
getNetworks(): Promise<NetworkConfig[]>
|
|
22
22
|
|
|
23
|
+
connect: (provider: SequenceProvider) => SequenceSigner
|
|
24
|
+
|
|
23
25
|
signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise<string>
|
|
24
26
|
|
|
25
27
|
signTypedData(
|
|
@@ -33,9 +35,7 @@ export interface ISequenceSigner extends ethers.Signer {
|
|
|
33
35
|
// the signer, and finally sends it to the relayer for submission to an Ethereum network.
|
|
34
36
|
// It supports any kind of transaction, including regular ethers transactions, and Sequence transactions.
|
|
35
37
|
sendTransaction(
|
|
36
|
-
transaction:
|
|
37
|
-
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>[]
|
|
38
|
-
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>,
|
|
38
|
+
transaction: ethers.TransactionRequest[] | ethers.TransactionRequest,
|
|
39
39
|
options?: OptionalChainIdLike
|
|
40
40
|
): Promise<commons.transaction.TransactionResponse>
|
|
41
41
|
|
|
@@ -45,7 +45,6 @@ export interface ISequenceSigner extends ethers.Signer {
|
|
|
45
45
|
export class SequenceSigner implements ISequenceSigner {
|
|
46
46
|
private readonly singleNetworkSigners: { [chainId: number]: SingleNetworkSequenceSigner } = {}
|
|
47
47
|
|
|
48
|
-
readonly _isSigner: boolean = true
|
|
49
48
|
readonly _isSequenceSigner: boolean = true
|
|
50
49
|
|
|
51
50
|
get utils(): WalletUtils {
|
|
@@ -63,7 +62,7 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
63
62
|
|
|
64
63
|
// This method shouldn't be used directly
|
|
65
64
|
// it exists to maintain compatibility with ethers.Signer
|
|
66
|
-
connect(provider: ethers.
|
|
65
|
+
connect(provider: ethers.Provider): SequenceSigner {
|
|
67
66
|
if (!SequenceProvider.is(provider)) {
|
|
68
67
|
throw new Error('SequenceSigner can only be connected to a SequenceProvider')
|
|
69
68
|
}
|
|
@@ -124,25 +123,28 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
124
123
|
return this.provider.getProvider(chainId)
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
async sendTransaction(
|
|
128
|
-
transaction:
|
|
129
|
-
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>[]
|
|
130
|
-
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>,
|
|
131
|
-
options?: OptionalChainIdLike
|
|
132
|
-
) {
|
|
126
|
+
async sendTransaction(transaction: ethers.TransactionRequest[] | ethers.TransactionRequest, options?: OptionalChainIdLike) {
|
|
133
127
|
const chainId = this.useChainId(options?.chainId)
|
|
134
128
|
const resolved = await resolveArrayProperties(transaction)
|
|
135
129
|
const txHash = await this.client.sendTransaction(resolved, { chainId })
|
|
136
130
|
const provider = this.getProvider(chainId)
|
|
137
131
|
|
|
138
132
|
try {
|
|
139
|
-
|
|
140
|
-
async () => {
|
|
133
|
+
const result = await new Promise<ethers.TransactionResponse>(resolve => {
|
|
134
|
+
const check = async () => {
|
|
141
135
|
const tx = await provider.getTransaction(txHash)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
136
|
+
|
|
137
|
+
if (tx !== null) {
|
|
138
|
+
return resolve(tx)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await provider.once('block', check)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
check()
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
return result
|
|
146
148
|
} catch (err) {
|
|
147
149
|
err.transactionHash = txHash
|
|
148
150
|
throw err
|
|
@@ -158,35 +160,24 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
158
160
|
return this.client.getNetworks()
|
|
159
161
|
}
|
|
160
162
|
|
|
161
|
-
async getBalance(blockTag?: ethers.
|
|
163
|
+
async getBalance(blockTag?: ethers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<bigint> {
|
|
162
164
|
const provider = this.getProvider(optionals?.chainId)
|
|
163
165
|
return provider.getBalance(this.getAddress(), blockTag)
|
|
164
166
|
}
|
|
165
167
|
|
|
166
|
-
async estimateGas(
|
|
167
|
-
transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>,
|
|
168
|
-
optionals?: OptionalChainIdLike
|
|
169
|
-
): Promise<ethers.BigNumber> {
|
|
168
|
+
async estimateGas(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<bigint> {
|
|
170
169
|
return this.getProvider(optionals?.chainId).estimateGas(transaction)
|
|
171
170
|
}
|
|
172
171
|
|
|
173
|
-
async call(
|
|
174
|
-
|
|
175
|
-
blockTag?: ethers.providers.BlockTag | undefined,
|
|
176
|
-
optionals?: OptionalChainIdLike
|
|
177
|
-
): Promise<string> {
|
|
178
|
-
return this.getProvider(optionals?.chainId).call(transaction, blockTag)
|
|
172
|
+
async call(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<string> {
|
|
173
|
+
return this.getProvider(optionals?.chainId).call(transaction)
|
|
179
174
|
}
|
|
180
175
|
|
|
181
176
|
getChainId(): Promise<number> {
|
|
182
177
|
return Promise.resolve(this.client.getChainId())
|
|
183
178
|
}
|
|
184
179
|
|
|
185
|
-
async
|
|
186
|
-
return this.getProvider(optionals?.chainId).getGasPrice()
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.providers.FeeData> {
|
|
180
|
+
async getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.FeeData> {
|
|
190
181
|
return this.getProvider(optionals?.chainId).getFeeData()
|
|
191
182
|
}
|
|
192
183
|
|
|
@@ -194,7 +185,7 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
194
185
|
const res = await this.provider.resolveName(name)
|
|
195
186
|
|
|
196
187
|
// For some reason ethers.Signer expects this to return `string`
|
|
197
|
-
// but ethers.
|
|
188
|
+
// but ethers.Provider expects this to return `string | null`.
|
|
198
189
|
// The signer doesn't have any other source of information, so we'll
|
|
199
190
|
// fail if the provider doesn't return a result.
|
|
200
191
|
if (res === null) {
|
|
@@ -208,25 +199,29 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
208
199
|
// We always have a provider, so this is a noop
|
|
209
200
|
}
|
|
210
201
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
202
|
+
getNonce(_blockTag?: ethers.BlockTag): Promise<number> {
|
|
203
|
+
throw new Error('SequenceSigner does not support getNonce')
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
populateCall(_transaction: ethers.TransactionRequest): Promise<ethers.TransactionLike<string>> {
|
|
207
|
+
throw new Error('SequenceSigner does not support populateCall')
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
populateTransaction(_transaction: ethers.TransactionRequest): Promise<ethers.TransactionLike<string>> {
|
|
214
211
|
throw new Error('SequenceSigner does not support populateTransaction')
|
|
215
212
|
}
|
|
216
213
|
|
|
217
|
-
checkTransaction(
|
|
218
|
-
_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>
|
|
219
|
-
): ethers.utils.Deferrable<ethers.providers.TransactionRequest> {
|
|
214
|
+
checkTransaction(_transaction: ethers.TransactionRequest): ethers.TransactionRequest {
|
|
220
215
|
throw new Error('SequenceSigner does not support checkTransaction')
|
|
221
216
|
}
|
|
222
217
|
|
|
223
|
-
getTransactionCount(_blockTag?: ethers.
|
|
218
|
+
getTransactionCount(_blockTag?: ethers.BlockTag): Promise<number> {
|
|
224
219
|
// We could try returning the sequence nonce here
|
|
225
220
|
// but we aren't sure how ethers will use this nonce
|
|
226
221
|
throw new Error('SequenceSigner does not support getTransactionCount')
|
|
227
222
|
}
|
|
228
223
|
|
|
229
|
-
signTransaction(_transaction:
|
|
224
|
+
signTransaction(_transaction: commons.transaction.Transactionish): Promise<string> {
|
|
230
225
|
// We could implement signTransaction/sendTransaction here
|
|
231
226
|
// but first we need a way of serializing these signed transactions
|
|
232
227
|
// and it could lead to more trouble, because the dapp could try to send this transaction
|
package/src/transactions.ts
CHANGED
|
@@ -12,7 +12,7 @@ const PROHIBITED_FUNCTIONS = new Map(
|
|
|
12
12
|
'updateImageHash(bytes32)',
|
|
13
13
|
'updateImageHashAndIPFS(bytes32,bytes32)',
|
|
14
14
|
'updateImplementation(address)'
|
|
15
|
-
].map(signature => [ethers.
|
|
15
|
+
].map(signature => [ethers.id(signature).slice(0, 10), signature])
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
export function validateTransactionRequest(wallet: string, transaction: commons.transaction.Transactionish) {
|
|
@@ -24,7 +24,7 @@ export function validateTransactionRequest(wallet: string, transaction: commons.
|
|
|
24
24
|
function validateTransaction(wallet: string, transaction: commons.transaction.Transaction) {
|
|
25
25
|
if (transaction.to.toLowerCase() === wallet.toLowerCase()) {
|
|
26
26
|
if (transaction.data) {
|
|
27
|
-
const data = ethers.
|
|
27
|
+
const data = ethers.getBytes(transaction.data)
|
|
28
28
|
if (data.length >= 4 && !isCreateContractCall(data)) {
|
|
29
29
|
throw new Error('self calls are forbidden')
|
|
30
30
|
}
|
|
@@ -36,7 +36,7 @@ function validateTransaction(wallet: string, transaction: commons.transaction.Tr
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
if (transaction.data) {
|
|
39
|
-
const data = ethers.
|
|
39
|
+
const data = ethers.hexlify(transaction.data)
|
|
40
40
|
const selector = data.slice(0, 10)
|
|
41
41
|
const signature = PROHIBITED_FUNCTIONS.get(selector)
|
|
42
42
|
if (signature) {
|
|
@@ -47,7 +47,7 @@ function validateTransaction(wallet: string, transaction: commons.transaction.Tr
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
function isCreateContractCall(data: ethers.BytesLike): boolean {
|
|
50
|
-
const walletInterface = new ethers.
|
|
50
|
+
const walletInterface = new ethers.Interface(walletContracts.mainModule.abi)
|
|
51
51
|
try {
|
|
52
52
|
walletInterface.decodeFunctionData('createContract', data)
|
|
53
53
|
return true
|