@0xsequence/provider
Advanced tools
Comparing version 0.0.0-20240807210827 to 0.0.0-20240812142652
@@ -1,2 +0,2 @@ | ||
import { JsonRpcRequest, NetworkConfig } from '@0xsequence/network'; | ||
import { NetworkConfig } from '@0xsequence/network'; | ||
import { ConnectDetails, ConnectOptions, ItemStore, MuxTransportTemplate, OpenWalletIntent, OptionalChainId, OptionalEIP6492, ProviderTransport, WalletEventTypes, WalletSession } from "./index.js"; | ||
@@ -78,3 +78,7 @@ import { commons } from '@0xsequence/core'; | ||
disconnect(): Promise<void>; | ||
send(request: JsonRpcRequest, chainId?: number): Promise<any>; | ||
request(request: { | ||
method: string; | ||
params?: any[]; | ||
chainId?: number; | ||
}): Promise<any>; | ||
getNetworks(pull?: boolean): Promise<NetworkConfig[]>; | ||
@@ -86,5 +90,5 @@ private signMethod; | ||
signTypedData(typedData: TypedData, options?: OptionalEIP6492 & OptionalChainId): Promise<string>; | ||
sendTransaction(tx: ethers.providers.TransactionRequest[] | ethers.providers.TransactionRequest, options?: OptionalChainId): Promise<string>; | ||
sendTransaction(tx: ethers.TransactionRequest[] | ethers.TransactionRequest, options?: OptionalChainId): Promise<string>; | ||
getWalletContext(): Promise<commons.context.VersionedContext>; | ||
getOnchainWalletConfig(options?: OptionalChainId): Promise<commons.config.Config>; | ||
} |
import { ethers } from 'ethers'; | ||
import { SequenceClient } from "./client.js"; | ||
import { ChainIdLike, NetworkConfig } from '@0xsequence/network'; | ||
import { ConnectDetails, ConnectOptions, EIP1193Provider, OpenWalletIntent, OptionalChainIdLike, WalletSession } from "./types.js"; | ||
import { EIP1193Provider, ChainIdLike, NetworkConfig } from '@0xsequence/network'; | ||
import { ConnectDetails, ConnectOptions, OpenWalletIntent, OptionalChainIdLike, WalletSession } from "./types.js"; | ||
import { commons } from '@0xsequence/core'; | ||
@@ -32,6 +32,9 @@ import { WalletUtils } from "./utils/index.js"; | ||
} | ||
export declare class SequenceProvider extends ethers.providers.BaseProvider implements ISequenceProvider, EIP1193Provider { | ||
declare const EIP1193EventTypes: readonly ["connect", "disconnect", "chainChanged", "accountsChanged"]; | ||
type EIP1193EventType = (typeof EIP1193EventTypes)[number]; | ||
export declare class SequenceProvider extends ethers.AbstractProvider implements ISequenceProvider, EIP1193Provider { | ||
readonly client: SequenceClient; | ||
private readonly providerFor; | ||
readonly networks: NetworkConfig[]; | ||
readonly options?: ethers.AbstractProviderOptions | undefined; | ||
private readonly singleNetworkProviders; | ||
@@ -41,3 +44,6 @@ readonly _isSequenceProvider = true; | ||
readonly signer: SequenceSigner; | ||
constructor(client: SequenceClient, providerFor: (networkId: number) => ethers.providers.JsonRpcProvider, networks?: NetworkConfig[]); | ||
readonly eip1193EventListeners: Map<"connect" | "disconnect" | "accountsChanged" | "chainChanged", Set<ethers.Listener>>; | ||
constructor(client: SequenceClient, providerFor: (networkId: number) => ethers.JsonRpcProvider, networks?: NetworkConfig[], options?: ethers.AbstractProviderOptions | undefined); | ||
on(event: ethers.ProviderEvent | EIP1193EventType, listener: ethers.Listener): Promise<this>; | ||
off(event: ethers.ProviderEvent | EIP1193EventType, listener?: ethers.Listener | undefined): Promise<this>; | ||
getSigner(): SequenceSigner; | ||
@@ -81,3 +87,4 @@ getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner; | ||
*/ | ||
_getSubprovider(chainId?: ChainIdLike): Promise<ethers.providers.JsonRpcProvider>; | ||
_getSubprovider(chainId?: ChainIdLike): Promise<ethers.JsonRpcProvider>; | ||
_perform(req: ethers.PerformActionRequest): Promise<any>; | ||
perform(method: string, params: any): Promise<any>; | ||
@@ -89,19 +96,20 @@ send(method: string, params: any): Promise<any>; | ||
}): Promise<any>; | ||
detectNetwork(): Promise<ethers.providers.Network>; | ||
waitForTransaction(transactionHash: string, confirmations?: number, timeout?: number, optionals?: OptionalChainIdLike): Promise<ethers.providers.TransactionReceipt>; | ||
_detectNetwork(): Promise<ethers.Network>; | ||
detectNetwork(): Promise<ethers.Network>; | ||
waitForTransaction(transactionHash: string, confirmations?: number, timeout?: number, optionals?: OptionalChainIdLike): Promise<ethers.TransactionReceipt | null>; | ||
getBlockNumber(optionals?: OptionalChainIdLike): Promise<number>; | ||
getGasPrice(optionals?: OptionalChainIdLike): Promise<ethers.BigNumber>; | ||
getBalance(addressOrName: string | Promise<string>, blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, optionals?: OptionalChainIdLike): Promise<ethers.BigNumber>; | ||
getTransactionCount(addressOrName: string | Promise<string>, blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, optionals?: OptionalChainIdLike): Promise<number>; | ||
getCode(addressOrName: string | Promise<string>, blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, optionals?: OptionalChainIdLike): Promise<string>; | ||
getStorageAt(addressOrName: string | Promise<string>, position: ethers.BigNumberish | Promise<ethers.BigNumberish>, blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, optionals?: OptionalChainIdLike): Promise<string>; | ||
call(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, optionals?: OptionalChainIdLike): Promise<string>; | ||
estimateGas(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, optionals?: OptionalChainIdLike): Promise<ethers.BigNumber>; | ||
getBlock(blockHashOrBlockTag: ethers.providers.BlockTag | string | Promise<ethers.providers.BlockTag | string>, optionals?: OptionalChainIdLike): Promise<ethers.providers.Block>; | ||
getTransaction(transactionHash: string | Promise<string>, optionals?: OptionalChainIdLike): Promise<ethers.providers.TransactionResponse>; | ||
getLogs(filter: ethers.providers.Filter | Promise<ethers.providers.Filter>, optionals?: OptionalChainIdLike): Promise<ethers.providers.Log[]>; | ||
getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.FeeData>; | ||
getBalance(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike): Promise<bigint>; | ||
getTransactionCount(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike): Promise<number>; | ||
getCode(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike): Promise<string>; | ||
getStorage(addressOrName: string | Promise<string>, position: ethers.BigNumberish, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike): Promise<string>; | ||
call(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<string>; | ||
estimateGas(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<bigint>; | ||
getBlock(blockHashOrBlockTag: ethers.BlockTag | string, prefetchTxs?: boolean, optionals?: OptionalChainIdLike): Promise<ethers.Block | null>; | ||
getTransaction(transactionHash: string, optionals?: OptionalChainIdLike): Promise<ethers.TransactionResponse | null>; | ||
getLogs(filter: ethers.Filter, optionals?: OptionalChainIdLike): Promise<ethers.Log[]>; | ||
supportsENS(): Promise<boolean>; | ||
getResolver(name: string): Promise<ethers.providers.Resolver | null>; | ||
resolveName(name: string | Promise<string>): Promise<string | null>; | ||
lookupAddress(address: string | Promise<string>): Promise<string | null>; | ||
getResolver(name: string): Promise<ethers.EnsResolver | null>; | ||
resolveName(name: string): Promise<string | null>; | ||
lookupAddress(address: string): Promise<string | null>; | ||
getAvatar(nameOrAddress: string): Promise<string | null>; | ||
@@ -122,7 +130,7 @@ static is: (provider: any) => provider is SequenceProvider; | ||
readonly _isSingleNetworkSequenceProvider = true; | ||
constructor(client: SequenceClient, providerFor: (networkId: number) => ethers.providers.JsonRpcProvider, chainId: ChainIdLike); | ||
constructor(client: SequenceClient, providerFor: (networkId: number) => ethers.JsonRpcProvider, chainId: ChainIdLike, options?: ethers.AbstractProviderOptions); | ||
private _useChainId; | ||
protected useChainId(chainId?: ChainIdLike): Promise<number>; | ||
getChainId(): number; | ||
getNetwork(): Promise<NetworkConfig>; | ||
getNetwork(): Promise<ethers.Network>; | ||
/** | ||
@@ -138,1 +146,2 @@ * Override getProvider and getSigner so they always use `useChainId` | ||
} | ||
export {}; |
@@ -8,3 +8,3 @@ import { ethers } from 'ethers'; | ||
import { OptionalChainIdLike, OptionalEIP6492 } from "./types.js"; | ||
export interface ISequenceSigner extends ethers.Signer { | ||
export interface ISequenceSigner extends Omit<ethers.Signer, 'connect'> { | ||
getProvider(): SequenceProvider; | ||
@@ -18,5 +18,6 @@ getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider; | ||
getNetworks(): Promise<NetworkConfig[]>; | ||
connect: (provider: SequenceProvider) => SequenceSigner; | ||
signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise<string>; | ||
signTypedData(domain: ethers.TypedDataDomain, types: Record<string, Array<ethers.TypedDataField>>, message: Record<string, any>, options?: OptionalChainIdLike & OptionalEIP6492): Promise<string>; | ||
sendTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>[] | ethers.utils.Deferrable<ethers.providers.TransactionRequest>, options?: OptionalChainIdLike): Promise<commons.transaction.TransactionResponse>; | ||
sendTransaction(transaction: ethers.TransactionRequest[] | ethers.TransactionRequest, options?: OptionalChainIdLike): Promise<commons.transaction.TransactionResponse>; | ||
utils: WalletUtils; | ||
@@ -28,3 +29,2 @@ } | ||
private readonly singleNetworkSigners; | ||
readonly _isSigner: boolean; | ||
readonly _isSequenceSigner: boolean; | ||
@@ -34,3 +34,3 @@ get utils(): WalletUtils; | ||
getAddress(): Promise<string>; | ||
connect(provider: ethers.providers.Provider): SequenceSigner; | ||
connect(provider: ethers.Provider): SequenceSigner; | ||
getSigner(): SequenceSigner; | ||
@@ -50,17 +50,18 @@ getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner; | ||
getProvider(chainId?: ChainIdLike): SingleNetworkSequenceProvider | SequenceProvider; | ||
sendTransaction(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>[] | ethers.utils.Deferrable<ethers.providers.TransactionRequest>, options?: OptionalChainIdLike): Promise<ethers.providers.TransactionResponse>; | ||
sendTransaction(transaction: ethers.TransactionRequest[] | ethers.TransactionRequest, options?: OptionalChainIdLike): Promise<ethers.TransactionResponse>; | ||
getWalletConfig(chainId?: ChainIdLike | undefined): Promise<commons.config.Config>; | ||
getNetworks(): Promise<NetworkConfig[]>; | ||
getBalance(blockTag?: ethers.providers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<ethers.BigNumber>; | ||
estimateGas(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, optionals?: OptionalChainIdLike): Promise<ethers.BigNumber>; | ||
call(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, blockTag?: ethers.providers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<string>; | ||
getBalance(blockTag?: ethers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<bigint>; | ||
estimateGas(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<bigint>; | ||
call(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<string>; | ||
getChainId(): Promise<number>; | ||
getGasPrice(optionals?: OptionalChainIdLike): Promise<ethers.BigNumber>; | ||
getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.providers.FeeData>; | ||
getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.FeeData>; | ||
resolveName(name: string): Promise<string>; | ||
_checkProvider(_operation?: string | undefined): void; | ||
populateTransaction(_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): Promise<ethers.providers.TransactionRequest>; | ||
checkTransaction(_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>): ethers.utils.Deferrable<ethers.providers.TransactionRequest>; | ||
getTransactionCount(_blockTag?: ethers.providers.BlockTag | undefined): Promise<number>; | ||
signTransaction(_transaction: ethers.utils.Deferrable<commons.transaction.Transactionish>): Promise<string>; | ||
getNonce(_blockTag?: ethers.BlockTag): Promise<number>; | ||
populateCall(_transaction: ethers.TransactionRequest): Promise<ethers.TransactionLike<string>>; | ||
populateTransaction(_transaction: ethers.TransactionRequest): Promise<ethers.TransactionLike<string>>; | ||
checkTransaction(_transaction: ethers.TransactionRequest): ethers.TransactionRequest; | ||
getTransactionCount(_blockTag?: ethers.BlockTag): Promise<number>; | ||
signTransaction(_transaction: commons.transaction.Transactionish): Promise<string>; | ||
static is(cand: any): cand is SequenceSigner; | ||
@@ -67,0 +68,0 @@ } |
import { ProviderTransport, ProviderMessage, ProviderMessageRequest, ProviderEventTypes, ProviderMessageResponse, ProviderMessageResponseCallback, OpenState, OpenWalletIntent, ConnectDetails, WalletSession, ProviderRpcError, InitState, TypedEventEmitter } from "../types.js"; | ||
import { NetworkConfig, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network'; | ||
import { NetworkConfig } from '@0xsequence/network'; | ||
import { commons } from '@0xsequence/core'; | ||
@@ -34,3 +34,7 @@ export declare const PROVIDER_OPEN_TIMEOUT = 30000; | ||
isConnected(): boolean; | ||
sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => Promise<void>; | ||
request(request: { | ||
method: string; | ||
params?: any[]; | ||
chainId?: number; | ||
}): Promise<any>; | ||
handleMessage(message: ProviderMessage<any>): void; | ||
@@ -37,0 +41,0 @@ sendMessageRequest: (message: ProviderMessageRequest) => Promise<ProviderMessageResponse>; |
import { WalletTransport, ProviderMessage, ProviderMessageRequest, ProviderMessageResponse, ProviderRpcError, InitState, ConnectDetails, WalletSession, TransportSession } from "../types.js"; | ||
import { WalletRequestHandler } from "./wallet-request-handler.js"; | ||
import { NetworkConfig, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network'; | ||
import { NetworkConfig } from '@0xsequence/network'; | ||
import { commons } from '@0xsequence/core'; | ||
@@ -17,3 +17,7 @@ export declare abstract class BaseWalletTransport implements WalletTransport { | ||
unregister(): void; | ||
sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => Promise<never>; | ||
request(request: { | ||
method: string; | ||
params?: any[]; | ||
chainId?: number; | ||
}): Promise<any>; | ||
handleMessage: (message: ProviderMessage<any>) => Promise<void>; | ||
@@ -20,0 +24,0 @@ sendMessageRequest: (message: ProviderMessageRequest) => Promise<ProviderMessageResponse>; |
import { ProviderMessage, ProviderTransport, ProviderEventTypes, ProviderMessageRequest, ProviderMessageResponse, WalletSession, OpenWalletIntent, ConnectDetails } from "../../types.js"; | ||
import { JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network'; | ||
import { ProxyMessageChannelPort } from "../proxy-transport/index.js"; | ||
@@ -38,3 +37,7 @@ import { Runtime } from 'webextension-polyfill'; | ||
emit<K extends keyof ProviderEventTypes>(event: K, ...args: Parameters<ProviderEventTypes[K]>): boolean; | ||
sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => Promise<void>; | ||
request(request: { | ||
method: string; | ||
params?: any[]; | ||
chainId?: number; | ||
}): Promise<any>; | ||
sendMessage(message: ProviderMessage<any>): void; | ||
@@ -41,0 +44,0 @@ sendMessageRequest: (message: ProviderMessageRequest) => Promise<ProviderMessageResponse>; |
import { Account } from '@0xsequence/account'; | ||
import { commons } from '@0xsequence/core'; | ||
import { ChainIdLike, JsonRpcHandler, JsonRpcRequest, JsonRpcResponseCallback, NetworkConfig } from '@0xsequence/network'; | ||
import { providers } from 'ethers'; | ||
import { ChainIdLike, NetworkConfig, EIP1193Provider } from '@0xsequence/network'; | ||
import { ConnectDetails, ConnectOptions, MessageToSign, NetworkedConnectOptions, OpenWalletIntent, PromptConnectDetails, ProviderEventTypes, ProviderMessageRequest, ProviderMessageRequestHandler, ProviderMessageResponse, ProviderRpcError, WalletSession } from "../types.js"; | ||
type ExternalProvider = providers.ExternalProvider; | ||
export interface WalletSignInOptions { | ||
@@ -11,3 +9,3 @@ connect?: boolean; | ||
} | ||
export declare class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, ProviderMessageRequestHandler { | ||
export declare class WalletRequestHandler implements EIP1193Provider, ProviderMessageRequestHandler { | ||
private account; | ||
@@ -30,3 +28,7 @@ private signerReadyCallbacks; | ||
sendMessageRequest(message: ProviderMessageRequest): Promise<ProviderMessageResponse>; | ||
sendAsync: (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => Promise<void>; | ||
request(request: { | ||
method: string; | ||
params?: any[]; | ||
chainId?: number; | ||
}): Promise<any>; | ||
on<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void; | ||
@@ -63,2 +65,1 @@ once<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void; | ||
} | ||
export {}; |
import { ETHAuthProof as AuthETHAuthProof } from '@0xsequence/auth'; | ||
import { commons } from '@0xsequence/core'; | ||
import { ChainIdLike, JsonRpcHandler, JsonRpcRequest, JsonRpcResponse, NetworkConfig, ProviderRpcError as NetworkProviderRpcError } from '@0xsequence/network'; | ||
import { ChainIdLike, EIP1193Provider, JsonRpcRequest, JsonRpcResponse, NetworkConfig, JsonRpcErrorPayload } from '@0xsequence/network'; | ||
import { TypedData } from '@0xsequence/utils'; | ||
export interface ProviderTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
export interface ProviderTransport extends EIP1193Provider, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
register(): void; | ||
@@ -19,3 +19,3 @@ unregister(): void; | ||
export declare function isProviderTransport(transport: any): transport is ProviderTransport; | ||
export interface WalletTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
export interface WalletTransport extends EIP1193Provider, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
register(): void; | ||
@@ -41,7 +41,8 @@ unregister(): void; | ||
origin?: string; | ||
clientVersion: string; | ||
} | ||
export type ProviderMessageRequest = ProviderMessage<JsonRpcRequest>; | ||
export type ProviderMessageResponse = ProviderMessage<JsonRpcResponse>; | ||
export type ProviderMessageResponse = ProviderMessage<JsonRpcResponse | any>; | ||
export type ProviderMessageResponseCallback = (error?: ProviderRpcError, response?: ProviderMessageResponse) => void; | ||
export type ProviderRpcError = NetworkProviderRpcError; | ||
export type ProviderRpcError = JsonRpcErrorPayload; | ||
export interface ProviderMessageRequestHandler { | ||
@@ -262,8 +263,2 @@ sendMessageRequest(message: ProviderMessageRequest): Promise<ProviderMessageResponse>; | ||
} | undefined; | ||
export interface EIP1193Provider { | ||
request: (request: { | ||
method: string; | ||
params?: Array<any>; | ||
}) => Promise<any>; | ||
} | ||
export {}; |
@@ -1,10 +0,10 @@ | ||
import { ethers, BytesLike } from 'ethers'; | ||
import { ethers } from 'ethers'; | ||
import { AccountStatus } from '@0xsequence/account'; | ||
import { TypedData } from '@0xsequence/utils'; | ||
export declare const messageToBytes: (message: BytesLike) => Uint8Array; | ||
export declare const prefixEIP191Message: (message: BytesLike) => Uint8Array; | ||
export declare const messageToBytes: (message: ethers.BytesLike) => Uint8Array; | ||
export declare const prefixEIP191Message: (message: ethers.BytesLike) => Uint8Array; | ||
export declare const trimEIP191Prefix: (prefixedMessage: Uint8Array) => Uint8Array; | ||
export declare const isValidSignature: (address: string, digest: Uint8Array, sig: string, provider: ethers.providers.Provider) => Promise<boolean>; | ||
export declare const isValidMessageSignature: (address: string, message: string | Uint8Array, signature: string, provider: ethers.providers.Provider) => Promise<boolean>; | ||
export declare const isValidTypedDataSignature: (address: string, typedData: TypedData, signature: string, provider: ethers.providers.Provider) => Promise<boolean>; | ||
export declare const isValidSignature: (address: string, digest: Uint8Array, sig: string, provider: ethers.Provider) => Promise<boolean>; | ||
export declare const isValidMessageSignature: (address: string, message: string | Uint8Array, signature: string, provider: ethers.Provider) => Promise<boolean>; | ||
export declare const isValidTypedDataSignature: (address: string, typedData: TypedData, signature: string, provider: ethers.Provider) => Promise<boolean>; | ||
export declare const isBrowserExtension: () => boolean; | ||
@@ -37,2 +37,2 @@ export declare const isUnityPlugin: () => boolean; | ||
export declare function useBestStore(): ItemStore; | ||
export declare function resolveArrayProperties<T>(object: Readonly<ethers.utils.Deferrable<T>> | Readonly<ethers.utils.Deferrable<T>>[]): Promise<T>; | ||
export declare function resolveArrayProperties<T>(object: Readonly<T> | Readonly<T>[]): Promise<T>; |
@@ -1,2 +0,2 @@ | ||
import { BytesLike, TypedDataDomain, TypedDataField } from 'ethers'; | ||
import { ethers } from 'ethers'; | ||
import { ChainIdLike } from '@0xsequence/network'; | ||
@@ -13,4 +13,4 @@ import { TypedData } from '@0xsequence/utils'; | ||
constructor(signer: SequenceSigner); | ||
signMessage(message: BytesLike, chainId?: ChainIdLike, eip6492?: boolean): Promise<string>; | ||
signTypedData(domain: TypedDataDomain, types: Record<string, Array<TypedDataField>>, message: Record<string, any>, chainId?: ChainIdLike, eip6492?: boolean): Promise<string>; | ||
signMessage(message: ethers.BytesLike, chainId?: ChainIdLike, eip6492?: boolean): Promise<string>; | ||
signTypedData(domain: ethers.TypedDataDomain, types: Record<string, Array<ethers.TypedDataField>>, message: Record<string, any>, chainId?: ChainIdLike, eip6492?: boolean): Promise<string>; | ||
isValidSignature(address: string, digest: Uint8Array, signature: string, chainId: number): Promise<boolean>; | ||
@@ -17,0 +17,0 @@ isValidMessageSignature(address: string, message: string | Uint8Array, signature: string, chainId: number): Promise<boolean>; |
{ | ||
"name": "@0xsequence/provider", | ||
"version": "0.0.0-20240807210827", | ||
"version": "0.0.0-20240812142652", | ||
"description": "provider sub-package for Sequence", | ||
@@ -15,18 +15,18 @@ "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/provider", | ||
"webextension-polyfill": "^0.10.0", | ||
"@0xsequence/abi": "0.0.0-20240807210827", | ||
"@0xsequence/account": "0.0.0-20240807210827", | ||
"@0xsequence/auth": "0.0.0-20240807210827", | ||
"@0xsequence/core": "0.0.0-20240807210827", | ||
"@0xsequence/migration": "0.0.0-20240807210827", | ||
"@0xsequence/network": "0.0.0-20240807210827", | ||
"@0xsequence/relayer": "0.0.0-20240807210827", | ||
"@0xsequence/utils": "0.0.0-20240807210827", | ||
"@0xsequence/wallet": "0.0.0-20240807210827" | ||
"@0xsequence/abi": "0.0.0-20240812142652", | ||
"@0xsequence/account": "0.0.0-20240812142652", | ||
"@0xsequence/auth": "0.0.0-20240812142652", | ||
"@0xsequence/core": "0.0.0-20240812142652", | ||
"@0xsequence/migration": "0.0.0-20240812142652", | ||
"@0xsequence/relayer": "0.0.0-20240812142652", | ||
"@0xsequence/network": "0.0.0-20240812142652", | ||
"@0xsequence/utils": "0.0.0-20240812142652", | ||
"@0xsequence/wallet": "0.0.0-20240812142652" | ||
}, | ||
"peerDependencies": { | ||
"ethers": ">=5.5 < 6" | ||
"ethers": ">=6" | ||
}, | ||
"devDependencies": { | ||
"@types/webextension-polyfill": "^0.10.0", | ||
"ethers": "^5.7.2", | ||
"ethers": "^6.13.0", | ||
"hardhat": "^2.20.1" | ||
@@ -33,0 +33,0 @@ }, |
@@ -1,2 +0,2 @@ | ||
import { JsonRpcRequest, JsonRpcResponse, NetworkConfig } from '@0xsequence/network' | ||
import { NetworkConfig } from '@0xsequence/network' | ||
import { | ||
@@ -18,3 +18,3 @@ ConnectDetails, | ||
} from '.' | ||
import { commons } from '@0xsequence/core' | ||
import { commons, VERSION } from '@0xsequence/core' | ||
import { TypedData } from '@0xsequence/utils' | ||
@@ -25,4 +25,2 @@ import { toExtended } from './extended' | ||
import packageJson from '../package.json' | ||
/** | ||
@@ -171,3 +169,3 @@ * This session class is meant to persist the state of the wallet connection | ||
this.transport.on('connect', (response: ConnectDetails) => { | ||
const chainIdHex = ethers.utils.hexValue(this.getChainId()) | ||
const chainIdHex = ethers.toQuantity(this.getChainId()) | ||
this.callbacks.connect?.forEach(cb => | ||
@@ -210,3 +208,3 @@ cb({ | ||
this.defaultChainId.onDefaultChainIdChanged((chainId: number) => { | ||
const chainIdHex = ethers.utils.hexValue(chainId) | ||
const chainIdHex = ethers.toQuantity(chainId) | ||
this.callbacks.chainChanged?.forEach(cb => cb(chainIdHex)) | ||
@@ -344,3 +342,3 @@ }) | ||
type: 'connect', | ||
options: { ...options, networkId: this.getChainId(), clientVersion: packageJson.version } | ||
options: { ...options, networkId: this.getChainId(), clientVersion: VERSION } | ||
}) | ||
@@ -359,3 +357,3 @@ | ||
if (connectDetails.chainId) { | ||
connectDetails.chainId = ethers.BigNumber.from(connectDetails.chainId).toString() | ||
connectDetails.chainId = BigInt(connectDetails.chainId).toString() | ||
} | ||
@@ -390,5 +388,3 @@ | ||
// Working with sendAsync is less idiomatic | ||
// but transport uses it instead of send, so we wrap it | ||
send(request: JsonRpcRequest, chainId?: number): Promise<any> { | ||
async request(request: { method: string; params?: any[]; chainId?: number }): Promise<any> { | ||
// Internally when sending requests we use `legacy_sign` | ||
@@ -399,21 +395,3 @@ // to avoid the default EIP6492 behavior overriding an explicit | ||
return new Promise((resolve, reject) => { | ||
this.transport.sendAsync( | ||
request, | ||
(error, response) => { | ||
if (error) { | ||
reject(error) | ||
} else if (response === undefined) { | ||
reject(new Error(`Got undefined response for request: ${request}`)) | ||
} else if (typeof response === 'object' && response.error) { | ||
reject(response.error) | ||
} else if (typeof response === 'object' && response.result) { | ||
resolve(response.result) | ||
} else { | ||
reject(new Error(`Got invalid response for request: ${request}`)) | ||
} | ||
}, | ||
chainId || this.getChainId() | ||
) | ||
}) | ||
return this.transport.request(request) | ||
} | ||
@@ -425,3 +403,3 @@ | ||
if (pull) { | ||
connectedSession.networks = await this.send({ method: 'sequence_getNetworks' }) | ||
connectedSession.networks = await this.request({ method: 'sequence_getNetworks' }) | ||
this.session.setSession(connectedSession) | ||
@@ -486,7 +464,10 @@ } | ||
// Serialize a BytesLike or string message into a hex string before sending | ||
message = ethers.utils.hexlify(messageToBytes(message)) | ||
message = ethers.hexlify(messageToBytes(message)) | ||
// Address is ignored by the wallet webapp | ||
return this.send({ method, params: [message, this.getAddress()] }, options?.chainId) | ||
return this.request({ | ||
method, | ||
params: [message, this.getAddress()], | ||
chainId: options?.chainId | ||
}) | ||
} | ||
@@ -499,3 +480,3 @@ | ||
// and it makes the client depend on ethers. | ||
const encoded = ethers.utils._TypedDataEncoder.getPayload(typedData.domain, typedData.types, typedData.message) | ||
const encoded = ethers.TypedDataEncoder.getPayload(typedData.domain, typedData.types, typedData.message) | ||
@@ -509,14 +490,10 @@ // The sign typed data will use one of the following chainIds, in order: | ||
return this.send( | ||
{ method, params: [this.getAddress(), encoded] }, | ||
options?.chainId || | ||
(typedData.domain.chainId && ethers.BigNumber.from(typedData.domain.chainId).toNumber()) || | ||
this.getChainId() | ||
) | ||
return this.request({ | ||
method, | ||
params: [this.getAddress(), encoded], | ||
chainId: options?.chainId || (typedData.domain.chainId && Number(typedData.domain.chainId)) || this.getChainId() | ||
}) | ||
} | ||
async sendTransaction( | ||
tx: ethers.providers.TransactionRequest[] | ethers.providers.TransactionRequest, | ||
options?: OptionalChainId | ||
): Promise<string> { | ||
async sendTransaction(tx: ethers.TransactionRequest[] | ethers.TransactionRequest, options?: OptionalChainId): Promise<string> { | ||
const sequenceTxs = Array.isArray(tx) ? tx : [tx] | ||
@@ -527,7 +504,7 @@ const extendedTxs = toExtended(sequenceTxs) | ||
return this.send({ method: 'eth_sendTransaction', params: [extendedTxs] }, options?.chainId) | ||
return this.request({ method: 'eth_sendTransaction', params: [extendedTxs], chainId: options?.chainId }) | ||
} | ||
async getWalletContext(): Promise<commons.context.VersionedContext> { | ||
return this.send({ method: 'sequence_getWalletContext' }) | ||
return this.request({ method: 'sequence_getWalletContext' }) | ||
} | ||
@@ -537,6 +514,7 @@ | ||
// NOTICE: sequence_getWalletConfig sends the chainId as a param | ||
const res = await this.send( | ||
{ method: 'sequence_getWalletConfig', params: [options?.chainId || this.getChainId()] }, | ||
options?.chainId | ||
) | ||
const res = await this.request({ | ||
method: 'sequence_getWalletConfig', | ||
params: [options?.chainId || this.getChainId()], | ||
chainId: options?.chainId | ||
}) | ||
return Array.isArray(res) ? res[0] : res | ||
@@ -543,0 +521,0 @@ } |
@@ -26,3 +26,3 @@ import { ethers } from 'ethers' | ||
try { | ||
const stringified = ethers.utils.toUtf8String(bytes) | ||
const stringified = ethers.toUtf8String(bytes) | ||
return DCL_REGEX.test(stringified) | ||
@@ -37,3 +37,3 @@ } catch { | ||
export function isZeroExV3Order(bytes: Uint8Array): boolean { | ||
const abi = new ethers.utils.Interface(ZeroXV3EIP1271OrderWithHashAbi) | ||
const abi = new ethers.Interface(ZeroXV3EIP1271OrderWithHashAbi) | ||
try { | ||
@@ -40,0 +40,0 @@ abi.decodeFunctionData('OrderWithHash', bytes) |
import { ethers } from 'ethers' | ||
export type ExtendedTransactionRequest = ethers.providers.TransactionRequest & { | ||
auxiliary?: ethers.providers.TransactionRequest[] | ||
export type ExtendedTransactionRequest = ethers.TransactionRequest & { | ||
auxiliary?: ethers.TransactionRequest[] | ||
} | ||
export function toExtended(transactions: ethers.providers.TransactionRequest[]): ExtendedTransactionRequest { | ||
export function toExtended(transactions: ethers.TransactionRequest[]): ExtendedTransactionRequest { | ||
if (transactions.length === 0) { | ||
@@ -20,8 +20,8 @@ throw new Error('No transaction provided') | ||
export function fromExtended(transaction: ExtendedTransactionRequest): ethers.providers.TransactionRequest[] { | ||
export function fromExtended(transaction: ExtendedTransactionRequest): ethers.TransactionRequest[] { | ||
return [transaction, ...(transaction.auxiliary || [])] | ||
} | ||
export function isExtended(transaction: ethers.providers.TransactionRequest): transaction is ExtendedTransactionRequest { | ||
export function isExtended(transaction: ethers.TransactionRequest): transaction is ExtendedTransactionRequest { | ||
return (transaction as any).auxiliary !== undefined | ||
} |
import { | ||
CachedProvider, | ||
ChainIdLike, | ||
JsonRpcRouter, | ||
JsonRpcSender, | ||
NetworkConfig, | ||
@@ -10,3 +8,4 @@ allNetworks, | ||
findNetworkConfig, | ||
loggingProviderMiddleware | ||
loggingProviderMiddleware, | ||
JsonRpcProvider | ||
} from '@0xsequence/network' | ||
@@ -89,3 +88,3 @@ import { MuxTransportTemplate } from './transports' | ||
const rpcProviders: Record<number, ethers.providers.JsonRpcProvider> = {} | ||
const rpcProviders: Record<number, ethers.JsonRpcProvider> = {} | ||
@@ -125,9 +124,9 @@ // Find any new networks that aren't already defined in sequence.js | ||
const baseProvider = new ethers.providers.JsonRpcProvider(rpcUrl) | ||
const router = new JsonRpcRouter( | ||
[loggingProviderMiddleware, exceptionProviderMiddleware, new CachedProvider()], | ||
new JsonRpcSender(baseProvider) | ||
rpcProviders[chainId] = new JsonRpcProvider( | ||
rpcUrl, | ||
{ | ||
middlewares: [loggingProviderMiddleware, exceptionProviderMiddleware, new CachedProvider()] | ||
}, | ||
{ cacheTimeout: -1 } | ||
) | ||
rpcProviders[chainId] = new ethers.providers.Web3Provider(router, chainId) | ||
} | ||
@@ -134,0 +133,0 @@ |
import { ethers } from 'ethers' | ||
import { SequenceClient } from './client' | ||
import { ChainIdLike, NetworkConfig, allNetworks, findNetworkConfig } from '@0xsequence/network' | ||
import { ConnectDetails, ConnectOptions, EIP1193Provider, OpenWalletIntent, OptionalChainIdLike, WalletSession } from './types' | ||
import { EIP1193Provider, ChainIdLike, NetworkConfig, allNetworks, findNetworkConfig } from '@0xsequence/network' | ||
import { ConnectDetails, ConnectOptions, OpenWalletIntent, OptionalChainIdLike, WalletSession } from './types' | ||
import { commons } from '@0xsequence/core' | ||
@@ -49,3 +49,6 @@ import { WalletUtils } from './utils/index' | ||
export class SequenceProvider extends ethers.providers.BaseProvider implements ISequenceProvider, EIP1193Provider { | ||
const EIP1193EventTypes = ['connect', 'disconnect', 'chainChanged', 'accountsChanged'] as const | ||
type EIP1193EventType = (typeof EIP1193EventTypes)[number] | ||
export class SequenceProvider extends ethers.AbstractProvider implements ISequenceProvider, EIP1193Provider { | ||
private readonly singleNetworkProviders: { [chainId: number]: SingleNetworkSequenceProvider } = {} | ||
@@ -58,26 +61,33 @@ | ||
readonly eip1193EventListeners = new Map<EIP1193EventType, Set<ethers.Listener>>() | ||
constructor( | ||
public readonly client: SequenceClient, | ||
private readonly providerFor: (networkId: number) => ethers.providers.JsonRpcProvider, | ||
public readonly networks: NetworkConfig[] = allNetworks | ||
private readonly providerFor: (networkId: number) => ethers.JsonRpcProvider, | ||
public readonly networks: NetworkConfig[] = allNetworks, | ||
public readonly options?: ethers.AbstractProviderOptions | ||
) { | ||
// We support a lot of networks | ||
// but we start with the default one | ||
super(client.getChainId()) | ||
super(client.getChainId(), options) | ||
// Emit events as defined by EIP-1193 | ||
client.onConnect(details => { | ||
this.emit('connect', details) | ||
//this.emit('connect', details) | ||
this.eip1193EventListeners.get('connect')?.forEach(listener => listener(details)) | ||
}) | ||
client.onDisconnect(error => { | ||
this.emit('disconnect', error) | ||
//this.emit('disconnect', error) | ||
this.eip1193EventListeners.get('disconnect')?.forEach(listener => listener(error)) | ||
}) | ||
client.onDefaultChainIdChanged(chainId => { | ||
this.emit('chainChanged', chainId) | ||
//this.emit('chainChanged', chainId) | ||
this.eip1193EventListeners.get('chainChanged')?.forEach(listener => listener(chainId)) | ||
}) | ||
client.onAccountsChanged(accounts => { | ||
this.emit('accountsChanged', accounts) | ||
//this.emit('accountsChanged', accounts) | ||
this.eip1193EventListeners.get('accountsChanged')?.forEach(listener => listener(accounts)) | ||
}) | ||
@@ -100,2 +110,32 @@ | ||
async on(event: ethers.ProviderEvent | EIP1193EventType, listener: ethers.Listener): Promise<this> { | ||
if (EIP1193EventTypes.includes(event as EIP1193EventType)) { | ||
const listeners = this.eip1193EventListeners.get(event as EIP1193EventType) || new Set() | ||
listeners.add(listener) | ||
this.eip1193EventListeners.set(event as EIP1193EventType, listeners) | ||
return this | ||
} | ||
return super.on(event, listener) as Promise<this> | ||
} | ||
async off(event: ethers.ProviderEvent | EIP1193EventType, listener?: ethers.Listener | undefined): Promise<this> { | ||
if (EIP1193EventTypes.includes(event as EIP1193EventType)) { | ||
const listeners = this.eip1193EventListeners.get(event as EIP1193EventType) | ||
if (listeners) { | ||
if (listener) { | ||
listeners.delete(listener) | ||
} else { | ||
listeners.clear() | ||
} | ||
} | ||
return this | ||
} | ||
return super.off(event, listener) as Promise<this> | ||
} | ||
getSigner(): SequenceSigner | ||
@@ -212,3 +252,3 @@ getSigner(chainId: ChainIdLike): SingleNetworkSequenceSigner | ||
if (!chainId) { | ||
return this | ||
return this as SequenceProvider | ||
} | ||
@@ -219,3 +259,8 @@ | ||
if (!this.singleNetworkProviders[useChainId]) { | ||
this.singleNetworkProviders[useChainId] = new SingleNetworkSequenceProvider(this.client, this.providerFor, useChainId) | ||
this.singleNetworkProviders[useChainId] = new SingleNetworkSequenceProvider( | ||
this.client, | ||
this.providerFor, | ||
useChainId, | ||
this.options | ||
) | ||
} | ||
@@ -230,3 +275,3 @@ | ||
*/ | ||
async _getSubprovider(chainId?: ChainIdLike): Promise<ethers.providers.JsonRpcProvider> { | ||
async _getSubprovider(chainId?: ChainIdLike): Promise<ethers.JsonRpcProvider> { | ||
const useChainId = await this.useChainId(chainId) | ||
@@ -245,6 +290,19 @@ | ||
async _perform(req: ethers.PerformActionRequest): Promise<any> { | ||
const { method, ...args } = req | ||
const provider = await this._getSubprovider() | ||
const prepared = provider.getRpcRequest(req) ?? { method, args: Object.values(args) } | ||
if (!prepared) { | ||
throw new Error(`Unsupported method ${req.method}`) | ||
} | ||
return provider.send(prepared.method, prepared.args) | ||
} | ||
async perform(method: string, params: any): Promise<any> { | ||
// First we check if the method should be handled by the client | ||
if (method === 'eth_chainId') { | ||
return ethers.utils.hexValue(await this.useChainId()) | ||
return ethers.toQuantity(await this.useChainId()) | ||
} | ||
@@ -278,10 +336,6 @@ | ||
// the client will use its own default chainId | ||
return this.client.send({ method, params }, this.getChainId()) | ||
return this.client.request({ method, params, chainId: this.getChainId() }) | ||
} | ||
// Forward call to the corresponding provider | ||
// we use the provided chainId, or the default one provided by the client | ||
const provider = await this._getSubprovider() | ||
const prepared = provider.prepareRequest(method, params) ?? [method, params] | ||
return provider.send(prepared[0], prepared[1]) | ||
return this._perform({ method, ...params }) | ||
} | ||
@@ -297,13 +351,19 @@ | ||
async detectNetwork(): Promise<ethers.providers.Network> { | ||
async _detectNetwork(): Promise<ethers.Network> { | ||
const chainId = this.client.getChainId() | ||
const network = findNetworkConfig(this.networks, chainId) | ||
const found = findNetworkConfig(this.networks, chainId) | ||
if (!network) { | ||
if (!found) { | ||
throw new Error(`Unknown network ${chainId}`) | ||
} | ||
const network = new ethers.Network(found.name, found.chainId) | ||
return network | ||
} | ||
async detectNetwork(): Promise<ethers.Network> { | ||
return this._detectNetwork() | ||
} | ||
// Override most of the methods, so we add support for an optional chainId | ||
@@ -326,12 +386,8 @@ // argument, which is used to select the provider to use. | ||
async getGasPrice(optionals?: OptionalChainIdLike) { | ||
async getFeeData(optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
return provider.getGasPrice() | ||
return provider.getFeeData() | ||
} | ||
async getBalance( | ||
addressOrName: string | Promise<string>, | ||
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, | ||
optionals?: OptionalChainIdLike | ||
) { | ||
async getBalance(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
@@ -343,3 +399,3 @@ return provider.getBalance(addressOrName, blockTag) | ||
addressOrName: string | Promise<string>, | ||
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, | ||
blockTag?: ethers.BlockTag, | ||
optionals?: OptionalChainIdLike | ||
@@ -351,7 +407,3 @@ ) { | ||
async getCode( | ||
addressOrName: string | Promise<string>, | ||
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, | ||
optionals?: OptionalChainIdLike | ||
) { | ||
async getCode(addressOrName: string | Promise<string>, blockTag?: ethers.BlockTag, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
@@ -361,22 +413,18 @@ return provider.getCode(addressOrName, blockTag) | ||
async getStorageAt( | ||
async getStorage( | ||
addressOrName: string | Promise<string>, | ||
position: ethers.BigNumberish | Promise<ethers.BigNumberish>, | ||
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, | ||
position: ethers.BigNumberish, | ||
blockTag?: ethers.BlockTag, | ||
optionals?: OptionalChainIdLike | ||
) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
return provider.getStorageAt(addressOrName, position, blockTag) | ||
return provider.getStorage(addressOrName, position, blockTag) | ||
} | ||
async call( | ||
transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, | ||
blockTag?: ethers.providers.BlockTag | Promise<ethers.providers.BlockTag>, | ||
optionals?: OptionalChainIdLike | ||
) { | ||
async call(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
return provider.call(transaction, blockTag) | ||
return provider.call(transaction) | ||
} | ||
async estimateGas(transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, optionals?: OptionalChainIdLike) { | ||
async estimateGas(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
@@ -386,11 +434,8 @@ return provider.estimateGas(transaction) | ||
async getBlock( | ||
blockHashOrBlockTag: ethers.providers.BlockTag | string | Promise<ethers.providers.BlockTag | string>, | ||
optionals?: OptionalChainIdLike | ||
) { | ||
async getBlock(blockHashOrBlockTag: ethers.BlockTag | string, prefetchTxs?: boolean, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
return provider.getBlock(blockHashOrBlockTag) | ||
return provider.getBlock(blockHashOrBlockTag, prefetchTxs) | ||
} | ||
async getTransaction(transactionHash: string | Promise<string>, optionals?: OptionalChainIdLike) { | ||
async getTransaction(transactionHash: string, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
@@ -400,3 +445,3 @@ return provider.getTransaction(transactionHash) | ||
async getLogs(filter: ethers.providers.Filter | Promise<ethers.providers.Filter>, optionals?: OptionalChainIdLike) { | ||
async getLogs(filter: ethers.Filter, optionals?: OptionalChainIdLike) { | ||
const provider = await this._getSubprovider(optionals?.chainId) | ||
@@ -423,4 +468,4 @@ return provider.getLogs(filter) | ||
async resolveName(name: string | Promise<string>) { | ||
if (ethers.utils.isAddress(await name)) { | ||
async resolveName(name: string) { | ||
if (ethers.isAddress(name)) { | ||
return name | ||
@@ -438,3 +483,3 @@ } | ||
async lookupAddress(address: string | Promise<string>) { | ||
async lookupAddress(address: string) { | ||
if (!(await this.supportsENS())) { | ||
@@ -463,5 +508,5 @@ return null | ||
function normalizeChainId(chainId: string | number | bigint | { chainId: string }): number { | ||
function normalizeChainId(chainId: ethers.BigNumberish | { chainId: string }): number { | ||
if (typeof chainId === 'object') return normalizeChainId(chainId.chainId) | ||
return ethers.BigNumber.from(chainId).toNumber() | ||
return Number(chainId) | ||
} | ||
@@ -483,6 +528,7 @@ | ||
client: SequenceClient, | ||
providerFor: (networkId: number) => ethers.providers.JsonRpcProvider, | ||
public readonly chainId: ChainIdLike | ||
providerFor: (networkId: number) => ethers.JsonRpcProvider, | ||
public readonly chainId: ChainIdLike, | ||
options?: ethers.AbstractProviderOptions | ||
) { | ||
super(client, providerFor) | ||
super(client, providerFor, undefined, options) | ||
} | ||
@@ -508,11 +554,11 @@ | ||
async getNetwork(): Promise<NetworkConfig> { | ||
async getNetwork(): Promise<ethers.Network> { | ||
const networks = await this.client.getNetworks() | ||
const res = findNetworkConfig(networks, this.chainId) | ||
const found = findNetworkConfig(networks, this.chainId) | ||
if (!res) { | ||
if (!found) { | ||
throw new Error(`Unsupported network ${this.chainId}`) | ||
} | ||
return res | ||
return new ethers.Network(found.name, found.chainId) | ||
} | ||
@@ -519,0 +565,0 @@ |
@@ -11,3 +11,3 @@ import { ethers } from 'ethers' | ||
export interface ISequenceSigner extends ethers.Signer { | ||
export interface ISequenceSigner extends Omit<ethers.Signer, 'connect'> { | ||
getProvider(): SequenceProvider | ||
@@ -24,2 +24,4 @@ getProvider(chainId: ChainIdLike): SingleNetworkSequenceProvider | ||
connect: (provider: SequenceProvider) => SequenceSigner | ||
signMessage(message: ethers.BytesLike, options?: OptionalChainIdLike & OptionalEIP6492): Promise<string> | ||
@@ -38,5 +40,3 @@ | ||
sendTransaction( | ||
transaction: | ||
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>[] | ||
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>, | ||
transaction: ethers.TransactionRequest[] | ethers.TransactionRequest, | ||
options?: OptionalChainIdLike | ||
@@ -51,3 +51,2 @@ ): Promise<commons.transaction.TransactionResponse> | ||
readonly _isSigner: boolean = true | ||
readonly _isSequenceSigner: boolean = true | ||
@@ -70,3 +69,3 @@ | ||
// it exists to maintain compatibility with ethers.Signer | ||
connect(provider: ethers.providers.Provider): SequenceSigner { | ||
connect(provider: ethers.Provider): SequenceSigner { | ||
if (!SequenceProvider.is(provider)) { | ||
@@ -132,8 +131,3 @@ throw new Error('SequenceSigner can only be connected to a SequenceProvider') | ||
async sendTransaction( | ||
transaction: | ||
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>[] | ||
| ethers.utils.Deferrable<ethers.providers.TransactionRequest>, | ||
options?: OptionalChainIdLike | ||
) { | ||
async sendTransaction(transaction: ethers.TransactionRequest[] | ethers.TransactionRequest, options?: OptionalChainIdLike) { | ||
const chainId = this.useChainId(options?.chainId) | ||
@@ -145,9 +139,17 @@ const resolved = await resolveArrayProperties(transaction) | ||
try { | ||
return (await ethers.utils.poll( | ||
async () => { | ||
const result = await new Promise<ethers.TransactionResponse>(resolve => { | ||
const check = async () => { | ||
const tx = await provider.getTransaction(txHash) | ||
return tx ? provider._wrapTransaction(tx, txHash) : undefined | ||
}, | ||
{ onceBlock: provider } | ||
)) as ethers.providers.TransactionResponse | ||
if (tx !== null) { | ||
return resolve(tx) | ||
} | ||
await provider.once('block', check) | ||
} | ||
check() | ||
}) | ||
return result | ||
} catch (err) { | ||
@@ -168,3 +170,3 @@ err.transactionHash = txHash | ||
async getBalance(blockTag?: ethers.providers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<ethers.BigNumber> { | ||
async getBalance(blockTag?: ethers.BlockTag | undefined, optionals?: OptionalChainIdLike): Promise<bigint> { | ||
const provider = this.getProvider(optionals?.chainId) | ||
@@ -174,15 +176,8 @@ return provider.getBalance(this.getAddress(), blockTag) | ||
async estimateGas( | ||
transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, | ||
optionals?: OptionalChainIdLike | ||
): Promise<ethers.BigNumber> { | ||
async estimateGas(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<bigint> { | ||
return this.getProvider(optionals?.chainId).estimateGas(transaction) | ||
} | ||
async call( | ||
transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest>, | ||
blockTag?: ethers.providers.BlockTag | undefined, | ||
optionals?: OptionalChainIdLike | ||
): Promise<string> { | ||
return this.getProvider(optionals?.chainId).call(transaction, blockTag) | ||
async call(transaction: ethers.TransactionRequest, optionals?: OptionalChainIdLike): Promise<string> { | ||
return this.getProvider(optionals?.chainId).call(transaction) | ||
} | ||
@@ -194,7 +189,3 @@ | ||
async getGasPrice(optionals?: OptionalChainIdLike): Promise<ethers.BigNumber> { | ||
return this.getProvider(optionals?.chainId).getGasPrice() | ||
} | ||
async getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.providers.FeeData> { | ||
async getFeeData(optionals?: OptionalChainIdLike): Promise<ethers.FeeData> { | ||
return this.getProvider(optionals?.chainId).getFeeData() | ||
@@ -207,3 +198,3 @@ } | ||
// For some reason ethers.Signer expects this to return `string` | ||
// but ethers.providers.Provider expects this to return `string | null`. | ||
// but ethers.Provider expects this to return `string | null`. | ||
// The signer doesn't have any other source of information, so we'll | ||
@@ -222,15 +213,19 @@ // fail if the provider doesn't return a result. | ||
populateTransaction( | ||
_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest> | ||
): Promise<ethers.providers.TransactionRequest> { | ||
getNonce(_blockTag?: ethers.BlockTag): Promise<number> { | ||
throw new Error('SequenceSigner does not support getNonce') | ||
} | ||
populateCall(_transaction: ethers.TransactionRequest): Promise<ethers.TransactionLike<string>> { | ||
throw new Error('SequenceSigner does not support populateCall') | ||
} | ||
populateTransaction(_transaction: ethers.TransactionRequest): Promise<ethers.TransactionLike<string>> { | ||
throw new Error('SequenceSigner does not support populateTransaction') | ||
} | ||
checkTransaction( | ||
_transaction: ethers.utils.Deferrable<ethers.providers.TransactionRequest> | ||
): ethers.utils.Deferrable<ethers.providers.TransactionRequest> { | ||
checkTransaction(_transaction: ethers.TransactionRequest): ethers.TransactionRequest { | ||
throw new Error('SequenceSigner does not support checkTransaction') | ||
} | ||
getTransactionCount(_blockTag?: ethers.providers.BlockTag | undefined): Promise<number> { | ||
getTransactionCount(_blockTag?: ethers.BlockTag): Promise<number> { | ||
// We could try returning the sequence nonce here | ||
@@ -241,3 +236,3 @@ // but we aren't sure how ethers will use this nonce | ||
signTransaction(_transaction: ethers.utils.Deferrable<commons.transaction.Transactionish>): Promise<string> { | ||
signTransaction(_transaction: commons.transaction.Transactionish): Promise<string> { | ||
// We could implement signTransaction/sendTransaction here | ||
@@ -244,0 +239,0 @@ // but first we need a way of serializing these signed transactions |
@@ -15,3 +15,3 @@ import { walletContracts } from '@0xsequence/abi' | ||
'updateImplementation(address)' | ||
].map(signature => [ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)).slice(0, 10), signature]) | ||
].map(signature => [ethers.id(signature).slice(0, 10), signature]) | ||
) | ||
@@ -28,3 +28,3 @@ | ||
if (transaction.data) { | ||
const data = ethers.utils.arrayify(transaction.data) | ||
const data = ethers.getBytes(transaction.data) | ||
if (data.length >= 4 && !isCreateContractCall(data)) { | ||
@@ -41,3 +41,3 @@ throw new Error('self calls are forbidden') | ||
if (transaction.data) { | ||
const data = ethers.utils.hexlify(transaction.data) | ||
const data = ethers.hexlify(transaction.data) | ||
const selector = data.slice(0, 10) | ||
@@ -53,3 +53,3 @@ const signature = PROHIBITED_FUNCTIONS.get(selector) | ||
function isCreateContractCall(data: ethers.BytesLike): boolean { | ||
const walletInterface = new ethers.utils.Interface(walletContracts.mainModule.abi) | ||
const walletInterface = new ethers.Interface(walletContracts.mainModule.abi) | ||
try { | ||
@@ -56,0 +56,0 @@ walletInterface.decodeFunctionData('createContract', data) |
@@ -20,6 +20,6 @@ import { EventEmitter2 as EventEmitter } from 'eventemitter2' | ||
import { NetworkConfig, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network' | ||
import { NetworkConfig } from '@0xsequence/network' | ||
import { logger } from '@0xsequence/utils' | ||
import { ethers } from 'ethers' | ||
import { commons } from '@0xsequence/core' | ||
import { VERSION, commons } from '@0xsequence/core' | ||
@@ -93,5 +93,3 @@ export const PROVIDER_OPEN_TIMEOUT = 30000 // in ms | ||
sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { | ||
// here, we receive the message from the dapp provider call | ||
async request(request: { method: string; params?: any[]; chainId?: number }): Promise<any> { | ||
if (this.state === OpenState.CLOSED) { | ||
@@ -109,20 +107,17 @@ // flag the wallet to auto-close once user submits input. ie. | ||
// TODO: how does this behave with a session has expired? | ||
this.openWallet(undefined, { type: 'jsonRpcRequest', method: request.method }, chainId) | ||
this.openWallet(undefined, { type: 'jsonRpcRequest', method: request.method }, request.chainId) | ||
// send message request, await, and then execute callback after receiving the response | ||
try { | ||
if (!this.isOpened()) { | ||
await this.waitUntilOpened() // will throw on timeout | ||
} | ||
if (!this.isOpened()) { | ||
await this.waitUntilOpened() // will throw on timeout | ||
} | ||
const response = await this.sendMessageRequest({ | ||
idx: nextMessageIdx(), | ||
type: EventType.MESSAGE, | ||
data: request, | ||
chainId: chainId | ||
}) | ||
callback(undefined, response.data) | ||
} catch (err) { | ||
callback(err) | ||
} | ||
const response = await this.sendMessageRequest({ | ||
idx: nextMessageIdx(), | ||
type: EventType.MESSAGE, | ||
data: request, | ||
chainId: request.chainId, | ||
clientVersion: VERSION | ||
}) | ||
return response.data | ||
} | ||
@@ -148,3 +143,4 @@ | ||
nonce: nonce | ||
} | ||
}, | ||
clientVersion: VERSION | ||
}) | ||
@@ -235,3 +231,3 @@ } | ||
this.accountsChangedPayload = { | ||
accounts: [ethers.utils.getAddress(message.data[0])], | ||
accounts: [ethers.getAddress(message.data[0])], | ||
origin: message.origin | ||
@@ -238,0 +234,0 @@ } |
@@ -17,3 +17,3 @@ import { ethers } from 'ethers' | ||
import { NetworkConfig, JsonRpcRequest, JsonRpcResponseCallback, findSupportedNetwork } from '@0xsequence/network' | ||
import { NetworkConfig, findSupportedNetwork } from '@0xsequence/network' | ||
import { logger, sanitizeAlphanumeric, sanitizeHost, sanitizeNumberString } from '@0xsequence/utils' | ||
@@ -24,3 +24,3 @@ import { AuthorizationOptions } from '@0xsequence/auth' | ||
import { isBrowserExtension, useBestStore } from '../utils' | ||
import { commons } from '@0xsequence/core' | ||
import { VERSION, commons } from '@0xsequence/core' | ||
@@ -70,3 +70,3 @@ const TRANSPORT_SESSION_LS_KEY = '@sequence.transportSession' | ||
} else { | ||
this.notifyChainChanged(ethers.utils.hexValue(networks.find(network => network.isDefaultChain)!.chainId)) | ||
this.notifyChainChanged(ethers.toQuantity(networks.find(network => network.isDefaultChain)!.chainId)) | ||
} | ||
@@ -102,3 +102,3 @@ }) | ||
sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { | ||
request(request: { method: string; params?: any[]; chainId?: number }): Promise<any> { | ||
throw new Error('abstract method') | ||
@@ -188,3 +188,4 @@ } | ||
error | ||
} | ||
}, | ||
clientVersion: VERSION | ||
}) | ||
@@ -197,3 +198,4 @@ } | ||
type: EventType.CLOSE, | ||
data: error ? { error } : null | ||
data: error ? { error } : null, | ||
clientVersion: VERSION | ||
}) | ||
@@ -206,3 +208,4 @@ } | ||
type: EventType.CONNECT, | ||
data: connectDetails | ||
data: connectDetails, | ||
clientVersion: VERSION | ||
}) | ||
@@ -216,3 +219,4 @@ } | ||
data: error ? { error } : null, | ||
origin | ||
origin, | ||
clientVersion: VERSION | ||
}) | ||
@@ -226,3 +230,4 @@ } | ||
data: accounts, | ||
origin | ||
origin, | ||
clientVersion: VERSION | ||
}) | ||
@@ -236,3 +241,4 @@ } | ||
data: chainIdHex, | ||
origin | ||
origin, | ||
clientVersion: VERSION | ||
}) | ||
@@ -245,3 +251,4 @@ } | ||
type: EventType.NETWORKS, | ||
data: networks | ||
data: networks, | ||
clientVersion: VERSION | ||
}) | ||
@@ -254,3 +261,4 @@ } | ||
type: EventType.WALLET_CONTEXT, | ||
data: walletContext | ||
data: walletContext, | ||
clientVersion: VERSION | ||
}) | ||
@@ -324,3 +332,4 @@ } | ||
type: EventType.INIT, | ||
data: { nonce: this._initNonce } | ||
data: { nonce: this._initNonce }, | ||
clientVersion: VERSION | ||
}) | ||
@@ -327,0 +336,0 @@ this._init = InitState.SENT_NONCE |
@@ -12,3 +12,2 @@ import { | ||
import { JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network' | ||
import { ProxyMessageChannelPort, ProxyMessageProvider } from '../proxy-transport' | ||
@@ -19,2 +18,3 @@ import { Runtime } from 'webextension-polyfill' | ||
import { WindowMessageProvider } from '../window-transport' | ||
import { JsonRpcResponse } from '@0xsequence/network' | ||
@@ -203,8 +203,7 @@ export type MuxTransportTemplate = { | ||
sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { | ||
if (this.provider) { | ||
this.provider.sendAsync(request, callback, chainId) | ||
return | ||
request(request: { method: string; params?: any[]; chainId?: number }): Promise<any> { | ||
if (!this.provider) { | ||
throw new Error('impossible state, wallet must be opened first') | ||
} | ||
throw new Error('impossible state, wallet must be opened first') | ||
return this.provider.request(request) | ||
} | ||
@@ -211,0 +210,0 @@ |
@@ -6,2 +6,3 @@ import { BaseProviderTransport } from '../base-provider-transport' | ||
import { ProxyMessageChannelPort, ProxyEventTypes } from './proxy-message-channel' | ||
import { VERSION } from '@0xsequence/core' | ||
@@ -66,3 +67,4 @@ export class ProxyMessageProvider extends BaseProviderTransport { | ||
sessionId | ||
} | ||
}, | ||
clientVersion: VERSION | ||
}) | ||
@@ -76,3 +78,4 @@ } | ||
type: EventType.CLOSE, | ||
data: null | ||
data: null, | ||
clientVersion: VERSION | ||
}) | ||
@@ -79,0 +82,0 @@ this.close() |
@@ -9,10 +9,8 @@ import { Account, AccountStatus } from '@0xsequence/account' | ||
findSupportedNetwork, | ||
JsonRpcHandler, | ||
JsonRpcRequest, | ||
JsonRpcResponse, | ||
JsonRpcResponseCallback, | ||
NetworkConfig | ||
NetworkConfig, | ||
EIP1193Provider, | ||
JsonRpcResponse | ||
} from '@0xsequence/network' | ||
import { logger, TypedData } from '@0xsequence/utils' | ||
import { BigNumber, ethers, providers } from 'ethers' | ||
import { logger, toHexString, TypedData } from '@0xsequence/utils' | ||
import { ethers } from 'ethers' | ||
import { EventEmitter2 as EventEmitter } from 'eventemitter2' | ||
@@ -40,4 +38,2 @@ | ||
type ExternalProvider = providers.ExternalProvider | ||
const SIGNER_READY_TIMEOUT = 10000 | ||
@@ -50,3 +46,3 @@ | ||
export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, ProviderMessageRequestHandler { | ||
export class WalletRequestHandler implements EIP1193Provider, ProviderMessageRequestHandler { | ||
// signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined | ||
@@ -160,3 +156,3 @@ // value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course | ||
connected: true, | ||
chainId: ethers.utils.hexValue(chainId) | ||
chainId: ethers.toQuantity(chainId) | ||
} | ||
@@ -222,31 +218,33 @@ | ||
// ProviderMessageResponse to be sent over the transport | ||
sendMessageRequest(message: ProviderMessageRequest): Promise<ProviderMessageResponse> { | ||
return new Promise(resolve => { | ||
this.sendAsync( | ||
message.data, | ||
(error: any, response?: JsonRpcResponse) => { | ||
// TODO: if response includes data.error, why do we need a separate error argument here? | ||
async sendMessageRequest(message: ProviderMessageRequest): Promise<ProviderMessageResponse> { | ||
// Older versions of the client require the response to be jsonrpc wrapped | ||
const majorVersion = Number(message.clientVersion?.split('.')[0] || '0') | ||
const isJsonRpcResponse = majorVersion < 2 | ||
const jsonRpcResponse: JsonRpcResponse = { | ||
id: message.data.id!, | ||
jsonrpc: '2.0', | ||
result: null, | ||
error: undefined | ||
} | ||
const responseMessage: ProviderMessageResponse = { | ||
...message, | ||
data: response! | ||
} | ||
try { | ||
const result = await this.request({ | ||
method: message.data.method, | ||
params: message.data.params, | ||
chainId: message.chainId | ||
}) | ||
// NOTE: we always resolve here, are the sendAsync call will wrap any exceptions | ||
// in the error field of the response to ensure we send back to the user | ||
resolve(responseMessage) | ||
}, | ||
message.chainId | ||
) | ||
}) | ||
return { | ||
...message, | ||
data: isJsonRpcResponse ? { ...jsonRpcResponse, result } : result | ||
} | ||
} catch (error) { | ||
return { | ||
...message, | ||
data: isJsonRpcResponse ? { ...jsonRpcResponse, error } : error | ||
} | ||
} | ||
} | ||
// sendAsync implements the JsonRpcHandler interface for sending JsonRpcRequests to the wallet | ||
sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => { | ||
const response: JsonRpcResponse = { | ||
jsonrpc: '2.0', | ||
id: request.id!, | ||
result: null | ||
} | ||
async request(request: { method: string; params?: any[]; chainId?: number }): Promise<any> { | ||
await this.getAccount() | ||
@@ -263,8 +261,12 @@ | ||
const account = this.account | ||
if (!account) throw new Error('WalletRequestHandler: wallet account is not configured') | ||
if (!account) { | ||
throw new Error('WalletRequestHandler: wallet account is not configured') | ||
} | ||
// fetch the provider for the specific chain, or undefined will select defaultChain | ||
const provider = this.account?.providerFor(chainId ?? this.defaultChainId()) | ||
if (!provider) throw new Error(`WalletRequestHandler: wallet provider is not configured for chainId ${chainId}`) | ||
const jsonRpcProvider = provider instanceof ethers.providers.JsonRpcProvider ? provider : undefined | ||
const provider = this.account?.providerFor(request.chainId ?? this.defaultChainId()) | ||
if (!provider) { | ||
throw new Error(`WalletRequestHandler: wallet provider is not configured for chainId ${request.chainId}`) | ||
} | ||
const jsonRpcProvider = provider instanceof ethers.JsonRpcProvider ? provider : undefined | ||
@@ -277,5 +279,3 @@ switch (request.method) { | ||
const result = await jsonRpcProvider.send('net_version', []) | ||
response.result = result | ||
break | ||
return await jsonRpcProvider.send('net_version', []) | ||
} | ||
@@ -288,11 +288,7 @@ | ||
const result = await jsonRpcProvider.send('eth_chainId', []) | ||
response.result = result | ||
break | ||
return await jsonRpcProvider.send('eth_chainId', []) | ||
} | ||
case 'eth_accounts': { | ||
const walletAddress = account.address | ||
response.result = [walletAddress] | ||
break | ||
return [account.address] | ||
} | ||
@@ -303,4 +299,3 @@ | ||
const walletBalance = await provider.getBalance(accountAddress, blockTag) | ||
response.result = walletBalance.toHexString() | ||
break | ||
return toHexString(walletBalance) | ||
} | ||
@@ -340,2 +335,3 @@ | ||
const sequenceVerified = request.method === 'sequence_sign' | ||
if (this.prompter === null) { | ||
@@ -345,3 +341,3 @@ // prompter is null, so we'll sign from here | ||
prefixedMessage, | ||
chainId ?? this.defaultChainId(), | ||
request.chainId ?? this.defaultChainId(), | ||
sequenceVerified ? 'eip6492' : 'ignore' | ||
@@ -352,4 +348,4 @@ ) | ||
{ | ||
chainId: chainId, | ||
message: prefixedMessage, | ||
chainId: request.chainId, | ||
message: ethers.getBytes(prefixedMessage), | ||
eip6492: sequenceVerified | ||
@@ -362,3 +358,3 @@ }, | ||
if (sig && sig.length > 0) { | ||
response.result = sig | ||
return sig | ||
} else { | ||
@@ -368,3 +364,2 @@ // The user has declined the request when value is null | ||
} | ||
break | ||
} | ||
@@ -403,3 +398,3 @@ | ||
typedData.message, | ||
chainId ?? this.defaultChainId(), | ||
request.chainId ?? this.defaultChainId(), | ||
sequenceVerified ? 'eip6492' : 'ignore' | ||
@@ -410,3 +405,3 @@ ) | ||
{ | ||
chainId: chainId, | ||
chainId: request.chainId, | ||
typedData: typedData, | ||
@@ -420,3 +415,3 @@ eip6492: sequenceVerified | ||
if (sig && sig.length > 0) { | ||
response.result = sig | ||
return sig | ||
} else { | ||
@@ -426,3 +421,2 @@ // The user has declined the request when value is null | ||
} | ||
break | ||
} | ||
@@ -448,11 +442,11 @@ | ||
// prompter is null, so we'll send from here | ||
const txnResponse = await account.sendTransaction(transactionParams, chainId ?? this.defaultChainId()) | ||
const txnResponse = await account.sendTransaction(transactionParams, request.chainId ?? this.defaultChainId()) | ||
txnHash = txnResponse?.hash ?? '' | ||
} else { | ||
// prompt user to provide the response | ||
txnHash = await this.prompter.promptSendTransaction(transactionParams, chainId, this.connectOptions) | ||
txnHash = await this.prompter.promptSendTransaction(transactionParams, request.chainId, this.connectOptions) | ||
} | ||
if (txnHash) { | ||
response.result = txnHash | ||
return txnHash | ||
} else { | ||
@@ -462,3 +456,2 @@ // The user has declined the request when value is null | ||
} | ||
break | ||
} | ||
@@ -469,3 +462,3 @@ | ||
const [transaction] = request.params! | ||
const sender = ethers.utils.getAddress(transaction.from) | ||
const sender = ethers.getAddress(transaction.from) | ||
@@ -484,8 +477,6 @@ if (sender !== account.address) { | ||
// we will want to resolveProperties the big number values to hex strings | ||
response.result = await account.signTransactions(transaction, chainId ?? this.defaultChainId()) | ||
return await account.signTransactions(transaction, request.chainId ?? this.defaultChainId()) | ||
} else { | ||
response.result = await this.prompter.promptSignTransaction(transaction, chainId, this.connectOptions) | ||
return await this.prompter.promptSignTransaction(transaction, request.chainId, this.connectOptions) | ||
} | ||
break | ||
} | ||
@@ -499,14 +490,13 @@ | ||
if (commons.transaction.isSignedTransactionBundle(request.params![0])) { | ||
const txChainId = BigNumber.from(request.params![0].chainId).toNumber() | ||
const txChainId = Number(request.params![0].chainId) | ||
const tx = await account.relayer(txChainId)!.relay(request.params![0]) | ||
response.result = tx.hash | ||
return tx.hash | ||
} else { | ||
const tx = await provider.sendTransaction(request.params![0]) | ||
response.result = tx.hash | ||
const tx = await provider.broadcastTransaction(request.params![0]) | ||
return tx.hash | ||
} | ||
break | ||
} | ||
case 'eth_getTransactionCount': { | ||
const address = ethers.utils.getAddress(request.params![0] as string) | ||
const address = ethers.getAddress(request.params![0] as string) | ||
const tag = request.params![1] | ||
@@ -518,25 +508,19 @@ | ||
const count = await provider.getTransactionCount(address, tag) | ||
response.result = ethers.BigNumber.from(count).toHexString() | ||
break | ||
return toHexString(BigInt(count)) | ||
} | ||
case 'eth_blockNumber': { | ||
response.result = await provider.getBlockNumber() | ||
break | ||
return await provider.getBlockNumber() | ||
} | ||
case 'eth_getBlockByNumber': { | ||
response.result = await provider.getBlock(request.params![0] /* , jsonRpcRequest.params[1] */) | ||
break | ||
return await provider.getBlock(request.params![0] /* , jsonRpcRequest.params[1] */) | ||
} | ||
case 'eth_getBlockByHash': { | ||
response.result = await provider.getBlock(request.params![0] /* , jsonRpcRequest.params[1] */) | ||
break | ||
return await provider.getBlock(request.params![0] /* , jsonRpcRequest.params[1] */) | ||
} | ||
case 'eth_getTransactionByHash': { | ||
response.result = await provider.getTransaction(request.params![0]) | ||
break | ||
return await provider.getTransaction(request.params![0]) | ||
} | ||
@@ -546,4 +530,3 @@ | ||
const [transactionObject, blockTag] = request.params! | ||
response.result = await provider.call(transactionObject, blockTag) | ||
break | ||
return await provider.call({ ...transactionObject, blockTag }) | ||
} | ||
@@ -553,4 +536,3 @@ | ||
const [contractAddress, blockTag] = request.params! | ||
response.result = await provider.getCode(contractAddress, blockTag) | ||
break | ||
return await provider.getCode(contractAddress, blockTag) | ||
} | ||
@@ -560,10 +542,8 @@ | ||
const [transactionObject] = request.params! | ||
response.result = await provider.estimateGas(transactionObject) | ||
break | ||
return await provider.estimateGas(transactionObject) | ||
} | ||
case 'eth_gasPrice': { | ||
const gasPrice = await provider.getGasPrice() | ||
response.result = gasPrice.toHexString() | ||
break | ||
const feeData = await provider.getFeeData() | ||
return feeData.gasPrice === null ? null : toHexString(feeData.gasPrice) | ||
} | ||
@@ -577,8 +557,7 @@ | ||
const chainId = ethers.BigNumber.from(switchParams.chainId) | ||
const chainId = BigInt(switchParams.chainId) | ||
this.setDefaultChainId(chainId.toNumber()) | ||
this.setDefaultChainId(Number(chainId)) | ||
response.result = null // success | ||
break | ||
return null // success | ||
} | ||
@@ -588,4 +567,3 @@ | ||
case 'sequence_getWalletContext': { | ||
response.result = account.contexts | ||
break | ||
return account.contexts | ||
} | ||
@@ -597,5 +575,5 @@ | ||
if (chainId) { | ||
response.result = [(await account.status(chainId)).onChain.config] | ||
return [(await account.status(chainId)).onChain.config] | ||
} else { | ||
response.result = await Promise.all( | ||
return await Promise.all( | ||
account.networks.map(async network => { | ||
@@ -607,3 +585,2 @@ const status = await account.status(network.chainId) | ||
} | ||
break | ||
} | ||
@@ -616,5 +593,5 @@ | ||
if (chainId) { | ||
response.result = [getLegacyWalletState(chainId, await account.status(chainId))] | ||
return [getLegacyWalletState(chainId, await account.status(chainId))] | ||
} else { | ||
response.result = await Promise.all( | ||
return await Promise.all( | ||
account.networks.map(async network => { | ||
@@ -626,3 +603,2 @@ const status = await account.status(network.chainId) | ||
} | ||
break | ||
} | ||
@@ -635,9 +611,7 @@ | ||
// This is handled by this.getNetworks() but noted here for future readers. | ||
response.result = await this.getNetworks(true) | ||
break | ||
return await this.getNetworks(true) | ||
} | ||
case 'sequence_isSequence': { | ||
response.result = true | ||
break | ||
return true | ||
} | ||
@@ -653,4 +627,3 @@ | ||
// const [newConfig] = request.params | ||
// response.result = await signer.updateConfig(newConfig) | ||
break | ||
// return await signer.updateConfig(newConfig) | ||
} | ||
@@ -661,3 +634,2 @@ | ||
throw new Error('sequence_publishConfig method is not allowed from a dapp') | ||
break | ||
} | ||
@@ -692,4 +664,3 @@ | ||
this.setDefaultChainId(defaultChainId) | ||
response.result = await this.getNetworks(true) | ||
break | ||
return await this.getNetworks(true) | ||
} | ||
@@ -703,4 +674,3 @@ | ||
// NOTE: provider here will be chain-bound if chainId is provided | ||
const providerResponse = await jsonRpcProvider.send(request.method, request.params!) | ||
response.result = providerResponse | ||
return await jsonRpcProvider.send(request.method, request.params!) | ||
} | ||
@@ -710,12 +680,4 @@ } | ||
logger.error(err) | ||
// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md#rpc-errors | ||
response.result = null | ||
response.error = { | ||
...new Error(err), | ||
code: 4001 | ||
} | ||
throw { message: err?.message, code: 4001 } as ProviderRpcError | ||
} | ||
callback(undefined, response) | ||
} | ||
@@ -749,3 +711,2 @@ | ||
this._connectOptions = options | ||
this.onConnectOptionsChange?.(options) | ||
@@ -819,3 +780,3 @@ } | ||
notifyChainChanged(chainId: number, origin?: string) { | ||
this.events.emit('chainChanged', ethers.utils.hexValue(chainId), origin) | ||
this.events.emit('chainChanged', ethers.toQuantity(chainId), origin) | ||
} | ||
@@ -829,3 +790,3 @@ | ||
if (defaultNetwork) { | ||
this.events.emit('chainChanged', ethers.utils.hexValue(defaultNetwork.chainId)) | ||
this.events.emit('chainChanged', ethers.toQuantity(defaultNetwork.chainId)) | ||
} | ||
@@ -832,0 +793,0 @@ } else { |
@@ -13,3 +13,4 @@ import { | ||
import { BaseWalletTransport } from '../base-wallet-transport' | ||
import { logger, sanitizeNumberString, base64DecodeObject } from '@0xsequence/utils' | ||
import { logger, base64DecodeObject } from '@0xsequence/utils' | ||
import { ethers } from 'ethers' | ||
@@ -34,3 +35,3 @@ export class WindowMessageHandler extends BaseWalletTransport { | ||
// record open details (sessionId + default network) from the window url | ||
const { pathname, search: rawParams } = new URL(windowHref || window.location.href) | ||
const { search: rawParams } = new URL(windowHref || window.location.href) | ||
@@ -97,3 +98,10 @@ let session: TransportSession | null = this.getWindowTransportSession(rawParams) | ||
try { | ||
request = JSON.parse(event.data) | ||
request = JSON.parse(event.data, (key, value) => { | ||
// BigNumber compatibility with older versions of sequence.js | ||
if (isBigNumberSerialized(value)) { | ||
return BigInt(value.hex) | ||
} | ||
return value | ||
}) | ||
} catch (err) { | ||
@@ -167,1 +175,5 @@ // event is not a ProviderMessage JSON object, skip | ||
} | ||
const isBigNumberSerialized = (value: any): boolean => { | ||
return typeof value === 'object' && value.type === 'BigNumber' && ethers.isHexString(value.hex) | ||
} |
@@ -1,2 +0,2 @@ | ||
import { OpenWalletIntent, ProviderMessage, InitState, EventType, WindowSessionParams } from '../../types' | ||
import { OpenWalletIntent, ProviderMessage, InitState, WindowSessionParams } from '../../types' | ||
import { BaseProviderTransport } from '../base-provider-transport' | ||
@@ -3,0 +3,0 @@ import { logger, base64EncodeObject } from '@0xsequence/utils' |
@@ -5,11 +5,11 @@ import { ETHAuthProof as AuthETHAuthProof } from '@0xsequence/auth' | ||
ChainIdLike, | ||
JsonRpcHandler, | ||
EIP1193Provider, | ||
JsonRpcRequest, | ||
JsonRpcResponse, | ||
NetworkConfig, | ||
ProviderRpcError as NetworkProviderRpcError | ||
JsonRpcErrorPayload | ||
} from '@0xsequence/network' | ||
import { TypedData } from '@0xsequence/utils' | ||
export interface ProviderTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
export interface ProviderTransport extends EIP1193Provider, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
register(): void | ||
@@ -46,3 +46,3 @@ unregister(): void | ||
export interface WalletTransport extends JsonRpcHandler, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
export interface WalletTransport extends EIP1193Provider, ProviderMessageTransport, ProviderMessageRequestHandler { | ||
register(): void | ||
@@ -66,2 +66,3 @@ unregister(): void | ||
origin?: string // origin of the message | ||
clientVersion: string // client version of the message | ||
} | ||
@@ -71,3 +72,4 @@ | ||
export type ProviderMessageResponse = ProviderMessage<JsonRpcResponse> | ||
// Older versions of sequence.js will require a JsonRpcResponse result type, but newer versions use raw EIP1193 results | ||
export type ProviderMessageResponse = ProviderMessage<JsonRpcResponse | any> | ||
@@ -79,3 +81,3 @@ // ProviderMessageCallback is used to respond to ProviderMessage requests. The error | ||
export type ProviderRpcError = NetworkProviderRpcError | ||
export type ProviderRpcError = JsonRpcErrorPayload | ||
@@ -381,6 +383,1 @@ export interface ProviderMessageRequestHandler { | ||
| undefined | ||
// This is required by viem, it expects a provider to have an EIP-1193 compliant `request` attribute. | ||
export interface EIP1193Provider { | ||
request: (request: { method: string; params?: Array<any> }) => Promise<any> | ||
} |
@@ -1,2 +0,2 @@ | ||
import { ethers, BytesLike } from 'ethers' | ||
import { ethers } from 'ethers' | ||
import { messageIsExemptFromEIP191Prefix } from './eip191exceptions' | ||
@@ -7,13 +7,13 @@ import { AccountStatus } from '@0xsequence/account' | ||
const eip191prefix = ethers.utils.toUtf8Bytes('\x19Ethereum Signed Message:\n') | ||
const eip191prefix = ethers.toUtf8Bytes('\x19Ethereum Signed Message:\n') | ||
export const messageToBytes = (message: BytesLike): Uint8Array => { | ||
if (ethers.utils.isBytesLike(message)) { | ||
return ethers.utils.arrayify(message) | ||
export const messageToBytes = (message: ethers.BytesLike): Uint8Array => { | ||
if (ethers.isBytesLike(message)) { | ||
return ethers.getBytes(message) | ||
} | ||
return ethers.utils.toUtf8Bytes(message) | ||
return ethers.toUtf8Bytes(message) | ||
} | ||
export const prefixEIP191Message = (message: BytesLike): Uint8Array => { | ||
export const prefixEIP191Message = (message: ethers.BytesLike): Uint8Array => { | ||
const messageBytes = messageToBytes(message) | ||
@@ -23,3 +23,3 @@ if (messageIsExemptFromEIP191Prefix(messageBytes)) { | ||
} else { | ||
return ethers.utils.concat([eip191prefix, ethers.utils.toUtf8Bytes(String(messageBytes.length)), messageBytes]) | ||
return ethers.getBytes(ethers.concat([eip191prefix, ethers.toUtf8Bytes(String(messageBytes.length)), messageBytes])) | ||
} | ||
@@ -52,5 +52,5 @@ } | ||
try { | ||
prefixAsNumber = Number(ethers.utils.toUtf8String(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength))) | ||
prefixAsNumber = Number(ethers.toUtf8String(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength))) | ||
} catch { | ||
prefixAsNumber = Number(ethers.utils.hexlify(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength))) | ||
prefixAsNumber = Number(ethers.hexlify(ethereumSignedMessagePartSlicedArray.slice(0, maxPrefixCharLength))) | ||
} | ||
@@ -73,3 +73,3 @@ | ||
sig: string, | ||
provider: ethers.providers.Provider | ||
provider: ethers.Provider | ||
): Promise<boolean> => { | ||
@@ -85,3 +85,3 @@ const reader = new commons.reader.OnChainReader(provider) | ||
signature: string, | ||
provider: ethers.providers.Provider | ||
provider: ethers.Provider | ||
): Promise<boolean> => { | ||
@@ -98,3 +98,3 @@ const prefixed = prefixEIP191Message(message) | ||
signature: string, | ||
provider: ethers.providers.Provider | ||
provider: ethers.Provider | ||
): Promise<boolean> => { | ||
@@ -209,11 +209,9 @@ return isValidSignature(address, encodeTypedDataDigest(typedData), signature, provider) | ||
export async function resolveArrayProperties<T>( | ||
object: Readonly<ethers.utils.Deferrable<T>> | Readonly<ethers.utils.Deferrable<T>>[] | ||
): Promise<T> { | ||
export async function resolveArrayProperties<T>(object: Readonly<T> | Readonly<T>[]): Promise<T> { | ||
if (Array.isArray(object)) { | ||
// T must include array type | ||
return Promise.all(object.map(o => ethers.utils.resolveProperties(o))) as any | ||
return Promise.all(object.map(o => ethers.resolveProperties(o))) as any | ||
} | ||
return ethers.utils.resolveProperties(object) | ||
return ethers.resolveProperties(object) | ||
} |
@@ -1,2 +0,2 @@ | ||
import { BytesLike, TypedDataDomain, TypedDataField } from 'ethers' | ||
import { ethers } from 'ethers' | ||
import { ChainIdLike } from '@0xsequence/network' | ||
@@ -20,3 +20,3 @@ import { encodeMessageDigest, TypedData, encodeTypedDataDigest } from '@0xsequence/utils' | ||
// Sign message on a specified chain, or DefaultChain by default | ||
signMessage(message: BytesLike, chainId?: ChainIdLike, eip6492?: boolean): Promise<string> { | ||
signMessage(message: ethers.BytesLike, chainId?: ChainIdLike, eip6492?: boolean): Promise<string> { | ||
return this.signer.signMessage(message, { chainId, eip6492 }) | ||
@@ -27,4 +27,4 @@ } | ||
signTypedData( | ||
domain: TypedDataDomain, | ||
types: Record<string, Array<TypedDataField>>, | ||
domain: ethers.TypedDataDomain, | ||
types: Record<string, Array<ethers.TypedDataField>>, | ||
message: Record<string, any>, | ||
@@ -31,0 +31,0 @@ chainId?: ChainIdLike, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
17864
699787
+ Added@0xsequence/abi@0.0.0-20240812142652(transitive)
+ Added@0xsequence/account@0.0.0-20240812142652(transitive)
+ Added@0xsequence/api@0.0.0-20240812142652(transitive)
+ Added@0xsequence/auth@0.0.0-20240812142652(transitive)
+ Added@0xsequence/core@0.0.0-20240812142652(transitive)
+ Added@0xsequence/ethauth@1.0.0(transitive)
+ Added@0xsequence/indexer@0.0.0-20240812142652(transitive)
+ Added@0xsequence/metadata@0.0.0-20240812142652(transitive)
+ Added@0xsequence/migration@0.0.0-20240812142652(transitive)
+ Added@0xsequence/network@0.0.0-20240812142652(transitive)
+ Added@0xsequence/relayer@0.0.0-20240812142652(transitive)
+ Added@0xsequence/replacer@0.0.0-20240812142652(transitive)
+ Added@0xsequence/sessions@0.0.0-20240812142652(transitive)
+ Added@0xsequence/signhub@0.0.0-20240812142652(transitive)
+ Added@0xsequence/utils@0.0.0-20240812142652(transitive)
+ Added@0xsequence/wallet@0.0.0-20240812142652(transitive)
+ Added@adraffy/ens-normalize@1.10.1(transitive)
+ Added@noble/curves@1.2.0(transitive)
+ Added@noble/hashes@1.3.2(transitive)
+ Added@types/node@18.15.13(transitive)
+ Addedaes-js@4.0.0-beta.5(transitive)
+ Addedethers@6.13.2(transitive)
+ Addedtslib@2.4.0(transitive)
+ Addedws@8.17.1(transitive)
- Removed@0xsequence/abi@0.0.0-20240807210827(transitive)
- Removed@0xsequence/account@0.0.0-20240807210827(transitive)
- Removed@0xsequence/api@0.0.0-20240807210827(transitive)
- Removed@0xsequence/auth@0.0.0-20240807210827(transitive)
- Removed@0xsequence/core@0.0.0-20240807210827(transitive)
- Removed@0xsequence/ethauth@0.8.1(transitive)
- Removed@0xsequence/indexer@0.0.0-20240807210827(transitive)
- Removed@0xsequence/metadata@0.0.0-20240807210827(transitive)
- Removed@0xsequence/migration@0.0.0-20240807210827(transitive)
- Removed@0xsequence/network@0.0.0-20240807210827(transitive)
- Removed@0xsequence/relayer@0.0.0-20240807210827(transitive)
- Removed@0xsequence/replacer@0.0.0-20240807210827(transitive)
- Removed@0xsequence/sessions@0.0.0-20240807210827(transitive)
- Removed@0xsequence/signhub@0.0.0-20240807210827(transitive)
- Removed@0xsequence/utils@0.0.0-20240807210827(transitive)
- Removed@0xsequence/wallet@0.0.0-20240807210827(transitive)
- Removed@ethersproject/abi@5.7.0(transitive)
- Removed@ethersproject/abstract-provider@5.7.0(transitive)
- Removed@ethersproject/abstract-signer@5.7.0(transitive)
- Removed@ethersproject/address@5.7.0(transitive)
- Removed@ethersproject/base64@5.7.0(transitive)
- Removed@ethersproject/basex@5.7.0(transitive)
- Removed@ethersproject/bignumber@5.7.0(transitive)
- Removed@ethersproject/bytes@5.7.0(transitive)
- Removed@ethersproject/constants@5.7.0(transitive)
- Removed@ethersproject/contracts@5.7.0(transitive)
- Removed@ethersproject/hash@5.7.0(transitive)
- Removed@ethersproject/hdnode@5.7.0(transitive)
- Removed@ethersproject/json-wallets@5.7.0(transitive)
- Removed@ethersproject/keccak256@5.7.0(transitive)
- Removed@ethersproject/logger@5.7.0(transitive)
- Removed@ethersproject/networks@5.7.1(transitive)
- Removed@ethersproject/pbkdf2@5.7.0(transitive)
- Removed@ethersproject/properties@5.7.0(transitive)
- Removed@ethersproject/providers@5.7.2(transitive)
- Removed@ethersproject/random@5.7.0(transitive)
- Removed@ethersproject/rlp@5.7.0(transitive)
- Removed@ethersproject/sha2@5.7.0(transitive)
- Removed@ethersproject/signing-key@5.7.0(transitive)
- Removed@ethersproject/solidity@5.7.0(transitive)
- Removed@ethersproject/strings@5.7.0(transitive)
- Removed@ethersproject/transactions@5.7.0(transitive)
- Removed@ethersproject/units@5.7.0(transitive)
- Removed@ethersproject/wallet@5.7.0(transitive)
- Removed@ethersproject/web@5.7.1(transitive)
- Removed@ethersproject/wordlists@5.7.0(transitive)
- Removedaes-js@3.0.0(transitive)
- Removedbech32@1.1.4(transitive)
- Removedbn.js@4.12.05.2.1(transitive)
- Removedbrorand@1.1.0(transitive)
- Removedelliptic@6.5.4(transitive)
- Removedethers@5.7.2(transitive)
- Removedhash.js@1.1.7(transitive)
- Removedhmac-drbg@1.0.1(transitive)
- Removedinherits@2.0.4(transitive)
- Removedjs-sha3@0.8.0(transitive)
- Removedminimalistic-assert@1.0.1(transitive)
- Removedminimalistic-crypto-utils@1.0.1(transitive)
- Removedscrypt-js@3.0.1(transitive)
- Removedws@7.4.6(transitive)