@0xsequence/provider 0.43.34 → 1.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 +2265 -2219
- package/dist/0xsequence-provider.cjs.prod.js +2265 -2219
- package/dist/0xsequence-provider.esm.js +2521 -2477
- package/dist/declarations/src/extended.d.ts +6 -0
- package/dist/declarations/src/provider.d.ts +23 -21
- package/dist/declarations/src/transports/base-provider-transport.d.ts +3 -2
- package/dist/declarations/src/transports/base-wallet-transport.d.ts +3 -2
- package/dist/declarations/src/transports/wallet-request-handler.d.ts +19 -22
- package/dist/declarations/src/types.d.ts +10 -14
- package/dist/declarations/src/utils/index.d.ts +5 -9
- package/dist/declarations/src/utils.d.ts +9 -17
- package/dist/declarations/src/wallet.d.ts +12 -15
- package/package.json +11 -10
- package/src/extended.ts +23 -0
- package/src/provider.ts +74 -75
- package/src/transports/base-provider-transport.ts +3 -2
- package/src/transports/base-wallet-transport.ts +11 -10
- package/src/transports/wallet-request-handler.ts +251 -180
- package/src/types.ts +12 -15
- package/src/utils/index.ts +46 -51
- package/src/utils.ts +97 -96
- package/src/wallet.ts +42 -52
package/src/types.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ETHAuthProof as AuthETHAuthProof } from '@0xsequence/auth'
|
|
2
|
+
import { commons } from '@0xsequence/core'
|
|
3
|
+
import { JsonRpcHandler, JsonRpcRequest, JsonRpcResponse, NetworkConfig, ProviderRpcError as NetworkProviderRpcError } from '@0xsequence/network'
|
|
2
4
|
import { TypedData } from '@0xsequence/utils'
|
|
3
5
|
|
|
4
6
|
export interface ProviderTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler {
|
|
@@ -49,11 +51,7 @@ export type ProviderMessageResponse = ProviderMessage<JsonRpcResponse>
|
|
|
49
51
|
// which may contain the result or an error payload from the wallet.
|
|
50
52
|
export type ProviderMessageResponseCallback = (error?: ProviderRpcError, response?: ProviderMessageResponse) => void
|
|
51
53
|
|
|
52
|
-
export
|
|
53
|
-
message: string
|
|
54
|
-
code?: number
|
|
55
|
-
data?: { [key: string]: any }
|
|
56
|
-
}
|
|
54
|
+
export type ProviderRpcError = NetworkProviderRpcError
|
|
57
55
|
|
|
58
56
|
export interface ProviderMessageRequestHandler {
|
|
59
57
|
// sendMessageRequest sends a ProviderMessageRequest over the wire to the wallet.
|
|
@@ -116,7 +114,7 @@ export interface WalletEventTypes {
|
|
|
116
114
|
chainChanged: (chainIdHex: string) => void
|
|
117
115
|
|
|
118
116
|
networks: (networks: NetworkConfig[]) => void
|
|
119
|
-
walletContext: (walletContext:
|
|
117
|
+
walletContext: (walletContext: commons.context.VersionedContext) => void
|
|
120
118
|
}
|
|
121
119
|
|
|
122
120
|
export interface ProviderEventTypes extends WalletEventTypes {
|
|
@@ -156,6 +154,9 @@ export interface ConnectOptions {
|
|
|
156
154
|
/** authorize will perform an ETHAuth eip712 signing and return the proof to the dapp. */
|
|
157
155
|
authorize?: boolean
|
|
158
156
|
|
|
157
|
+
/** authorizeVersion is the version of the SDK that will validate the ETHAuth proof. */
|
|
158
|
+
authorizeVersion?: number
|
|
159
|
+
|
|
159
160
|
/** askForEmail will prompt to give permission to the dapp to access email address */
|
|
160
161
|
askForEmail?: boolean
|
|
161
162
|
|
|
@@ -263,19 +264,15 @@ export interface MessageToSign {
|
|
|
263
264
|
message?: Uint8Array
|
|
264
265
|
typedData?: TypedData
|
|
265
266
|
chainId?: number
|
|
266
|
-
}
|
|
267
267
|
|
|
268
|
-
|
|
269
|
-
// eip712 typed-data payload for ETHAuth domain as input
|
|
270
|
-
typedData: TypedData
|
|
271
|
-
|
|
272
|
-
// signature encoded in an ETHAuth proof string
|
|
273
|
-
proofString: string
|
|
268
|
+
eip6492?: boolean
|
|
274
269
|
}
|
|
275
270
|
|
|
271
|
+
export type ETHAuthProof = AuthETHAuthProof
|
|
272
|
+
|
|
276
273
|
export interface WalletSession {
|
|
277
274
|
// Wallet context
|
|
278
|
-
walletContext?:
|
|
275
|
+
walletContext?: commons.context.VersionedContext
|
|
279
276
|
|
|
280
277
|
// Account address of the wallet
|
|
281
278
|
accountAddress?: string
|
package/src/utils/index.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { BytesLike, TypedDataDomain, TypedDataField } from 'ethers'
|
|
2
|
+
import { ChainIdLike } from '@0xsequence/network'
|
|
3
3
|
import { encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils'
|
|
4
|
-
import { DecodedSignature, WalletConfig } from '@0xsequence/config'
|
|
5
4
|
import { Wallet } from '../wallet'
|
|
6
|
-
import { isValidSignature, prefixEIP191Message
|
|
7
|
-
import { isValidEIP712Signature, isValidEthSignSignature } from '@0xsequence/wallet'
|
|
5
|
+
import { isValidSignature, prefixEIP191Message } from '../utils'
|
|
8
6
|
|
|
9
7
|
export class WalletUtils {
|
|
10
8
|
private wallet: Wallet
|
|
@@ -22,7 +20,7 @@ export class WalletUtils {
|
|
|
22
20
|
|
|
23
21
|
// Sign message on the AuthChain
|
|
24
22
|
async signAuthMessage(message: BytesLike, allSigners?: boolean): Promise<string> {
|
|
25
|
-
const signer =
|
|
23
|
+
const signer = this.wallet.getSigner()
|
|
26
24
|
if (!signer) throw new Error('unable to get AuthChain signer')
|
|
27
25
|
return signer.signMessage(message, await signer.getChainId(), allSigners)
|
|
28
26
|
}
|
|
@@ -47,7 +45,7 @@ export class WalletUtils {
|
|
|
47
45
|
message: Record<string, any>,
|
|
48
46
|
allSigners?: boolean
|
|
49
47
|
): Promise<string> {
|
|
50
|
-
const signer =
|
|
48
|
+
const signer = this.wallet.getSigner()
|
|
51
49
|
if (!signer) throw new Error('unable to get AuthChain signer')
|
|
52
50
|
return signer.signTypedData(domain, types, message, await signer.getChainId(), allSigners)
|
|
53
51
|
}
|
|
@@ -57,12 +55,11 @@ export class WalletUtils {
|
|
|
57
55
|
address: string,
|
|
58
56
|
digest: Uint8Array,
|
|
59
57
|
signature: string,
|
|
60
|
-
chainId: number
|
|
61
|
-
walletContext?: WalletContext
|
|
58
|
+
chainId: number
|
|
62
59
|
): Promise<boolean> {
|
|
63
60
|
const provider = this.wallet.getProvider(chainId)
|
|
64
61
|
if (!provider) throw new Error(`unable to get provider for chainId ${chainId}`)
|
|
65
|
-
return isValidSignature(address, digest, signature, provider,
|
|
62
|
+
return isValidSignature(address, digest, signature, provider, await this.wallet.getWalletContext())
|
|
66
63
|
}
|
|
67
64
|
|
|
68
65
|
// Verify message signature
|
|
@@ -70,14 +67,13 @@ export class WalletUtils {
|
|
|
70
67
|
address: string,
|
|
71
68
|
message: string | Uint8Array,
|
|
72
69
|
signature: string,
|
|
73
|
-
chainId: number
|
|
74
|
-
walletContext?: WalletContext
|
|
70
|
+
chainId: number
|
|
75
71
|
): Promise<boolean> {
|
|
76
72
|
const provider = this.wallet.getProvider(chainId)
|
|
77
73
|
if (!provider) throw new Error(`unable to get provider for chainId ${chainId}`)
|
|
78
74
|
const prefixed = prefixEIP191Message(message)
|
|
79
75
|
const digest = encodeMessageDigest(prefixed)
|
|
80
|
-
return isValidSignature(address, digest, signature, provider,
|
|
76
|
+
return isValidSignature(address, digest, signature, provider, await this.wallet.getWalletContext())
|
|
81
77
|
}
|
|
82
78
|
|
|
83
79
|
// Verify typedData signature
|
|
@@ -85,47 +81,46 @@ export class WalletUtils {
|
|
|
85
81
|
address: string,
|
|
86
82
|
typedData: TypedData,
|
|
87
83
|
signature: string,
|
|
88
|
-
chainId: number
|
|
89
|
-
walletContext?: WalletContext
|
|
84
|
+
chainId: number
|
|
90
85
|
): Promise<boolean> {
|
|
91
|
-
return this.isValidSignature(address, encodeTypedDataDigest(typedData), signature, chainId
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Recover the WalletConfig from a signature + digest combo
|
|
95
|
-
recoverWalletConfig = async (
|
|
96
|
-
address: string,
|
|
97
|
-
digest: BytesLike,
|
|
98
|
-
signature: string | DecodedSignature,
|
|
99
|
-
chainId: BigNumberish,
|
|
100
|
-
walletContext?: WalletContext
|
|
101
|
-
): Promise<WalletConfig> => {
|
|
102
|
-
walletContext = walletContext || (await this.wallet.getWalletContext())
|
|
103
|
-
return recoverWalletConfig(address, digest, signature, chainId, walletContext)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Recover the WalletConfig from a signature of a message
|
|
107
|
-
recoverWalletConfigFromMessage = async (
|
|
108
|
-
address: string,
|
|
109
|
-
message: string | Uint8Array,
|
|
110
|
-
signature: string | DecodedSignature,
|
|
111
|
-
chainId: BigNumberish,
|
|
112
|
-
walletContext?: WalletContext
|
|
113
|
-
): Promise<WalletConfig> => {
|
|
114
|
-
walletContext = walletContext || (await this.wallet.getWalletContext())
|
|
115
|
-
return recoverWalletConfig(address, encodeMessageDigest(prefixEIP191Message(message)), signature, chainId, walletContext)
|
|
86
|
+
return this.isValidSignature(address, encodeTypedDataDigest(typedData), signature, chainId)
|
|
116
87
|
}
|
|
117
88
|
|
|
118
|
-
// Recover the WalletConfig from a signature
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
): Promise<WalletConfig> => {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
89
|
+
// // Recover the WalletConfig from a signature + digest combo
|
|
90
|
+
// recoverWalletConfig = async (
|
|
91
|
+
// address: string,
|
|
92
|
+
// digest: BytesLike,
|
|
93
|
+
// signature: string | DecodedSignature,
|
|
94
|
+
// chainId: BigNumberish,
|
|
95
|
+
// walletContext?: WalletContext
|
|
96
|
+
// ): Promise<WalletConfig> => {
|
|
97
|
+
// walletContext = walletContext || (await this.wallet.getWalletContext())
|
|
98
|
+
// return recoverWalletConfig(address, digest, signature, chainId, walletContext)
|
|
99
|
+
// }
|
|
100
|
+
|
|
101
|
+
// // Recover the WalletConfig from a signature of a message
|
|
102
|
+
// recoverWalletConfigFromMessage = async (
|
|
103
|
+
// address: string,
|
|
104
|
+
// message: string | Uint8Array,
|
|
105
|
+
// signature: string | DecodedSignature,
|
|
106
|
+
// chainId: BigNumberish,
|
|
107
|
+
// walletContext?: WalletContext
|
|
108
|
+
// ): Promise<WalletConfig> => {
|
|
109
|
+
// walletContext = walletContext || (await this.wallet.getWalletContext())
|
|
110
|
+
// return recoverWalletConfig(address, encodeMessageDigest(prefixEIP191Message(message)), signature, chainId, walletContext)
|
|
111
|
+
// }
|
|
112
|
+
|
|
113
|
+
// // Recover the WalletConfig from a signature of a typedData object
|
|
114
|
+
// recoverWalletConfigFromTypedData = async (
|
|
115
|
+
// address: string,
|
|
116
|
+
// typedData: TypedData,
|
|
117
|
+
// signature: string | DecodedSignature,
|
|
118
|
+
// chainId: BigNumberish,
|
|
119
|
+
// walletContext?: WalletContext
|
|
120
|
+
// ): Promise<WalletConfig> => {
|
|
121
|
+
// walletContext = walletContext || (await this.wallet.getWalletContext())
|
|
122
|
+
// return recoverWalletConfig(address, encodeTypedDataDigest(typedData), signature, chainId, walletContext)
|
|
123
|
+
// }
|
|
129
124
|
|
|
130
125
|
// sendTransaction()
|
|
131
126
|
// sendTransactions()
|
package/src/utils.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { ethers,
|
|
2
|
-
import { WalletContext } from '@0xsequence/network'
|
|
3
|
-
import { WalletConfig, addressOf, DecodedSignature, isConfigEqual } from '@0xsequence/config'
|
|
4
|
-
import { packMessageData, encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils'
|
|
1
|
+
import { ethers, BytesLike } from 'ethers'
|
|
5
2
|
import { Web3Provider } from './provider'
|
|
6
|
-
import { isValidSignature as _isValidSignature, recoverConfig, Signer } from '@0xsequence/wallet'
|
|
7
3
|
import { messageIsExemptFromEIP191Prefix } from './eip191exceptions'
|
|
4
|
+
import { AccountStatus } from '@0xsequence/account'
|
|
5
|
+
import { commons } from '@0xsequence/core'
|
|
8
6
|
|
|
9
7
|
const eip191prefix = ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n')
|
|
10
8
|
|
|
@@ -25,112 +23,115 @@ export const prefixEIP191Message = (message: BytesLike): Uint8Array => {
|
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
provider: Web3Provider | ethers.providers.Web3Provider | ethers.providers.Provider,
|
|
33
|
-
chainId?: number,
|
|
34
|
-
walletContext?: WalletContext
|
|
35
|
-
): Promise<boolean> => {
|
|
36
|
-
if (!chainId) {
|
|
37
|
-
chainId = (await provider.getNetwork())?.chainId
|
|
26
|
+
export const trimEIP191Prefix = (prefixedMessage: Uint8Array): Uint8Array => {
|
|
27
|
+
// If the message is not prefixed, we return the message as is.
|
|
28
|
+
if (JSON.stringify(prefixedMessage.slice(0, eip191prefix.length)) !== JSON.stringify(eip191prefix)) {
|
|
29
|
+
return prefixedMessage
|
|
38
30
|
}
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
|
|
32
|
+
// We have two parts to remove.
|
|
33
|
+
// First is the EIP-191 prefix.
|
|
34
|
+
const ethereumSignedMessagePartSlicedArray = prefixedMessage.slice(eip191prefix.length)
|
|
35
|
+
|
|
36
|
+
// Second is the digits added which represent length of the message without the prefix
|
|
37
|
+
// and we need to find the prefix that will match this.
|
|
38
|
+
// Here first we take the max prefix char length, and check if as a number it is bigger
|
|
39
|
+
// than the length of the message (since prefix is added to represent length of original message),
|
|
40
|
+
// if it is we remove 1 from char length, if not we keep the max prefix char length.
|
|
41
|
+
// As an example for the case where , if the message is 123456789, the expected prefix char is 9, with starting value 9123456789
|
|
42
|
+
// the char length of the total message with the prefix is 10, so the max prefix char length we start is 2 from [1,0], and as a number 10, it is longer
|
|
43
|
+
// than the length of the message after removing prefix (10 - 2 = 8), so we slice 1 char less, which is 9, and we get the correct prefix.
|
|
44
|
+
const maxPrefixCharLength = String(ethereumSignedMessagePartSlicedArray.length).length
|
|
45
|
+
|
|
46
|
+
let prefixCharLenght: number
|
|
47
|
+
let prefixAsNumber: number
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
prefixAsNumber = Number(ethers.utils.toUtf8String(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength)))
|
|
51
|
+
} catch {
|
|
52
|
+
prefixAsNumber = Number(ethers.utils.hexlify(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength)))
|
|
41
53
|
}
|
|
42
|
-
return _isValidSignature(address, digest, sig, provider, walletContext, chainId)
|
|
43
|
-
}
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const digest = encodeMessageDigest(prefixed)
|
|
55
|
-
return isValidSignature(address, digest, signature, provider, chainId, walletContext)
|
|
55
|
+
if (prefixAsNumber > ethereumSignedMessagePartSlicedArray.length || !Number.isInteger(prefixAsNumber)) {
|
|
56
|
+
prefixCharLenght = maxPrefixCharLength - 1
|
|
57
|
+
} else {
|
|
58
|
+
prefixCharLenght = maxPrefixCharLength
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const prefixRevertedMessage = ethereumSignedMessagePartSlicedArray.slice(prefixCharLenght)
|
|
62
|
+
|
|
63
|
+
return prefixRevertedMessage
|
|
56
64
|
}
|
|
57
65
|
|
|
58
|
-
export const
|
|
66
|
+
export const isValidSignature = async (
|
|
59
67
|
address: string,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
provider: Web3Provider | ethers.providers.Web3Provider
|
|
63
|
-
|
|
64
|
-
walletContext?: WalletContext
|
|
68
|
+
digest: Uint8Array,
|
|
69
|
+
sig: string,
|
|
70
|
+
provider: Web3Provider | ethers.providers.Web3Provider,
|
|
71
|
+
contexts: { [key: number]: commons.context.WalletContext }
|
|
65
72
|
): Promise<boolean> => {
|
|
66
|
-
|
|
73
|
+
const reader = new commons.reader.OnChainReader(provider, contexts)
|
|
74
|
+
return reader.isValidSignature(address, digest, sig)
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
export const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
77
|
+
// export const isValidMessageSignature = async (
|
|
78
|
+
// address: string,
|
|
79
|
+
// message: string | Uint8Array,
|
|
80
|
+
// signature: string,
|
|
81
|
+
// provider: Web3Provider | ethers.providers.Web3Provider,
|
|
82
|
+
// chainId?: number,
|
|
83
|
+
// walletContext?: WalletContext
|
|
84
|
+
// ): Promise<boolean> => {
|
|
85
|
+
// const prefixed = prefixEIP191Message(message)
|
|
86
|
+
// const digest = encodeMessageDigest(prefixed)
|
|
87
|
+
// return isValidSignature(address, digest, signature, provider, chainId, walletContext)
|
|
88
|
+
// }
|
|
89
|
+
|
|
90
|
+
// export const isValidTypedDataSignature = (
|
|
91
|
+
// address: string,
|
|
92
|
+
// typedData: TypedData,
|
|
93
|
+
// signature: string,
|
|
94
|
+
// provider: Web3Provider | ethers.providers.Web3Provider,
|
|
95
|
+
// chainId?: number,
|
|
96
|
+
// walletContext?: WalletContext
|
|
97
|
+
// ): Promise<boolean> => {
|
|
98
|
+
// return isValidSignature(address, encodeTypedDataDigest(typedData), signature, provider, chainId, walletContext)
|
|
99
|
+
// }
|
|
100
|
+
|
|
101
|
+
// export const recoverWalletConfig = async (
|
|
102
|
+
// address: string,
|
|
103
|
+
// digest: BytesLike,
|
|
104
|
+
// signature: string | commons.signature.UnrecoveredSignature | commons.signature.Signature<commons.config.Config>,
|
|
105
|
+
// chainId: BigNumberish,
|
|
106
|
+
// walletContext?: WalletContext
|
|
107
|
+
// ): Promise<commons.config.Config> => {
|
|
108
|
+
// const subDigest = packMessageData(address, chainId, digest)
|
|
109
|
+
// const config = await recoverConfig(subDigest, signature)
|
|
110
|
+
|
|
111
|
+
// if (walletContext) {
|
|
112
|
+
// const recoveredWalletAddress = addressOf(config, walletContext)
|
|
113
|
+
// if (config.address && config.address !== recoveredWalletAddress) {
|
|
114
|
+
// throw new Error('recovered address does not match the WalletConfig address, check the WalletContext')
|
|
115
|
+
// } else {
|
|
116
|
+
// config.address = recoveredWalletAddress
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
119
|
+
|
|
120
|
+
// return config
|
|
121
|
+
// }
|
|
90
122
|
|
|
91
123
|
export const isBrowserExtension = (): boolean =>
|
|
92
124
|
window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:'
|
|
93
125
|
|
|
94
126
|
export const isUnityPlugin = (): boolean => !!navigator.userAgent.match(/UnitySequence/i)
|
|
95
127
|
|
|
96
|
-
/**
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
export const isWalletUpToDate = async (signer: Signer, chainId: number): Promise<boolean> => {
|
|
104
|
-
const walletState = await signer.getWalletState()
|
|
105
|
-
const networks = await signer.getNetworks()
|
|
106
|
-
|
|
107
|
-
const walletStateForRequiredChain = walletState.find(state => state.chainId === chainId)
|
|
108
|
-
if (!walletStateForRequiredChain) {
|
|
109
|
-
throw new Error(`WalletRequestHandler: could not find wallet state for chainId ${chainId}`)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const isDeployed = walletStateForRequiredChain.deployed
|
|
113
|
-
|
|
114
|
-
if (!networks) {
|
|
115
|
-
throw new Error(`isWalletUpToDate util: could not get networks from signer`)
|
|
116
|
-
}
|
|
117
|
-
const authChain = networks.find(network => network.isAuthChain)
|
|
118
|
-
if (!authChain) {
|
|
119
|
-
throw new Error(`isWalletUpToDate util: could not get auth chain network information`)
|
|
120
|
-
}
|
|
121
|
-
const authChainId = authChain.chainId
|
|
122
|
-
const authChainConfig = walletState.find(state => state.chainId === authChainId)?.config
|
|
123
|
-
if (!authChainConfig) {
|
|
124
|
-
throw new Error(`isWalletUpToDate util: could not get auth chain config`)
|
|
125
|
-
}
|
|
126
|
-
const requiredChainConfig = walletStateForRequiredChain.config
|
|
127
|
-
if (!requiredChainConfig) {
|
|
128
|
-
throw new Error(`isWalletUpToDate util: could not get config for chainId ${chainId}`)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const isUpToDate = isConfigEqual(authChainConfig, requiredChainConfig)
|
|
132
|
-
|
|
133
|
-
return isDeployed && isUpToDate
|
|
128
|
+
// /**
|
|
129
|
+
// * Returns the status of a signer's wallet on given chain by checking wallet deployment and config status
|
|
130
|
+
// *
|
|
131
|
+
// * @param {Status} of the wallet
|
|
132
|
+
// */
|
|
133
|
+
export const isWalletUpToDate = (status: AccountStatus): boolean => {
|
|
134
|
+
return status.onChain.deployed && status.fullyMigrated
|
|
134
135
|
}
|
|
135
136
|
|
|
136
137
|
export interface ItemStore {
|
package/src/wallet.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NetworkConfig,
|
|
3
|
-
WalletContext,
|
|
4
3
|
ChainIdLike,
|
|
5
4
|
JsonRpcSender,
|
|
6
5
|
JsonRpcRouter,
|
|
@@ -16,10 +15,10 @@ import {
|
|
|
16
15
|
findNetworkConfig,
|
|
17
16
|
updateNetworkConfig,
|
|
18
17
|
ensureValidNetworks,
|
|
19
|
-
sortNetworks
|
|
18
|
+
sortNetworks,
|
|
19
|
+
findSupportedNetwork
|
|
20
20
|
} from '@0xsequence/network'
|
|
21
|
-
import {
|
|
22
|
-
import { logger } from '@0xsequence/utils'
|
|
21
|
+
import { getDefaultConnectionInfo, logger } from '@0xsequence/utils'
|
|
23
22
|
import { Web3Provider, Web3Signer } from './provider'
|
|
24
23
|
import {
|
|
25
24
|
MuxMessageProvider,
|
|
@@ -35,6 +34,10 @@ import { LocalStore, ItemStore, LocalStorage } from './utils'
|
|
|
35
34
|
import { WalletUtils } from './utils/index'
|
|
36
35
|
|
|
37
36
|
import { Runtime } from 'webextension-polyfill'
|
|
37
|
+
import { commons } from '@0xsequence/core'
|
|
38
|
+
import { AccountStatus } from '@0xsequence/account'
|
|
39
|
+
|
|
40
|
+
export const SESSION_LOCALSTORE_KEY = '@sequence.session'
|
|
38
41
|
|
|
39
42
|
export interface WalletProvider {
|
|
40
43
|
connect(options?: ConnectOptions): Promise<ConnectDetails>
|
|
@@ -46,7 +49,6 @@ export interface WalletProvider {
|
|
|
46
49
|
getAddress(): Promise<string>
|
|
47
50
|
getNetworks(chainId?: ChainIdLike): Promise<NetworkConfig[]>
|
|
48
51
|
getChainId(): Promise<number>
|
|
49
|
-
getAuthChainId(): Promise<number>
|
|
50
52
|
|
|
51
53
|
isOpened(): boolean
|
|
52
54
|
openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number): Promise<boolean>
|
|
@@ -55,9 +57,9 @@ export interface WalletProvider {
|
|
|
55
57
|
getProvider(chainId?: ChainIdLike): Web3Provider | undefined
|
|
56
58
|
getSigner(chainId?: ChainIdLike): Web3Signer
|
|
57
59
|
|
|
58
|
-
getWalletContext(): Promise<
|
|
59
|
-
getWalletConfig(chainId?: ChainIdLike): Promise<
|
|
60
|
-
getWalletState(chainId?: ChainIdLike): Promise<
|
|
60
|
+
getWalletContext(): Promise<commons.context.VersionedContext>
|
|
61
|
+
getWalletConfig(chainId?: ChainIdLike): Promise<commons.config.Config>
|
|
62
|
+
getWalletState(chainId?: ChainIdLike): Promise<AccountStatus>
|
|
61
63
|
isDeployed(chainId?: ChainIdLike): Promise<boolean>
|
|
62
64
|
|
|
63
65
|
getProviderConfig(): ProviderConfig
|
|
@@ -177,7 +179,7 @@ export class Wallet implements WalletProvider {
|
|
|
177
179
|
if (!this.networks || this.networks.length === 0) return 0
|
|
178
180
|
|
|
179
181
|
// return the default chainId as we're connected
|
|
180
|
-
return this.networks
|
|
182
|
+
return findNetworkConfig(this.networks, this.config.defaultNetworkId!)!.chainId
|
|
181
183
|
})
|
|
182
184
|
|
|
183
185
|
// Provider proxy to support middleware stack of logging, caching and read-only rpc calls
|
|
@@ -200,7 +202,11 @@ export class Wallet implements WalletProvider {
|
|
|
200
202
|
this.transport.messageProvider
|
|
201
203
|
)
|
|
202
204
|
|
|
203
|
-
this
|
|
205
|
+
// TODO: Move finding this config to upper in the stack
|
|
206
|
+
this.transport.provider = new Web3Provider(
|
|
207
|
+
this.transport.router,
|
|
208
|
+
findSupportedNetwork(this.config.defaultNetworkId!)?.chainId
|
|
209
|
+
)
|
|
204
210
|
|
|
205
211
|
// NOTE: we don't listen on 'connect' even here as we handle it within connect() method
|
|
206
212
|
// in more synchronous flow.
|
|
@@ -244,13 +250,13 @@ export class Wallet implements WalletProvider {
|
|
|
244
250
|
})
|
|
245
251
|
|
|
246
252
|
// below will update the wallet context automatically
|
|
247
|
-
this.transport.messageProvider.on('walletContext', (walletContext:
|
|
253
|
+
this.transport.messageProvider.on('walletContext', (walletContext: commons.context.VersionedContext) => {
|
|
248
254
|
this.useSession({ walletContext: walletContext }, true)
|
|
249
255
|
})
|
|
250
256
|
}
|
|
251
257
|
|
|
252
258
|
loadSession = async (preferredNetwork?: string | number): Promise<WalletSession | undefined> => {
|
|
253
|
-
const data = await LocalStorage.getInstance().getItem(
|
|
259
|
+
const data = await LocalStorage.getInstance().getItem(SESSION_LOCALSTORE_KEY)
|
|
254
260
|
if (!data || data === '') {
|
|
255
261
|
return undefined
|
|
256
262
|
}
|
|
@@ -282,6 +288,11 @@ export class Wallet implements WalletProvider {
|
|
|
282
288
|
}
|
|
283
289
|
|
|
284
290
|
connect = async (options?: ConnectOptions): Promise<ConnectDetails> => {
|
|
291
|
+
if (options && options?.authorizeVersion === undefined) {
|
|
292
|
+
// Populate default authorize version if not provided
|
|
293
|
+
options.authorizeVersion = 2
|
|
294
|
+
}
|
|
295
|
+
|
|
285
296
|
if (options?.refresh === true) {
|
|
286
297
|
this.disconnect()
|
|
287
298
|
}
|
|
@@ -301,8 +312,13 @@ export class Wallet implements WalletProvider {
|
|
|
301
312
|
}
|
|
302
313
|
|
|
303
314
|
if (options) {
|
|
304
|
-
if (options.authorize
|
|
305
|
-
|
|
315
|
+
if (options.authorize) {
|
|
316
|
+
if (!options.app) {
|
|
317
|
+
throw new Error(`connecting with 'authorize' option also requires 'app' to be set`)
|
|
318
|
+
}
|
|
319
|
+
if (options.authorizeVersion === undefined) {
|
|
320
|
+
options.authorizeVersion = 2
|
|
321
|
+
}
|
|
306
322
|
}
|
|
307
323
|
}
|
|
308
324
|
|
|
@@ -366,11 +382,11 @@ export class Wallet implements WalletProvider {
|
|
|
366
382
|
return this.connect({ ...options, authorize: true })
|
|
367
383
|
}
|
|
368
384
|
|
|
369
|
-
disconnect(): void {
|
|
385
|
+
disconnect(): Promise<void> {
|
|
370
386
|
if (this.isOpened()) {
|
|
371
387
|
this.closeWallet()
|
|
372
388
|
}
|
|
373
|
-
this.clearSession()
|
|
389
|
+
return this.clearSession()
|
|
374
390
|
}
|
|
375
391
|
|
|
376
392
|
// TODO: add switchNetwork(network: string | number) which will call wallet_switchEthereumChain
|
|
@@ -429,7 +445,7 @@ export class Wallet implements WalletProvider {
|
|
|
429
445
|
throw new Error('networks have not been set by session. connect first.')
|
|
430
446
|
}
|
|
431
447
|
|
|
432
|
-
const network = this.networks
|
|
448
|
+
const network = findNetworkConfig(this.networks, this.config.defaultNetworkId!)
|
|
433
449
|
|
|
434
450
|
if (!network) {
|
|
435
451
|
throw new Error('networks must have a default chain specified')
|
|
@@ -438,20 +454,6 @@ export class Wallet implements WalletProvider {
|
|
|
438
454
|
return network.chainId
|
|
439
455
|
}
|
|
440
456
|
|
|
441
|
-
getAuthChainId = async (): Promise<number> => {
|
|
442
|
-
if (!this.networks || this.networks.length < 1) {
|
|
443
|
-
throw new Error('networks have not been set by session. connect first.')
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const network = this.networks.find(network => network.isAuthChain)
|
|
447
|
-
|
|
448
|
-
if (!network) {
|
|
449
|
-
throw new Error('networks must have an auth chain specified')
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
return network.chainId
|
|
453
|
-
}
|
|
454
|
-
|
|
455
457
|
openWallet = async (path?: string, intent?: OpenWalletIntent, networkId?: string | number): Promise<boolean> => {
|
|
456
458
|
if (intent?.type !== 'connect' && !this.isConnected()) {
|
|
457
459
|
throw new Error('connect first')
|
|
@@ -486,7 +488,7 @@ export class Wallet implements WalletProvider {
|
|
|
486
488
|
}
|
|
487
489
|
}
|
|
488
490
|
|
|
489
|
-
let network: NetworkConfig | undefined = this.networks
|
|
491
|
+
let network: NetworkConfig | undefined = findNetworkConfig(this.networks, this.config.defaultNetworkId!)!
|
|
490
492
|
if (chainId) {
|
|
491
493
|
network = findNetworkConfig(this.networks, chainId)
|
|
492
494
|
if (!network) {
|
|
@@ -503,7 +505,7 @@ export class Wallet implements WalletProvider {
|
|
|
503
505
|
let provider: Web3Provider
|
|
504
506
|
|
|
505
507
|
// network.provider may be set by the ProviderConfig override
|
|
506
|
-
const rpcProvider =
|
|
508
|
+
const rpcProvider = new providers.JsonRpcProvider(getDefaultConnectionInfo(network.rpcUrl), network.chainId)
|
|
507
509
|
|
|
508
510
|
if (network.isDefaultChain) {
|
|
509
511
|
// communicating with defaultChain will prioritize the wallet message transport
|
|
@@ -544,14 +546,6 @@ export class Wallet implements WalletProvider {
|
|
|
544
546
|
return provider
|
|
545
547
|
}
|
|
546
548
|
|
|
547
|
-
async getAuthProvider(): Promise<Web3Provider> {
|
|
548
|
-
return this.getProvider((await this.getAuthNetwork()).chainId)!
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
async getAuthNetwork(): Promise<NetworkConfig> {
|
|
552
|
-
return (await this.getNetworks()).find(n => n.isAuthChain)!
|
|
553
|
-
}
|
|
554
|
-
|
|
555
549
|
getAllProviders(): { [chainId: number]: Web3Provider } {
|
|
556
550
|
return this.providers
|
|
557
551
|
}
|
|
@@ -560,19 +554,15 @@ export class Wallet implements WalletProvider {
|
|
|
560
554
|
return this.getProvider(chainId)!.getSigner()
|
|
561
555
|
}
|
|
562
556
|
|
|
563
|
-
|
|
564
|
-
return (await this.getAuthProvider()).getSigner()
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
getWalletConfig(chainId?: ChainIdLike): Promise<WalletConfig[]> {
|
|
557
|
+
getWalletConfig(chainId?: ChainIdLike): Promise<commons.config.Config> {
|
|
568
558
|
return this.getSigner().getWalletConfig(chainId)
|
|
569
559
|
}
|
|
570
560
|
|
|
571
|
-
getWalletState(chainId?: ChainIdLike): Promise<
|
|
561
|
+
getWalletState(chainId?: ChainIdLike): Promise<AccountStatus> {
|
|
572
562
|
return this.getSigner().getWalletState(chainId)
|
|
573
563
|
}
|
|
574
564
|
|
|
575
|
-
getWalletContext(): Promise<
|
|
565
|
+
getWalletContext(): Promise<commons.context.VersionedContext> {
|
|
576
566
|
return this.getSigner().getWalletContext()
|
|
577
567
|
}
|
|
578
568
|
|
|
@@ -596,7 +586,7 @@ export class Wallet implements WalletProvider {
|
|
|
596
586
|
private saveSession = async (session: WalletSession) => {
|
|
597
587
|
logger.debug('wallet provider: saving session')
|
|
598
588
|
const data = JSON.stringify(session)
|
|
599
|
-
await LocalStorage.getInstance().setItem(
|
|
589
|
+
await LocalStorage.getInstance().setItem(SESSION_LOCALSTORE_KEY, data)
|
|
600
590
|
}
|
|
601
591
|
|
|
602
592
|
private useSession = async (session: WalletSession, autoSave: boolean = true) => {
|
|
@@ -678,9 +668,9 @@ export class Wallet implements WalletProvider {
|
|
|
678
668
|
}
|
|
679
669
|
}
|
|
680
670
|
|
|
681
|
-
private clearSession(): void {
|
|
671
|
+
private async clearSession(): Promise<void> {
|
|
682
672
|
logger.debug('wallet provider: clearing session')
|
|
683
|
-
LocalStorage.getInstance().removeItem(
|
|
673
|
+
await LocalStorage.getInstance().removeItem(SESSION_LOCALSTORE_KEY)
|
|
684
674
|
this.session = undefined
|
|
685
675
|
this.networks = []
|
|
686
676
|
this.providers = {}
|
|
@@ -741,7 +731,7 @@ export interface ProviderConfig {
|
|
|
741
731
|
// WalletContext used the one returned by the wallet app upon login.
|
|
742
732
|
//
|
|
743
733
|
// NOTE: do not use this option unless you know what you're doing
|
|
744
|
-
walletContext?:
|
|
734
|
+
walletContext?: commons.context.VersionedContext
|
|
745
735
|
}
|
|
746
736
|
|
|
747
737
|
export const DefaultProviderConfig: ProviderConfig = {
|