@0xsequence/provider 1.0.5 → 1.1.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.
Files changed (31) hide show
  1. package/dist/0xsequence-provider.cjs.dev.js +1742 -1678
  2. package/dist/0xsequence-provider.cjs.prod.js +1742 -1678
  3. package/dist/0xsequence-provider.esm.js +1735 -1676
  4. package/dist/declarations/src/client.d.ts +74 -0
  5. package/dist/declarations/src/index.d.ts +3 -1
  6. package/dist/declarations/src/init.d.ts +25 -0
  7. package/dist/declarations/src/provider.d.ts +127 -63
  8. package/dist/declarations/src/signer.d.ts +87 -0
  9. package/dist/declarations/src/transports/mux-transport/mux-message-provider.d.ts +21 -0
  10. package/dist/declarations/src/transports/wallet-request-handler.d.ts +0 -1
  11. package/dist/declarations/src/types.d.ts +25 -9
  12. package/dist/declarations/src/utils/index.d.ts +10 -7
  13. package/dist/declarations/src/utils.d.ts +21 -15
  14. package/package.json +19 -12
  15. package/src/client.ts +423 -0
  16. package/src/extended.ts +4 -0
  17. package/src/index.ts +3 -1
  18. package/src/init.ts +134 -0
  19. package/src/provider.ts +447 -424
  20. package/src/signer.ts +316 -0
  21. package/src/transports/base-wallet-transport.ts +3 -8
  22. package/src/transports/mux-transport/mux-message-provider.ts +86 -2
  23. package/src/transports/proxy-transport/proxy-message-provider.ts +1 -1
  24. package/src/transports/wallet-request-handler.ts +3 -33
  25. package/src/transports/window-transport/window-message-provider.ts +4 -2
  26. package/src/types.ts +41 -10
  27. package/src/utils/index.ts +16 -76
  28. package/src/utils.ts +81 -51
  29. package/dist/declarations/src/extended.d.ts +0 -6
  30. package/dist/declarations/src/wallet.d.ts +0 -105
  31. package/src/wallet.ts +0 -770
@@ -1,28 +1,24 @@
1
1
  import { BytesLike, TypedDataDomain, TypedDataField } from 'ethers'
2
2
  import { ChainIdLike } from '@0xsequence/network'
