@0xsequence/provider 1.1.0 → 1.1.2
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 +38 -17
- package/dist/0xsequence-provider.cjs.prod.js +38 -17
- package/dist/0xsequence-provider.esm.js +38 -17
- package/dist/declarations/src/client.d.ts +5 -5
- package/dist/declarations/src/init.d.ts +1 -1
- package/dist/declarations/src/provider.d.ts +3 -3
- package/dist/declarations/src/signer.d.ts +5 -5
- package/package.json +10 -10
- package/src/client.ts +76 -76
- package/src/extended.ts +3 -4
- package/src/init.ts +30 -27
- package/src/provider.ts +36 -66
- package/src/signer.ts +38 -54
- package/src/transactions.ts +23 -0
- package/src/transports/extension-transport/extension-message-handler.ts +4 -1
- package/src/transports/extension-transport/index.ts +1 -1
- package/src/transports/mux-transport/mux-message-provider.ts +15 -14
- package/src/transports/proxy-transport/proxy-message-channel.ts +0 -1
- package/src/transports/proxy-transport/proxy-message-provider.ts +12 -8
- package/src/transports/unreal-transport/index.ts +1 -1
- package/src/transports/unreal-transport/overridelogs.ts +1 -3
- package/src/transports/wallet-request-handler.ts +67 -40
- package/src/transports/window-transport/window-message-provider.ts +4 -3
- package/src/types.ts +25 -12
- package/src/utils/index.ts +2 -12
- package/src/utils.ts +12 -13
package/src/signer.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ethers } from
|
|
1
|
+
import { ethers } from 'ethers'
|
|
2
2
|
|
|
3
|
-
import { SequenceProvider, SingleNetworkSequenceProvider } from
|
|
4
|
-
import { SequenceClient } from
|
|
5
|
-
import { commons } from
|
|
6
|
-
import { ChainIdLike, NetworkConfig } from
|
|
7
|
-
import { resolveArrayProperties } from
|
|
8
|
-
import { WalletUtils } from
|
|
9
|
-
import { OptionalChainIdLike, OptionalEIP6492 } from
|
|
3
|
+
import { SequenceProvider, SingleNetworkSequenceProvider } from './provider'
|
|
4
|
+
import { SequenceClient } from './client'
|
|
5
|
+
import { commons } from '@0xsequence/core'
|
|
6
|
+
import { ChainIdLike, NetworkConfig } from '@0xsequence/network'
|
|
7
|
+
import { resolveArrayProperties } from './utils'
|
|
8
|
+
import { WalletUtils } from './utils/index'
|
|
9
|
+
import { OptionalChainIdLike, OptionalEIP6492 } from './types'
|
|
10
10
|
|
|
11
11
|
export interface ISequenceSigner extends ethers.Signer {
|
|
12
12
|
getProvider(): SequenceProvider
|
|
@@ -20,10 +20,7 @@ export interface ISequenceSigner extends ethers.Signer {
|
|
|
20
20
|
getWalletConfig(chainId?: ChainIdLike): Promise<commons.config.Config>
|
|
21
21
|
getNetworks(): Promise<NetworkConfig[]>
|
|
22
22
|
|
|
23
|
-
signMessage(
|
|
24
|
-
message: ethers.BytesLike,
|
|
25
|
-
options?: OptionalChainIdLike & OptionalEIP6492
|
|
26
|
-
): Promise<string>
|
|
23
|
+
signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise<string>
|
|
27
24
|
|
|
28
25
|
signTypedData(
|
|
29
26
|
domain: ethers.TypedDataDomain,
|
|
@@ -36,10 +33,9 @@ export interface ISequenceSigner extends ethers.Signer {
|
|
|
36
33
|
// the signer, and finally sends it to the relayer for submission to an Ethereum network.
|
|
37
34
|
// It supports any kind of transaction, including regular ethers transactions, and Sequence transactions.
|
|
38
35
|
sendTransaction(
|
|
39
|
-
transaction:
|
|
40
|
-
ethers.utils.Deferrable<ethers.providers.TransactionRequest>[]
|
|
41
|
-
ethers.utils.Deferrable<ethers.providers.TransactionRequest
|
|
42
|
-
),
|
|
36
|
+
transaction:
|
|
37
|
+
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>[]
|
|
38
|
+
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>,
|
|
43
39
|
options?: OptionalChainIdLike
|
|
44
40
|
): Promise<commons.transaction.TransactionResponse>
|
|
45
41
|
|
|
@@ -56,10 +52,10 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
56
52
|
return this.provider.utils
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
constructor
|
|
55
|
+
constructor(
|
|
60
56
|
public client: SequenceClient,
|
|
61
57
|
public provider: SequenceProvider
|
|
62
|
-
) {
|
|
58
|
+
) {}
|
|
63
59
|
|
|
64
60
|
async getAddress(): Promise<string> {
|
|
65
61
|
return this.client.getAddress()
|
|
@@ -69,7 +65,7 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
69
65
|
// it exists to maintain compatibility with ethers.Signer
|
|
70
66
|
connect(provider: ethers.providers.Provider): SequenceSigner {
|
|
71
67
|
if (!SequenceProvider.is(provider)) {
|
|
72
|
-
throw new Error(
|
|
68
|
+
throw new Error('SequenceSigner can only be connected to a SequenceProvider')
|
|
73
69
|
}
|
|
74
70
|
|
|
75
71
|
return new SequenceSigner(this.client, provider)
|
|
@@ -90,7 +86,7 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
90
86
|
if (!this.singleNetworkSigners[useChainId]) {
|
|
91
87
|
this.singleNetworkSigners[useChainId] = new SingleNetworkSequenceSigner(this.client, this.provider, useChainId)
|
|
92
88
|
}
|
|
93
|
-
|
|
89
|
+
|
|
94
90
|
return this.singleNetworkSigners[useChainId]
|
|
95
91
|
}
|
|
96
92
|
|
|
@@ -103,10 +99,7 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
103
99
|
return this.provider.toChainId(chainId) || this.client.getChainId()
|
|
104
100
|
}
|
|
105
101
|
|
|
106
|
-
async signMessage(
|
|
107
|
-
message: ethers.BytesLike,
|
|
108
|
-
options?: OptionalChainIdLike & OptionalEIP6492
|
|
109
|
-
): Promise<string> {
|
|
102
|
+
async signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise<string> {
|
|
110
103
|
const { eip6492 = true } = options || {}
|
|
111
104
|
const chainId = this.useChainId(options?.chainId)
|
|
112
105
|
return this.client.signMessage(message, { eip6492, chainId })
|
|
@@ -132,10 +125,9 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
132
125
|
}
|
|
133
126
|
|
|
134
127
|
async sendTransaction(
|
|
135
|
-
transaction:
|
|
136
|
-
ethers.utils.Deferrable<ethers.providers.TransactionRequest>[]
|
|
137
|
-
ethers.utils.Deferrable<ethers.providers.TransactionRequest
|
|
138
|
-
),
|
|
128
|
+
transaction:
|
|
129
|
+
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>[]
|
|
130
|
+
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>,
|
|
139
131
|
options?: OptionalChainIdLike
|
|
140
132
|
) {
|
|
141
133
|
const chainId = this.useChainId(options?.chainId)
|
|
@@ -144,10 +136,13 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
144
136
|
const provider = this.getProvider(chainId)
|
|
145
137
|
|
|
146
138
|
try {
|
|
147
|
-
return await ethers.utils.poll(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
139
|
+
return (await ethers.utils.poll(
|
|
140
|
+
async () => {
|
|
141
|
+
const tx = await provider.getTransaction(txHash)
|
|
142
|
+
return tx ? provider._wrapTransaction(tx, txHash) : undefined
|
|
143
|
+
},
|
|
144
|
+
{ onceBlock: provider }
|
|
145
|
+
)) as ethers.providers.TransactionResponse
|
|
151
146
|
} catch (err) {
|
|
152
147
|
err.transactionHash = txHash
|
|
153
148
|
throw err
|
|
@@ -163,10 +158,7 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
163
158
|
return this.client.getNetworks()
|
|
164
159
|
}
|
|
165
160
|
|
|
166
|
-
async getBalance(
|
|
167
|
-
blockTag?: ethers.providers.BlockTag | undefined,
|
|
168
|
-
optionals?: OptionalChainIdLike
|
|
169
|
-
): Promise<ethers.BigNumber> {
|
|
161
|
+
async getBalance(blockTag?: ethers.providers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<ethers.BigNumber> {
|
|
170
162
|
const provider = this.getProvider(optionals?.chainId)
|
|
171
163
|
return provider.getBalance(this.getAddress(), blockTag)
|
|
172
164
|
}
|
|
@@ -219,19 +211,19 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
219
211
|
populateTransaction(
|
|
220
212
|
_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>
|
|
221
213
|
): Promise<ethers.providers.TransactionRequest> {
|
|
222
|
-
throw new Error(
|
|
214
|
+
throw new Error('SequenceSigner does not support populateTransaction')
|
|
223
215
|
}
|
|
224
216
|
|
|
225
217
|
checkTransaction(
|
|
226
218
|
_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>
|
|
227
219
|
): ethers.utils.Deferrable<ethers.providers.TransactionRequest> {
|
|
228
|
-
throw new Error(
|
|
220
|
+
throw new Error('SequenceSigner does not support checkTransaction')
|
|
229
221
|
}
|
|
230
222
|
|
|
231
223
|
getTransactionCount(_blockTag?: ethers.providers.BlockTag | undefined): Promise<number> {
|
|
232
224
|
// We could try returning the sequence nonce here
|
|
233
225
|
// but we aren't sure how ethers will use this nonce
|
|
234
|
-
throw new Error(
|
|
226
|
+
throw new Error('SequenceSigner does not support getTransactionCount')
|
|
235
227
|
}
|
|
236
228
|
|
|
237
229
|
signTransaction(_transaction: ethers.utils.Deferrable<commons.transaction.Transactionish>): Promise<string> {
|
|
@@ -239,31 +231,27 @@ export class SequenceSigner implements ISequenceSigner {
|
|
|
239
231
|
// but first we need a way of serializing these signed transactions
|
|
240
232
|
// and it could lead to more trouble, because the dapp could try to send this transaction
|
|
241
233
|
// using a different provider, which would fail.
|
|
242
|
-
throw new Error(
|
|
234
|
+
throw new Error('SequenceWallet does not support signTransaction, use sendTransaction instead.')
|
|
243
235
|
}
|
|
244
236
|
|
|
245
237
|
static is(cand: any): cand is SequenceSigner {
|
|
246
|
-
return
|
|
247
|
-
cand &&
|
|
248
|
-
typeof cand === "object" &&
|
|
249
|
-
cand._isSequenceSigner === true
|
|
250
|
-
)
|
|
238
|
+
return cand && typeof cand === 'object' && cand._isSequenceSigner === true
|
|
251
239
|
}
|
|
252
240
|
}
|
|
253
241
|
|
|
254
242
|
/**
|
|
255
243
|
* This is the same provider, but it only allows a single network at a time.
|
|
256
244
|
* the network defined by the constructor is the only one that can be used.
|
|
257
|
-
*
|
|
245
|
+
*
|
|
258
246
|
* Attempting to call any method with a different network will throw an error.
|
|
259
247
|
* Attempting to change the network of this provider will throw an error.
|
|
260
|
-
*
|
|
248
|
+
*
|
|
261
249
|
* NOTICE: These networks won't support ENS unless they are the mainnet.
|
|
262
250
|
*/
|
|
263
251
|
export class SingleNetworkSequenceSigner extends SequenceSigner {
|
|
264
252
|
readonly _isSingleNetworkSequenceSigner = true
|
|
265
253
|
|
|
266
|
-
constructor
|
|
254
|
+
constructor(
|
|
267
255
|
client: SequenceClient,
|
|
268
256
|
provider: SequenceProvider,
|
|
269
257
|
public readonly chainId: ChainIdLike
|
|
@@ -302,15 +290,11 @@ export class SingleNetworkSequenceSigner extends SequenceSigner {
|
|
|
302
290
|
if (this._useChainId(chainId) !== this.chainId) {
|
|
303
291
|
throw new Error(`Unreachable code`)
|
|
304
292
|
}
|
|
305
|
-
|
|
293
|
+
|
|
306
294
|
return this
|
|
307
295
|
}
|
|
308
296
|
|
|
309
297
|
static is(cand: any): cand is SingleNetworkSequenceSigner {
|
|
310
|
-
return
|
|
311
|
-
cand &&
|
|
312
|
-
typeof cand === "object" &&
|
|
313
|
-
cand._isSingleNetworkSequenceSigner === true
|
|
314
|
-
)
|
|
298
|
+
return cand && typeof cand === 'object' && cand._isSingleNetworkSequenceSigner === true
|
|
315
299
|
}
|
|
316
300
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { commons } from '@0xsequence/core'
|
|
2
|
+
import { ethers } from 'ethers'
|
|
3
|
+
|
|
4
|
+
export function validateTransactionRequest(wallet: string, transaction: commons.transaction.Transactionish) {
|
|
5
|
+
const transactions = commons.transaction.fromTransactionish(wallet, transaction)
|
|
6
|
+
const unwound = commons.transaction.unwind(wallet, transactions)
|
|
7
|
+
unwound.forEach(transaction => validateTransaction(wallet, transaction))
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function validateTransaction(wallet: string, transaction: commons.transaction.Transaction) {
|
|
11
|
+
if (transaction.to.toLowerCase() === wallet.toLowerCase()) {
|
|
12
|
+
if (transaction.data) {
|
|
13
|
+
const data = ethers.utils.arrayify(transaction.data)
|
|
14
|
+
if (data.length >= 4) {
|
|
15
|
+
throw new Error('self calls are forbidden')
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (transaction.delegateCall) {
|
|
21
|
+
throw new Error('delegate calls are forbidden')
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -9,7 +9,10 @@ export const CHANNEL_ID = 'sequence-extension-message-handler'
|
|
|
9
9
|
export class ExtensionMessageHandler extends BaseWalletTransport {
|
|
10
10
|
private port: any
|
|
11
11
|
|
|
12
|
-
constructor(
|
|
12
|
+
constructor(
|
|
13
|
+
walletRequestHandler: WalletRequestHandler,
|
|
14
|
+
public runtime: Runtime.Static
|
|
15
|
+
) {
|
|
13
16
|
super(walletRequestHandler)
|
|
14
17
|
this._init = InitState.OK
|
|
15
18
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ProviderMessage,
|
|
3
|
-
|
|
2
|
+
ProviderMessage,
|
|
3
|
+
ProviderTransport,
|
|
4
|
+
ProviderEventTypes,
|
|
5
|
+
ProviderMessageRequest,
|
|
6
|
+
ProviderMessageResponse,
|
|
7
|
+
WalletSession,
|
|
8
|
+
OpenWalletIntent,
|
|
9
|
+
ConnectDetails
|
|
4
10
|
} from '../../types'
|
|
5
11
|
|
|
6
12
|
import { JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network'
|
|
@@ -40,19 +46,15 @@ export function isMuxTransportTemplate(obj: any): obj is MuxTransportTemplate {
|
|
|
40
46
|
return (
|
|
41
47
|
obj &&
|
|
42
48
|
typeof obj === 'object' &&
|
|
43
|
-
(
|
|
44
|
-
(obj.windowTransport && typeof obj.windowTransport === 'object') ||
|
|
49
|
+
((obj.windowTransport && typeof obj.windowTransport === 'object') ||
|
|
45
50
|
(obj.proxyTransport && typeof obj.proxyTransport === 'object') ||
|
|
46
51
|
(obj.extensionTransport && typeof obj.extensionTransport === 'object') ||
|
|
47
|
-
(obj.unrealTransport && typeof obj.unrealTransport === 'object')
|
|
48
|
-
|
|
49
|
-
(
|
|
50
|
-
// One of the transports must be enabled
|
|
51
|
-
(obj.windowTransport && obj.windowTransport.enabled) ||
|
|
52
|
+
(obj.unrealTransport && typeof obj.unrealTransport === 'object')) &&
|
|
53
|
+
// One of the transports must be enabled
|
|
54
|
+
((obj.windowTransport && obj.windowTransport.enabled) ||
|
|
52
55
|
(obj.proxyTransport && obj.proxyTransport.enabled) ||
|
|
53
56
|
(obj.extensionTransport && obj.extensionTransport.enabled) ||
|
|
54
|
-
(obj.unrealTransport && obj.unrealTransport.enabled)
|
|
55
|
-
)
|
|
57
|
+
(obj.unrealTransport && obj.unrealTransport.enabled))
|
|
56
58
|
)
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -81,7 +83,7 @@ export class MuxMessageProvider implements ProviderTransport {
|
|
|
81
83
|
if (template.extensionTransport?.enabled) {
|
|
82
84
|
const extensionMessageProvider = new ExtensionMessageProvider(template.extensionTransport.runtime)
|
|
83
85
|
muxMessageProvider.add(extensionMessageProvider)
|
|
84
|
-
|
|
86
|
+
|
|
85
87
|
// NOTE/REVIEW: see note in mux-message-provider
|
|
86
88
|
//
|
|
87
89
|
// We don't add the extensionMessageProvider here because we don't send requests to it anyways, we seem to
|
|
@@ -190,7 +192,7 @@ export class MuxMessageProvider implements ProviderTransport {
|
|
|
190
192
|
if (this.provider) {
|
|
191
193
|
return this.provider.emit(event, ...args)
|
|
192
194
|
}
|
|
193
|
-
for (let i=0; i < this.messageProviders.length; i++) {
|
|
195
|
+
for (let i = 0; i < this.messageProviders.length; i++) {
|
|
194
196
|
this.messageProviders[i].emit(event, ...args)
|
|
195
197
|
}
|
|
196
198
|
return true
|
|
@@ -244,5 +246,4 @@ export class MuxMessageProvider implements ProviderTransport {
|
|
|
244
246
|
}
|
|
245
247
|
throw new Error('impossible state, wallet must be opened first')
|
|
246
248
|
}
|
|
247
|
-
|
|
248
249
|
}
|
|
@@ -21,7 +21,6 @@ export class ProxyMessageChannelPort implements ProviderMessageTransport {
|
|
|
21
21
|
conn: ProviderMessageTransport
|
|
22
22
|
events: TypedEventEmitter<ProxyEventTypes> = new EventEmitter() as TypedEventEmitter<ProxyEventTypes>
|
|
23
23
|
|
|
24
|
-
|
|
25
24
|
// handle messages which hit this port
|
|
26
25
|
handleMessage = (message: ProviderMessage<any>): void => {
|
|
27
26
|
throw new Error('ProxyMessageChannelPort is not registered')
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import { BaseProviderTransport } from '../base-provider-transport'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
ProviderMessage, OpenState, OpenWalletIntent, EventType, InitState
|
|
5
|
-
} from '../../types'
|
|
3
|
+
import { ProviderMessage, OpenState, OpenWalletIntent, EventType, InitState } from '../../types'
|
|
6
4
|
|
|
7
5
|
import { ProxyMessageChannelPort, ProxyEventTypes } from './proxy-message-channel'
|
|
8
6
|
|
|
9
7
|
export class ProxyMessageProvider extends BaseProviderTransport {
|
|
10
|
-
|
|
11
8
|
private port: ProxyMessageChannelPort
|
|
12
|
-
|
|
9
|
+
|
|
13
10
|
constructor(port: ProxyMessageChannelPort) {
|
|
14
11
|
super()
|
|
15
12
|
this.state = OpenState.CLOSED
|
|
@@ -58,8 +55,13 @@ export class ProxyMessageProvider extends BaseProviderTransport {
|
|
|
58
55
|
const sessionId = `${performance.now()}`
|
|
59
56
|
this._sessionId = sessionId
|
|
60
57
|
this.sendMessage({
|
|
61
|
-
idx: -1,
|
|
62
|
-
|
|
58
|
+
idx: -1,
|
|
59
|
+
type: EventType.OPEN,
|
|
60
|
+
data: {
|
|
61
|
+
path,
|
|
62
|
+
intent,
|
|
63
|
+
networkId,
|
|
64
|
+
sessionId
|
|
63
65
|
}
|
|
64
66
|
})
|
|
65
67
|
}
|
|
@@ -67,7 +69,9 @@ export class ProxyMessageProvider extends BaseProviderTransport {
|
|
|
67
69
|
|
|
68
70
|
closeWallet() {
|
|
69
71
|
this.sendMessage({
|
|
70
|
-
idx: -1,
|
|
72
|
+
idx: -1,
|
|
73
|
+
type: EventType.CLOSE,
|
|
74
|
+
data: null
|
|
71
75
|
})
|
|
72
76
|
this.close()
|
|
73
77
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './unreal-message-provider'
|
|
2
|
-
export * from './unreal-message-handler'
|
|
2
|
+
export * from './unreal-message-handler'
|
|
@@ -30,7 +30,5 @@ export function overrideLogs(side: 'dapp' | 'wallet') {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function stringify(things: unknown[]): string {
|
|
33
|
-
return things
|
|
34
|
-
.map(a => (typeof a === 'object' ? (a instanceof Error ? a.message : JSON.stringify(a)) : String(a)))
|
|
35
|
-
.join(' ')
|
|
33
|
+
return things.map(a => (typeof a === 'object' ? (a instanceof Error ? a.message : JSON.stringify(a)) : String(a))).join(' ')
|
|
36
34
|
}
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { Account, AccountStatus } from '@0xsequence/account'
|
|
2
2
|
import { signAuthorization, AuthorizationOptions } from '@0xsequence/auth'
|
|
3
3
|
import { commons } from '@0xsequence/core'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
NetworkConfig,
|
|
6
|
+
JsonRpcHandler,
|
|
7
|
+
JsonRpcRequest,
|
|
8
|
+
JsonRpcResponseCallback,
|
|
9
|
+
JsonRpcResponse,
|
|
10
|
+
getChainId
|
|
11
|
+
} from '@0xsequence/network'
|
|
5
12
|
import { logger, TypedData } from '@0xsequence/utils'
|
|
6
13
|
import { BigNumber, ethers, providers } from 'ethers'
|
|
7
14
|
import { EventEmitter2 as EventEmitter } from 'eventemitter2'
|
|
8
15
|
|
|
9
16
|
import { fromExtended } from '../extended'
|
|
17
|
+
import { validateTransactionRequest } from '../transactions'
|
|
10
18
|
import {
|
|
11
19
|
ProviderMessageRequest,
|
|
12
20
|
ProviderMessageResponse,
|
|
@@ -50,11 +58,7 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
50
58
|
|
|
51
59
|
onConnectOptionsChange: ((connectOptions: ConnectOptions | undefined) => void) | undefined = undefined
|
|
52
60
|
|
|
53
|
-
constructor(
|
|
54
|
-
account: Account | null | undefined,
|
|
55
|
-
prompter: WalletUserPrompter | null,
|
|
56
|
-
networks: NetworkConfig[]
|
|
57
|
-
) {
|
|
61
|
+
constructor(account: Account | null | undefined, prompter: WalletUserPrompter | null, networks: NetworkConfig[]) {
|
|
58
62
|
this.account = account
|
|
59
63
|
this.prompter = prompter
|
|
60
64
|
this.networks = networks
|
|
@@ -95,7 +99,7 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
95
99
|
this.notifyClose()
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
|
-
|
|
102
|
+
|
|
99
103
|
if (defaultNetworkId && this.defaultChainId() !== defaultNetworkId) {
|
|
100
104
|
await this.prompter?.promptChangeNetwork(defaultNetworkId)
|
|
101
105
|
}
|
|
@@ -141,7 +145,7 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
141
145
|
|
|
142
146
|
const connectDetails: ConnectDetails = {
|
|
143
147
|
connected: true,
|
|
144
|
-
chainId: ethers.
|
|
148
|
+
chainId: ethers.utils.hexValue(chainId)
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
if (options && options.authorize) {
|
|
@@ -316,13 +320,20 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
316
320
|
const sequenceVerified = request.method === 'sequence_sign'
|
|
317
321
|
if (this.prompter === null) {
|
|
318
322
|
// prompter is null, so we'll sign from here
|
|
319
|
-
sig = await account.signMessage(
|
|
323
|
+
sig = await account.signMessage(
|
|
324
|
+
prefixedMessage,
|
|
325
|
+
chainId ?? this.defaultChainId(),
|
|
326
|
+
sequenceVerified ? 'eip6492' : 'ignore'
|
|
327
|
+
)
|
|
320
328
|
} else {
|
|
321
|
-
sig = await this.prompter.promptSignMessage(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
329
|
+
sig = await this.prompter.promptSignMessage(
|
|
330
|
+
{
|
|
331
|
+
chainId: chainId,
|
|
332
|
+
message: prefixedMessage,
|
|
333
|
+
eip6492: sequenceVerified
|
|
334
|
+
},
|
|
335
|
+
this.connectOptions
|
|
336
|
+
)
|
|
326
337
|
}
|
|
327
338
|
|
|
328
339
|
if (sig && sig.length > 0) {
|
|
@@ -361,13 +372,22 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
361
372
|
const sequenceVerified = request.method === 'sequence_signTypedData_v4'
|
|
362
373
|
if (this.prompter === null) {
|
|
363
374
|
// prompter is null, so we'll sign from here
|
|
364
|
-
sig = await account.signTypedData(
|
|
375
|
+
sig = await account.signTypedData(
|
|
376
|
+
typedData.domain,
|
|
377
|
+
typedData.types,
|
|
378
|
+
typedData.message,
|
|
379
|
+
chainId ?? this.defaultChainId(),
|
|
380
|
+
sequenceVerified ? 'eip6492' : 'ignore'
|
|
381
|
+
)
|
|
365
382
|
} else {
|
|
366
|
-
sig = await this.prompter.promptSignMessage(
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
sig = await this.prompter.promptSignMessage(
|
|
384
|
+
{
|
|
385
|
+
chainId: chainId,
|
|
386
|
+
typedData: typedData,
|
|
387
|
+
eip6492: sequenceVerified
|
|
388
|
+
},
|
|
389
|
+
this.connectOptions
|
|
390
|
+
)
|
|
371
391
|
}
|
|
372
392
|
|
|
373
393
|
if (sig && sig.length > 0) {
|
|
@@ -381,17 +401,18 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
381
401
|
|
|
382
402
|
case 'eth_sendTransaction': {
|
|
383
403
|
// https://eth.wiki/json-rpc/API#eth_sendtransaction
|
|
384
|
-
const transactionParams = fromExtended(request.params![0])
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
404
|
+
const transactionParams = fromExtended(request.params![0]).map(tx => {
|
|
405
|
+
// eth_sendTransaction uses 'gas'
|
|
406
|
+
// ethers and sequence use 'gasLimit'
|
|
407
|
+
if ('gas' in tx && tx.gasLimit === undefined) {
|
|
408
|
+
tx.gasLimit = tx.gas as any
|
|
409
|
+
delete tx.gas
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return tx
|
|
413
|
+
})
|
|
414
|
+
|
|
415
|
+
validateTransactionRequest(account.address, transactionParams)
|
|
395
416
|
|
|
396
417
|
let txnHash = ''
|
|
397
418
|
if (this.prompter === null) {
|
|
@@ -421,6 +442,8 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
421
442
|
throw new Error('sender address does not match wallet')
|
|
422
443
|
}
|
|
423
444
|
|
|
445
|
+
validateTransactionRequest(account.address, transaction)
|
|
446
|
+
|
|
424
447
|
if (this.prompter === null) {
|
|
425
448
|
// The eth_signTransaction method expects a `string` return value we instead return a `SignedTransactions` object,
|
|
426
449
|
// this can only be broadcasted using an RPC provider with support for signed Sequence transactions, like this one.
|
|
@@ -534,10 +557,12 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
534
557
|
if (chainId) {
|
|
535
558
|
response.result = [(await account.status(chainId)).onChain.config]
|
|
536
559
|
} else {
|
|
537
|
-
response.result = await Promise.all(
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
560
|
+
response.result = await Promise.all(
|
|
561
|
+
account.networks.map(async network => {
|
|
562
|
+
const status = await account.status(network.chainId)
|
|
563
|
+
return status.onChain.config
|
|
564
|
+
})
|
|
565
|
+
)
|
|
541
566
|
}
|
|
542
567
|
break
|
|
543
568
|
}
|
|
@@ -549,10 +574,12 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
549
574
|
if (chainId) {
|
|
550
575
|
response.result = [getLegacyWalletState(chainId, await account.status(chainId))]
|
|
551
576
|
} else {
|
|
552
|
-
response.result = await Promise.all(
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
577
|
+
response.result = await Promise.all(
|
|
578
|
+
account.networks.map(async network => {
|
|
579
|
+
const status = await account.status(network.chainId)
|
|
580
|
+
return getLegacyWalletState(network.chainId, status)
|
|
581
|
+
})
|
|
582
|
+
)
|
|
556
583
|
}
|
|
557
584
|
break
|
|
558
585
|
}
|
|
@@ -704,7 +731,7 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
704
731
|
walletContext: this.account.contexts,
|
|
705
732
|
accountAddress: this.account.address,
|
|
706
733
|
// The dapp shouldn't access the relayer directly, and the provider (as an object) is not serializable.
|
|
707
|
-
networks: this.account.networks.map(
|
|
734
|
+
networks: this.account.networks.map(n => ({ ...n, provider: undefined, relayer: undefined }))
|
|
708
735
|
}
|
|
709
736
|
}
|
|
710
737
|
|
|
@@ -88,9 +88,10 @@ export class WindowMessageProvider extends BaseProviderTransport {
|
|
|
88
88
|
// when connecting to the wallet, however, this will be verified and enforced
|
|
89
89
|
// on the wallet-side, so if a dapp provides the wrong origin, it will be dropped.
|
|
90
90
|
if (intent.type === 'connect') {
|
|
91
|
-
if (!intent.options)
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
if (!intent.options)
|
|
92
|
+
intent.options = {
|
|
93
|
+
app: window.location.origin
|
|
94
|
+
}
|
|
94
95
|
|
|
95
96
|
// skip setting origin host if we're in an browser extension execution context
|
|
96
97
|
// allow origin that is passed in
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { ETHAuthProof as AuthETHAuthProof } from '@0xsequence/auth'
|
|
2
2
|
import { commons } from '@0xsequence/core'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ChainIdLike,
|
|
5
|
+
JsonRpcHandler,
|
|
6
|
+
JsonRpcRequest,
|
|
7
|
+
JsonRpcResponse,
|
|
8
|
+
NetworkConfig,
|
|
9
|
+
ProviderRpcError as NetworkProviderRpcError
|
|
10
|
+
} from '@0xsequence/network'
|
|
4
11
|
import { TypedData } from '@0xsequence/utils'
|
|
5
12
|
|
|
6
13
|
export interface ProviderTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler {
|
|
@@ -185,7 +192,7 @@ export interface NetworkedConnectOptions extends ConnectOptions {
|
|
|
185
192
|
/** chainId is the chainId to connect to. If not specified, the default chainId
|
|
186
193
|
* will be used. This does not define a default chain id, it is only used for the connect
|
|
187
194
|
* authorization signature. */
|
|
188
|
-
networkId?: string | number
|
|
195
|
+
networkId?: string | number
|
|
189
196
|
}
|
|
190
197
|
|
|
191
198
|
/** Options to further customize the wallet experience. */
|
|
@@ -329,19 +336,25 @@ export interface TypedEventEmitter<Events> {
|
|
|
329
336
|
|
|
330
337
|
type Arguments<T> = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T]
|
|
331
338
|
|
|
332
|
-
export type OptionalChainIdLike =
|
|
333
|
-
|
|
334
|
-
|
|
339
|
+
export type OptionalChainIdLike =
|
|
340
|
+
| {
|
|
341
|
+
chainId?: ChainIdLike
|
|
342
|
+
}
|
|
343
|
+
| undefined
|
|
335
344
|
|
|
336
|
-
export type OptionalChainId =
|
|
337
|
-
|
|
338
|
-
|
|
345
|
+
export type OptionalChainId =
|
|
346
|
+
| {
|
|
347
|
+
chainId?: number
|
|
348
|
+
}
|
|
349
|
+
| undefined
|
|
339
350
|
|
|
340
|
-
export type OptionalEIP6492 =
|
|
341
|
-
|
|
342
|
-
|
|
351
|
+
export type OptionalEIP6492 =
|
|
352
|
+
| {
|
|
353
|
+
eip6492?: boolean
|
|
354
|
+
}
|
|
355
|
+
| undefined
|
|
343
356
|
|
|
344
357
|
// This is required by viem, it expects a provider to have an EIP-1193 compliant `request` attribute.
|
|
345
358
|
export interface EIP1193Provider {
|
|
346
|
-
request: (request: { method: string
|
|
359
|
+
request: (request: { method: string; params?: Array<any> }) => Promise<any>
|
|
347
360
|
}
|