3
3
  import { encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils'
4
- import { Wallet } from '../wallet'
5
4
  import { isValidSignature, prefixEIP191Message } from '../utils'
5
+ import { SequenceSigner, SingleNetworkSequenceSigner } from '../signer'
6
6
 
7
+ /**
8
+ * This class is redundant with the SequenceSigner class, but it is here for now to
9
+ * maintain compatibility with the old wallet API. Eventually we should move these
10
+ * methods to the SequenceSigner class and deprecate this class.
11
+ */
7
12
  export class WalletUtils {
8
- private wallet: Wallet
9
-
10
- constructor(walletProvider: Wallet) {
11
- this.wallet = walletProvider
13
+ constructor(public signer: SequenceSigner) {
14
+ if (SingleNetworkSequenceSigner.is(signer)) {
15
+ throw new Error('WalletUtils does not support SingleNetworkSequenceSigner')
16
+ }
12
17
  }
13
18
 
14
19
  // Sign message on a specified chain, or DefaultChain by default
15
- signMessage(message: BytesLike, chainId?: ChainIdLike, allSigners?: boolean): Promise<string> {
16
- const signer = this.wallet.getSigner()
17
- if (!signer) throw new Error('unable to get signer')
18
- return signer.signMessage(message, chainId, allSigners)
19
- }
20
-
21
- // Sign message on the AuthChain
22
- async signAuthMessage(message: BytesLike, allSigners?: boolean): Promise<string> {
23
- const signer = this.wallet.getSigner()
24
- if (!signer) throw new Error('unable to get AuthChain signer')
25
- return signer.signMessage(message, await signer.getChainId(), allSigners)
20
+ signMessage(message: BytesLike, chainId?: ChainIdLike, eip6492?: boolean): Promise<string> {
21
+ return this.signer.signMessage(message, { chainId, eip6492 })
26
22
  }
27
23
 
28
24
  // Sign EIP-712 TypedData on a specified chain, or DefaultChain by default
@@ -31,23 +27,9 @@ export class WalletUtils {
31
27
  types: Record<string, Array<TypedDataField>>,
32
28
  message: Record<string, any>,
33
29
  chainId?: ChainIdLike,
34
- allSigners?: boolean
35
- ): Promise<string> {
36
- const signer = this.wallet.getSigner()
37
- if (!signer) throw new Error('unable to get signer')
38
- return signer.signTypedData(domain, types, message, chainId, allSigners)
39
- }
40
-
41
- // Sign EIP-712 TypedData on the AuthChain
42
- async signAuthTypedData(
43
- domain: TypedDataDomain,
44
- types: Record<string, Array<TypedDataField>>,
45
- message: Record<string, any>,
46
- allSigners?: boolean
30
+ eip6492?: boolean
47
31
  ): Promise<string> {
48
- const signer = this.wallet.getSigner()
49
- if (!signer) throw new Error('unable to get AuthChain signer')
50
- return signer.signTypedData(domain, types, message, await signer.getChainId(), allSigners)
32
+ return this.signer.signTypedData(domain, types, message, { chainId, eip6492 })
51
33
  }
52
34
 
53
35
  // Verify signature of a digest, one of a message, typedData or other
@@ -57,9 +39,7 @@ export class WalletUtils {
57
39
  signature: string,
58
40
  chainId: number
59
41
  ): Promise<boolean> {
60
- const provider = this.wallet.getProvider(chainId)
61
- if (!provider) throw new Error(`unable to get provider for chainId ${chainId}`)
62
- return isValidSignature(address, digest, signature, provider)
42
+ return isValidSignature(address, digest, signature, this.signer.getProvider(chainId))
63
43
  }
64
44
 
65
45
  // Verify message signature
@@ -69,8 +49,7 @@ export class WalletUtils {
69
49
  signature: string,
70
50
  chainId: number
71
51
  ): Promise<boolean> {
72
- const provider = this.wallet.getProvider(chainId)
73
- if (!provider) throw new Error(`unable to get provider for chainId ${chainId}`)
52
+ const provider = this.signer.getProvider(chainId)
74
53
  const prefixed = prefixEIP191Message(message)
75
54
  const digest = encodeMessageDigest(prefixed)
76
55
  return isValidSignature(address, digest, signature, provider)
@@ -86,42 +65,6 @@ export class WalletUtils {
86
65
  return this.isValidSignature(address, encodeTypedDataDigest(typedData), signature, chainId)
87
66
  }
88
67
 
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
- // }
124
-
125
68
  // sendTransaction()
126
69
  // sendTransactions()
127
70
 
@@ -136,9 +79,6 @@ export class WalletUtils {
136
79
  // getLogs()
137
80
  // // ..
138
81
 
139
- // isWalletDeployed()
140
- // deployWallet()
141
-
142
82
  // validateSignature()
143
83
  // recoverWalletConfig()
144
84
  // recoverAddress()
package/src/utils.ts CHANGED
@@ -111,73 +111,103 @@ export const isWalletUpToDate = (status: AccountStatus): boolean => {
111
111
  }
112
112
 
113
113
  export interface ItemStore {
114
- getItem(key: string): Promise<string | null>
115
- setItem(key: string, value: string): Promise<void>
116
- removeItem(key: string): Promise<void>
114
+ getItem(key: string): string | null
115
+ setItem(key: string, value: string): void
116
+
117
+ removeItem(key: string): void
118
+
119
+ onItemChange(key: string, cb: (value: string | null) => void): () => void
117
120
  }
118
121
 
119
- export class LocalStorage {
120
- private static _instance: ItemStore
121
-
122
- private constructor() {}
123
-
124
- static getInstance(): ItemStore {
125
- if (typeof window === 'object') {
126
- if (!LocalStorage._instance) {
127
- LocalStorage._instance = {
128
- getItem: (key: string) => Promise.resolve(window.localStorage.getItem(key)),
129
- setItem: (key: string, value: string) => Promise.resolve(window.localStorage.setItem(key, value)),
130
- removeItem: (key: string) => Promise.resolve(window.localStorage.removeItem(key))
131
- }
132
- }
133
- } else {
134
- // noop local storage if window is not defined
135
- // TODO: perhaps add an in-memory local storage if we need?
136
- if (!LocalStorage._instance) {
137
- LocalStorage._instance = {
138
- getItem: (key: string) => Promise.resolve(null),
139
- setItem: (key: string, value: string) => Promise.resolve(),
140
- removeItem: (key: string) => Promise.resolve()
141
- }
142
- }
143
- }
144
- return this._instance
145
- }
122
+ export class MemoryItemStore implements ItemStore {
123
+ private callbacks: { key: string, cb: (value: string | null) => void }[] = []
124
+ private store: Record<string, string> = {}
146
125
 
147
- static use(instance: ItemStore) {
148
- LocalStorage._instance = instance
126
+ getItem(key: string): string | null {
127
+ return this.store[key] || null
149
128
  }
150
- }
151
129
 
152
- // window.localstorage helper
153
- export class LocalStore<T extends Object = string> {
154
- readonly key: string
130
+ setItem(key: string, value: string): void {
131
+ this.store[key] = value
132
+ this.callbacks.filter((c) => c.key === key).forEach((c) => c.cb(value))
133
+ }
155
134
 
156
- constructor(key: string, public def?: T) {
157
- this.key = key
135
+ removeItem(key: string): void {
136
+ delete this.store[key]
158
137
  }
159
138
 
160
- async get(): Promise<T | undefined> {
161
- const val = await LocalStorage.getInstance().getItem(this.key)
139
+ onItemChange(key: string, cb: (value: string | null) => void): () => void {
140
+ this.callbacks.push({ key, cb })
162
141
 
163
- if (val === null) {
164
- return this.def
142
+ return () => {
143
+ this.callbacks = this.callbacks.filter((c) => c.cb !== cb)
165
144
  }
145
+ }
146
+ }
147
+
148
+ export class LocalStorage implements ItemStore {
149
+ private callbacks: { key: string, cb: (value: string | null) => void }[] = []
150
+
151
+ static isAvailable(): boolean {
152
+ return typeof window === 'object' && typeof window.localStorage === 'object'
153
+ }
166
154
 
167
- try {
168
- return JSON.parse(val)
169
- } catch (err) {
170
- console.error(err)
155
+ constructor() {
156
+ if (!LocalStorage.isAvailable()) {
157
+ throw new Error('LocalStorage is not available')
171
158
  }
172
159
 
173
- return
160
+ window.addEventListener('storage', (e) => {
161
+ const { key } = e
162
+ const cb = this.callbacks.filter((c) => c.key === key)
163
+ cb.forEach((c) => c.cb(this.getItem(key!)))
164
+ })
174
165
  }
175
166
 
176
- set(val: T | undefined) {
177
- val ? LocalStorage.getInstance().setItem(this.key, JSON.stringify(val)) : LocalStorage.getInstance().removeItem(this.key)
167
+ getItem(key: string): string | null {
168
+ return window.localStorage.getItem(key)
178
169
  }
179
170
 
180
- del() {
181
- LocalStorage.getInstance().removeItem(this.key)
171
+ setItem(key: string, value: string): void {
172
+ window.localStorage.setItem(key, value)
173
+
174
+ // Trigger callbacks
175
+ // NOTICE: the event is not triggered on the same window
176
+ this.callbacks.filter((c) => c.key === key).forEach((c) => c.cb(value))
182
177
  }
178
+
179
+ removeItem(key: string): void {
180
+ window.localStorage.removeItem(key)
181
+
182
+ // Trigger callbacks
183
+ // NOTICE: the event is not triggered on the same window
184
+ this.callbacks.filter((c) => c.key === key).forEach((c) => c.cb(null))
185
+ }
186
+
187
+ onItemChange(key: string, cb: (value: string | null) => void): () => void {
188
+ this.callbacks.push({ key, cb })
189
+
190
+ return () => {
191
+ this.callbacks = this.callbacks.filter((c) => c.cb !== cb)
192
+ }
193
+ }
194
+ }
195
+
196
+ export function useBestStore(): ItemStore {
197
+ if (LocalStorage.isAvailable()) {
198
+ return new LocalStorage()
199
+ }
200
+
201
+ return new MemoryItemStore()
202
+ }
203
+
204
+ export async function resolveArrayProperties<T>(
205
+ object: Readonly<ethers.utils.Deferrable<T>> | Readonly<ethers.utils.Deferrable<T>>[]
206
+ ): Promise<T> {
207
+ if (Array.isArray(object)) {
208
+ // T must include array type
209
+ return Promise.all(object.map((o) => ethers.utils.resolveProperties(o))) as any
210
+ }
211
+
212
+ return ethers.utils.resolveProperties(object)
183
213
  }
@@ -1,6 +0,0 @@
1
- import { ethers } from "ethers";
2
- export type ExtendedTransactionRequest = ethers.providers.TransactionRequest & {
3
- auxiliary?: ethers.providers.TransactionRequest[];
4
- };
5
- export declare function toExtended(transactions: ethers.providers.TransactionRequest[]): ExtendedTransactionRequest;
6
- export declare function fromExtended(transaction: ExtendedTransactionRequest): ethers.providers.TransactionRequest[];
@@ -1,105 +0,0 @@
1
- import { NetworkConfig, ChainIdLike } from '@0xsequence/network';
2
- import { Web3Provider, Web3Signer } from "./provider.js";
3
- import { ProxyMessageChannelPort } from "./transports/index.js";
4
- import { WalletSession, ProviderEventTypes, ConnectOptions, OpenWalletIntent, ConnectDetails } from "./types.js";
5
- import { ItemStore } from "./utils.js";
6
- import { WalletUtils } from "./utils/index.js";
7
- import { Runtime } from 'webextension-polyfill';
8
- import { commons } from '@0xsequence/core';
9
- import { AccountStatus } from '@0xsequence/account';
10
- export declare const SESSION_LOCALSTORE_KEY = "@sequence.session";
11
- export interface WalletProvider {
12
- connect(options?: ConnectOptions): Promise<ConnectDetails>;
13
- disconnect(): void;
14
- isConnected(): boolean;
15
- getSession(): WalletSession | undefined;
16
- getAddress(): Promise<string>;
17
- getNetworks(chainId?: ChainIdLike): Promise<NetworkConfig[]>;
18
- getChainId(): Promise<number>;
19
- isOpened(): boolean;
20
- openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number): Promise<boolean>;
21
- closeWallet(): void;
22
- getProvider(chainId?: ChainIdLike): Web3Provider | undefined;
23
- getSigner(chainId?: ChainIdLike): Web3Signer;
24
- getWalletContext(): Promise<commons.context.VersionedContext>;
25
- getWalletConfig(chainId?: ChainIdLike): Promise<commons.config.Config>;
26
- getWalletState(chainId?: ChainIdLike): Promise<AccountStatus>;
27
- isDeployed(chainId?: ChainIdLike): Promise<boolean>;
28
- getProviderConfig(): ProviderConfig;
29
- on<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void;
30
- once<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void;
31
- utils: WalletUtils;
32
- }
33
- export declare class Wallet implements WalletProvider {
34
- utils: WalletUtils;
35
- private config;
36
- private session?;
37
- private connectedSites;
38
- private transport;
39
- private networks;
40
- private providers;
41
- constructor(network?: string | number, config?: Partial<ProviderConfig>);
42
- private init;
43
- loadSession: (preferredNetwork?: string | number) => Promise<WalletSession | undefined>;
44
- connect: (options?: ConnectOptions) => Promise<ConnectDetails>;
45
- addConnectedSite(origin: string | undefined): Promise<void>;
46
- removeConnectedSite(origin: string): Promise<void>;
47
- getConnectedSites(): Promise<string[] | undefined>;
48
- isSiteConnected(origin: string | undefined): Promise<boolean>;
49
- authorize: (options?: ConnectOptions) => Promise<ConnectDetails>;
50
- disconnect(): Promise<void>;
51
- getProviderConfig(): ProviderConfig;
52
- isOpened(): boolean;
53
- isConnected(): boolean;
54
- getSession: () => WalletSession | undefined;
55
- getAddress: () => Promise<string>;
56
- getNetworks: (chainId?: ChainIdLike) => Promise<NetworkConfig[]>;
57
- getChainId: () => Promise<number>;
58
- openWallet: (path?: string, intent?: OpenWalletIntent, networkId?: string | number) => Promise<boolean>;
59
- closeWallet: () => void;
60
- getProvider(chainId?: ChainIdLike): Web3Provider | undefined;
61
- getAllProviders(): {
62
- [chainId: number]: Web3Provider;
63
- };
64
- getSigner(chainId?: ChainIdLike): Web3Signer;
65
- getWalletConfig(chainId?: ChainIdLike): Promise<commons.config.Config>;
66
- getWalletState(chainId?: ChainIdLike): Promise<AccountStatus>;
67
- getWalletContext(): Promise<commons.context.VersionedContext>;
68
- isDeployed(chainId?: ChainIdLike): Promise<boolean>;
69
- on<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void;
70
- once<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void;
71
- unregister: () => void;
72
- private saveSession;
73
- private useSession;
74
- private useAccountAddress;
75
- private useNetworks;
76
- private clearSession;
77
- }
78
- export interface ProviderConfig {
79
- localStorage?: ItemStore;
80
- walletAppURL: string;
81
- networks?: Partial<NetworkConfig>[];
82
- networkRpcUrl?: string;
83
- defaultNetworkId?: string | number;
84
- transports?: {
85
- windowTransport?: {
86
- enabled: boolean;
87
- };
88
- proxyTransport?: {
89
- enabled: boolean;
90
- appPort?: ProxyMessageChannelPort;
91
- };
92
- extensionTransport?: {
93
- enabled: boolean;
94
- runtime: Runtime.Static;
95
- };
96
- unrealTransport?: {
97
- enabled: boolean;
98
- };
99
- };
100
- walletContext?: commons.context.VersionedContext;
101
- }
102
- export declare const DefaultProviderConfig: ProviderConfig;
103
- export declare const initWallet: (network?: string | number, config?: Partial<ProviderConfig>) => Promise<Wallet>;
104
- export declare const unregisterWallet: () => void;
105
- export declare const getWallet: () => Wallet;