@imtbl/wallet 2.12.5-alpha.8 → 2.12.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/index.js +202 -29
- package/dist/node/index.cjs +241 -56
- package/dist/node/index.js +202 -29
- package/dist/types/confirmation/confirmation.d.ts +1 -1
- package/dist/types/connectWallet.d.ts +2 -3
- package/dist/types/constants.d.ts +7 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/network/chainRegistry.d.ts +13 -0
- package/dist/types/{presets.d.ts → network/presets.d.ts} +37 -1
- package/dist/types/sequence/sequenceProvider.d.ts +21 -0
- package/dist/types/sequence/signer/identityInstrumentSigner.d.ts +15 -0
- package/dist/types/sequence/signer/index.d.ts +20 -0
- package/dist/types/sequence/signer/privateKeySigner.d.ts +15 -0
- package/dist/types/sequence/signer/types.d.ts +14 -0
- package/dist/types/sequence/user/index.d.ts +2 -0
- package/dist/types/sequence/user/registerUser.d.ts +18 -0
- package/dist/types/types.d.ts +22 -1
- package/dist/types/zkEvm/types.d.ts +3 -10
- package/package.json +9 -4
- package/src/confirmation/confirmation.ts +14 -4
- package/src/connectWallet.test.ts +62 -3
- package/src/connectWallet.ts +82 -45
- package/src/constants.ts +10 -0
- package/src/guardian/index.ts +2 -0
- package/src/index.ts +14 -2
- package/src/network/chainRegistry.test.ts +64 -0
- package/src/network/chainRegistry.ts +74 -0
- package/src/{presets.ts → network/presets.ts} +64 -2
- package/src/sequence/sequenceProvider.ts +276 -0
- package/src/sequence/signer/identityInstrumentSigner.ts +193 -0
- package/src/sequence/signer/index.ts +45 -0
- package/src/sequence/signer/privateKeySigner.ts +111 -0
- package/src/sequence/signer/types.ts +24 -0
- package/src/sequence/user/index.ts +2 -0
- package/src/sequence/user/registerUser.ts +100 -0
- package/src/types.ts +26 -2
- package/src/zkEvm/types.ts +4 -10
|
@@ -15,7 +15,7 @@ export default class ConfirmationScreen {
|
|
|
15
15
|
constructor(config: IAuthConfiguration);
|
|
16
16
|
private getHref;
|
|
17
17
|
requestConfirmation(transactionId: string, etherAddress: string, chainType: GeneratedClients.mr.TransactionApprovalRequestChainTypeEnum, chainId?: string): Promise<ConfirmationResult>;
|
|
18
|
-
requestMessageConfirmation(messageID: string, etherAddress: string, messageType
|
|
18
|
+
requestMessageConfirmation(messageID: string, etherAddress: string, messageType: MessageType, chainId: string): Promise<ConfirmationResult>;
|
|
19
19
|
showServiceUnavailable(): Promise<void>;
|
|
20
20
|
loading(popupOptions?: {
|
|
21
21
|
width: number;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ConnectWalletOptions } from './types';
|
|
1
|
+
import { ConnectWalletOptions, Provider } from './types';
|
|
3
2
|
/**
|
|
4
3
|
* Connect wallet with the provided configuration
|
|
5
4
|
*
|
|
@@ -32,4 +31,4 @@ import { ConnectWalletOptions } from './types';
|
|
|
32
31
|
* });
|
|
33
32
|
* ```
|
|
34
33
|
*/
|
|
35
|
-
export declare function connectWallet(config?: ConnectWalletOptions): Promise<
|
|
34
|
+
export declare function connectWallet(config?: ConnectWalletOptions): Promise<Provider>;
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
export declare const IMMUTABLE_ZKEVM_MAINNET_CHAIN_ID = 13371;
|
|
6
6
|
/** Immutable zkEVM Testnet chain ID */
|
|
7
7
|
export declare const IMMUTABLE_ZKEVM_TESTNET_CHAIN_ID = 13473;
|
|
8
|
+
/**
|
|
9
|
+
* Chain ID constants for Arbitrum networks
|
|
10
|
+
*/
|
|
11
|
+
/** Arbitrum One Mainnet chain ID */
|
|
12
|
+
export declare const ARBITRUM_ONE_CHAIN_ID = 42161;
|
|
13
|
+
/** Arbitrum Sepolia Testnet chain ID */
|
|
14
|
+
export declare const ARBITRUM_SEPOLIA_CHAIN_ID = 421614;
|
|
8
15
|
/**
|
|
9
16
|
* Magic configuration for Immutable networks
|
|
10
17
|
* @internal
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { connectWallet } from './connectWallet';
|
|
2
|
-
export { IMMUTABLE_ZKEVM_MAINNET_CHAIN_ID, IMMUTABLE_ZKEVM_TESTNET_CHAIN_ID, } from './constants';
|
|
3
|
-
export { IMMUTABLE_ZKEVM_MAINNET, IMMUTABLE_ZKEVM_TESTNET, IMMUTABLE_ZKEVM_MULTICHAIN, IMMUTABLE_ZKEVM_MAINNET_CHAIN, IMMUTABLE_ZKEVM_TESTNET_CHAIN, DEFAULT_CHAINS, } from './presets';
|
|
2
|
+
export { IMMUTABLE_ZKEVM_MAINNET_CHAIN_ID, IMMUTABLE_ZKEVM_TESTNET_CHAIN_ID, ARBITRUM_ONE_CHAIN_ID, ARBITRUM_SEPOLIA_CHAIN_ID, } from './constants';
|
|
3
|
+
export { IMMUTABLE_ZKEVM_MAINNET, IMMUTABLE_ZKEVM_TESTNET, IMMUTABLE_ZKEVM_MULTICHAIN, IMMUTABLE_ZKEVM_MAINNET_CHAIN, IMMUTABLE_ZKEVM_TESTNET_CHAIN, DEFAULT_CHAINS, ARBITRUM_ONE, ARBITRUM_SEPOLIA, ARBITRUM_ONE_CHAIN, ARBITRUM_SEPOLIA_CHAIN, } from './network/presets';
|
|
4
|
+
export { getChainConfig, getEvmChainFromChainId } from './network/chainRegistry';
|
|
4
5
|
export { ZkEvmProvider } from './zkEvm/zkEvmProvider';
|
|
6
|
+
export { SequenceProvider } from './sequence/sequenceProvider';
|
|
5
7
|
export { WalletConfiguration } from './config';
|
|
6
8
|
export * from './types';
|
|
7
9
|
export { WalletError, WalletErrorType } from './errors';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Environment } from '@imtbl/config';
|
|
2
|
+
import { ChainConfig, EvmChain } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Get chain config for non-zkEVM chains
|
|
5
|
+
* @throws Error if chain is not in registry
|
|
6
|
+
*/
|
|
7
|
+
export declare function getChainConfig(chain: Exclude<EvmChain, EvmChain.ZKEVM>, environment: Environment): ChainConfig;
|
|
8
|
+
/**
|
|
9
|
+
* Get EvmChain from chainId
|
|
10
|
+
* @param chainId - Chain ID (can be number or string like "eip155:42161")
|
|
11
|
+
* @returns EvmChain enum value, defaults to ZKEVM if not found
|
|
12
|
+
*/
|
|
13
|
+
export declare function getEvmChainFromChainId(chainId: string | number): EvmChain;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChainConfig } from '
|
|
1
|
+
import { ChainConfig } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Immutable zkEVM Mainnet chain configuration
|
|
4
4
|
*/
|
|
@@ -7,6 +7,14 @@ export declare const IMMUTABLE_ZKEVM_MAINNET_CHAIN: ChainConfig;
|
|
|
7
7
|
* Immutable zkEVM Testnet chain configuration
|
|
8
8
|
*/
|
|
9
9
|
export declare const IMMUTABLE_ZKEVM_TESTNET_CHAIN: ChainConfig;
|
|
10
|
+
/**
|
|
11
|
+
* Arbitrum One Mainnet chain configuration
|
|
12
|
+
*/
|
|
13
|
+
export declare const ARBITRUM_ONE_CHAIN: ChainConfig;
|
|
14
|
+
/**
|
|
15
|
+
* Arbitrum Sepolia Testnet chain configuration
|
|
16
|
+
*/
|
|
17
|
+
export declare const ARBITRUM_SEPOLIA_CHAIN: ChainConfig;
|
|
10
18
|
/**
|
|
11
19
|
* Default chains (testnet + mainnet)
|
|
12
20
|
* Testnet is first (default initial chain)
|
|
@@ -56,3 +64,31 @@ export declare const IMMUTABLE_ZKEVM_TESTNET: {
|
|
|
56
64
|
export declare const IMMUTABLE_ZKEVM_MULTICHAIN: {
|
|
57
65
|
chains: ChainConfig[];
|
|
58
66
|
};
|
|
67
|
+
/**
|
|
68
|
+
* Arbitrum mainnet only preset
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* const provider = await connectWallet({
|
|
73
|
+
* ...ARBITRUM_ONE_MAINNET,
|
|
74
|
+
* auth,
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare const ARBITRUM_ONE: {
|
|
79
|
+
chains: ChainConfig[];
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Arbitrum testnet only preset
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const provider = await connectWallet({
|
|
87
|
+
* ...ARBITRUM_SEPOLIA,
|
|
88
|
+
* auth,
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export declare const ARBITRUM_SEPOLIA: {
|
|
93
|
+
chains: ChainConfig[];
|
|
94
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MultiRollupApiClients } from '@imtbl/generated-clients';
|
|
2
|
+
import { Auth, TypedEventEmitter } from '@imtbl/auth';
|
|
3
|
+
import { Provider, ProviderEventMap, RequestArguments, ChainConfig } from '../types';
|
|
4
|
+
import GuardianClient from '../guardian';
|
|
5
|
+
import { SequenceSigner } from './signer';
|
|
6
|
+
export type SequenceProviderInput = {
|
|
7
|
+
auth: Auth;
|
|
8
|
+
chainConfig: ChainConfig;
|
|
9
|
+
multiRollupApiClients: MultiRollupApiClients;
|
|
10
|
+
guardianClient: GuardianClient;
|
|
11
|
+
ethSigner: SequenceSigner;
|
|
12
|
+
passportEventEmitter: TypedEventEmitter<ProviderEventMap>;
|
|
13
|
+
};
|
|
14
|
+
export declare class SequenceProvider implements Provider {
|
|
15
|
+
#private;
|
|
16
|
+
readonly isPassport: boolean;
|
|
17
|
+
constructor({ auth, chainConfig, multiRollupApiClients, guardianClient, ethSigner, passportEventEmitter, }: SequenceProviderInput);
|
|
18
|
+
request(request: RequestArguments): Promise<any>;
|
|
19
|
+
on(event: string, listener: (...args: any[]) => void): void;
|
|
20
|
+
removeListener(event: string, listener: (...args: any[]) => void): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Auth } from '@imtbl/auth';
|
|
2
|
+
import { Address } from 'ox';
|
|
3
|
+
import { Payload, Signature as SequenceSignature } from '@0xsequence/wallet-primitives';
|
|
4
|
+
import { SequenceSigner } from './types';
|
|
5
|
+
export interface IdentityInstrumentSignerConfig {
|
|
6
|
+
/** Sequence Identity Instrument endpoint URL */
|
|
7
|
+
identityInstrumentEndpoint: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class IdentityInstrumentSigner implements SequenceSigner {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(auth: Auth, config: IdentityInstrumentSignerConfig);
|
|
12
|
+
getAddress(): Promise<string>;
|
|
13
|
+
signPayload(walletAddress: Address.Address, chainId: number, payload: Payload.Parented): Promise<SequenceSignature.SignatureOfSignerLeaf>;
|
|
14
|
+
signMessage(message: string | Uint8Array): Promise<string>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Auth, IAuthConfiguration } from '@imtbl/auth';
|
|
2
|
+
import { SequenceSigner } from './types';
|
|
3
|
+
export type { SequenceSigner } from './types';
|
|
4
|
+
export { IdentityInstrumentSigner } from './identityInstrumentSigner';
|
|
5
|
+
export type { IdentityInstrumentSignerConfig } from './identityInstrumentSigner';
|
|
6
|
+
export { PrivateKeySigner } from './privateKeySigner';
|
|
7
|
+
export interface CreateSequenceSignerConfig {
|
|
8
|
+
/** Identity Instrument endpoint (required for prod/sandbox) */
|
|
9
|
+
identityInstrumentEndpoint?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create the appropriate signer based on environment.
|
|
13
|
+
* - Dev environment (behind VPN): uses PrivateKeySigner
|
|
14
|
+
* - Prod/Sandbox: uses IdentityInstrumentSigner
|
|
15
|
+
*
|
|
16
|
+
* @param auth - Auth instance
|
|
17
|
+
* @param authConfig - Auth configuration (to determine environment)
|
|
18
|
+
* @param config - Signer configuration
|
|
19
|
+
*/
|
|
20
|
+
export declare function createSequenceSigner(auth: Auth, authConfig: IAuthConfiguration, config?: CreateSequenceSignerConfig): SequenceSigner;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Auth } from '@imtbl/auth';
|
|
2
|
+
import { Payload, Signature as SequenceSignature } from '@0xsequence/wallet-primitives';
|
|
3
|
+
import { SequenceSigner } from './types';
|
|
4
|
+
import { Address } from 'ox';
|
|
5
|
+
/**
|
|
6
|
+
* Private key signer for dev environments (behind VPN).
|
|
7
|
+
* Uses a deterministic private key derived from the user's sub.
|
|
8
|
+
*/
|
|
9
|
+
export declare class PrivateKeySigner implements SequenceSigner {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(auth: Auth);
|
|
12
|
+
getAddress(): Promise<string>;
|
|
13
|
+
signPayload(walletAddress: Address.Address, chainId: number, payload: Payload.Parented): Promise<SequenceSignature.SignatureOfSignerLeaf>;
|
|
14
|
+
signMessage(message: string | Uint8Array): Promise<string>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Address } from 'ox';
|
|
2
|
+
import { Payload, Signature as SequenceSignature } from '@0xsequence/wallet-primitives';
|
|
3
|
+
/**
|
|
4
|
+
* Signer interface for Sequence wallet operations.
|
|
5
|
+
* Used by non-zkEVM chains (e.g., Arbitrum).
|
|
6
|
+
*/
|
|
7
|
+
export interface SequenceSigner {
|
|
8
|
+
/** Get the signer's address */
|
|
9
|
+
getAddress(): Promise<string>;
|
|
10
|
+
/** Sign a Sequence payload (for transactions) */
|
|
11
|
+
signPayload(walletAddress: Address.Address, chainId: number, payload: Payload.Parented): Promise<SequenceSignature.SignatureOfSignerLeaf>;
|
|
12
|
+
/** Sign a message (EIP-191 personal_sign) */
|
|
13
|
+
signMessage(message: string | Uint8Array): Promise<string>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MultiRollupApiClients } from '@imtbl/generated-clients';
|
|
2
|
+
import { Flow } from '@imtbl/metrics';
|
|
3
|
+
import type { PublicClient } from 'viem';
|
|
4
|
+
import { Auth } from '@imtbl/auth';
|
|
5
|
+
import { SequenceSigner } from '../signer';
|
|
6
|
+
export type RegisterUserInput = {
|
|
7
|
+
auth: Auth;
|
|
8
|
+
ethSigner: SequenceSigner;
|
|
9
|
+
multiRollupApiClients: MultiRollupApiClients;
|
|
10
|
+
accessToken: string;
|
|
11
|
+
rpcProvider: PublicClient;
|
|
12
|
+
flow: Flow;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Register a user for a non-zkEVM chain (e.g., Arbitrum).
|
|
16
|
+
* Creates a counterfactual address for the user on the specified chain.
|
|
17
|
+
*/
|
|
18
|
+
export declare function registerUser({ auth, ethSigner, multiRollupApiClients, accessToken, rpcProvider, flow, }: RegisterUserInput): Promise<string>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Flow } from '@imtbl/metrics';
|
|
2
2
|
import { Auth, TypedEventEmitter, type AuthEventMap } from '@imtbl/auth';
|
|
3
3
|
import { JsonRpcError } from './zkEvm/JsonRpcError';
|
|
4
|
+
export declare enum EvmChain {
|
|
5
|
+
ZKEVM = "zkevm",
|
|
6
|
+
ARBITRUM_ONE = "arbitrum_one"
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* A viem-compatible signer interface for wallet operations.
|
|
6
10
|
* This replaces ethers' AbstractSigner/Signer.
|
|
@@ -28,7 +32,16 @@ export type AccountsRequestedEvent = {
|
|
|
28
32
|
export interface PassportEventMap extends AuthEventMap {
|
|
29
33
|
[WalletEvents.ACCOUNTS_REQUESTED]: [AccountsRequestedEvent];
|
|
30
34
|
}
|
|
31
|
-
|
|
35
|
+
/**
|
|
36
|
+
* EIP-1193 Provider Interface
|
|
37
|
+
* Standard Ethereum provider interface for all chain types
|
|
38
|
+
*/
|
|
39
|
+
export type Provider = {
|
|
40
|
+
request: (request: RequestArguments) => Promise<any>;
|
|
41
|
+
on: (event: string, listener: (...args: any[]) => void) => void;
|
|
42
|
+
removeListener: (event: string, listener: (...args: any[]) => void) => void;
|
|
43
|
+
isPassport: boolean;
|
|
44
|
+
};
|
|
32
45
|
export interface RequestArguments {
|
|
33
46
|
method: string;
|
|
34
47
|
params?: Array<any>;
|
|
@@ -151,6 +164,14 @@ export interface ChainConfig {
|
|
|
151
164
|
* Defaults to 'https://tee.express.magiclabs.com'
|
|
152
165
|
*/
|
|
153
166
|
magicTeeBasePath?: string;
|
|
167
|
+
/** Preferred token symbol for relayer fees (default: 'IMX') */
|
|
168
|
+
feeTokenSymbol?: string;
|
|
169
|
+
/** Sequence RPC node URL TODO: check if this can be removed and only use rpcUrl */
|
|
170
|
+
nodeUrl?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Sequence Identity Instrument endpoint (for non-zkEVM chains in prod/sandbox)
|
|
173
|
+
*/
|
|
174
|
+
sequenceIdentityInstrumentEndpoint?: string;
|
|
154
175
|
}
|
|
155
176
|
/**
|
|
156
177
|
* Popup overlay options for wallet UI
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { JsonRpcError } from './JsonRpcError';
|
|
2
|
+
import type { Provider as ProviderType } from '../types';
|
|
2
3
|
export declare enum RelayerTransactionStatus {
|
|
3
4
|
PENDING = "PENDING",
|
|
4
5
|
SUBMITTED = "SUBMITTED",
|
|
@@ -82,16 +83,8 @@ export interface JsonRpcResponsePayload {
|
|
|
82
83
|
jsonrpc?: string;
|
|
83
84
|
id?: string | number;
|
|
84
85
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
* Standard Ethereum provider interface
|
|
88
|
-
*/
|
|
89
|
-
export type Provider = {
|
|
90
|
-
request: (request: RequestArguments) => Promise<any>;
|
|
91
|
-
on: (event: string, listener: (...args: any[]) => void) => void;
|
|
92
|
-
removeListener: (event: string, listener: (...args: any[]) => void) => void;
|
|
93
|
-
isPassport: boolean;
|
|
94
|
-
};
|
|
86
|
+
export type { Provider } from '../types';
|
|
87
|
+
type Provider = ProviderType;
|
|
95
88
|
export declare enum ProviderEvent {
|
|
96
89
|
ACCOUNTS_CHANGED = "accountsChanged"
|
|
97
90
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@imtbl/wallet",
|
|
3
|
-
"version": "2.12.5
|
|
3
|
+
"version": "2.12.5",
|
|
4
4
|
"description": "Wallet SDK for Immutable",
|
|
5
5
|
"author": "Immutable",
|
|
6
6
|
"bugs": "https://github.com/immutable/ts-immutable-sdk/issues",
|
|
@@ -25,12 +25,16 @@
|
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@imtbl/auth": "2.12.5
|
|
29
|
-
"@imtbl/generated-clients": "2.12.5
|
|
30
|
-
"@imtbl/metrics": "2.12.5
|
|
28
|
+
"@imtbl/auth": "2.12.5",
|
|
29
|
+
"@imtbl/generated-clients": "2.12.5",
|
|
30
|
+
"@imtbl/metrics": "2.12.5",
|
|
31
31
|
"viem": "~2.18.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
+
"@0xsequence/identity-instrument": "3.0.0-beta.10",
|
|
35
|
+
"@0xsequence/wallet-wdk": "3.0.0-beta.10",
|
|
36
|
+
"@0xsequence/wallet-core": "3.0.0-beta.10",
|
|
37
|
+
"@0xsequence/wallet-primitives": "3.0.0-beta.10",
|
|
34
38
|
"@swc/core": "^1.3.36",
|
|
35
39
|
"@swc/jest": "^0.2.37",
|
|
36
40
|
"@types/jest": "^29.5.12",
|
|
@@ -38,6 +42,7 @@
|
|
|
38
42
|
"@jest/test-sequencer": "^29.7.0",
|
|
39
43
|
"jest": "^29.4.3",
|
|
40
44
|
"jest-environment-jsdom": "^29.4.3",
|
|
45
|
+
"ox": "^0.9.17",
|
|
41
46
|
"ts-node": "^10.9.1",
|
|
42
47
|
"tsup": "^8.3.0",
|
|
43
48
|
"typescript": "^5.6.2"
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
import { openPopupCenter } from './popup';
|
|
11
11
|
import { IAuthConfiguration } from '@imtbl/auth';
|
|
12
12
|
import ConfirmationOverlay from '../overlay/confirmationOverlay';
|
|
13
|
+
import { getEvmChainFromChainId } from '../network/chainRegistry';
|
|
14
|
+
import { EvmChain } from '../types';
|
|
13
15
|
|
|
14
16
|
const CONFIRMATION_WINDOW_TITLE = 'Confirm this transaction';
|
|
15
17
|
const CONFIRMATION_WINDOW_HEIGHT = 720;
|
|
@@ -105,7 +107,10 @@ export default class ConfirmationScreen {
|
|
|
105
107
|
if (chainType === GeneratedClients.mr.TransactionApprovalRequestChainTypeEnum.Starkex) {
|
|
106
108
|
href = this.getHref('transaction', { transactionId, etherAddress, chainType });
|
|
107
109
|
} else {
|
|
108
|
-
|
|
110
|
+
// Get chain path from chainId (e.g., 'zkevm', 'arbitrum-one')
|
|
111
|
+
const chain = chainId ? getEvmChainFromChainId(chainId) : EvmChain.ZKEVM;
|
|
112
|
+
const chainPath = chain.replace('_', '-');
|
|
113
|
+
href = this.getHref(`${chainPath}/transaction`, {
|
|
109
114
|
transactionID: transactionId, etherAddress, chainType, chainID: chainId,
|
|
110
115
|
});
|
|
111
116
|
}
|
|
@@ -117,7 +122,8 @@ export default class ConfirmationScreen {
|
|
|
117
122
|
requestMessageConfirmation(
|
|
118
123
|
messageID: string,
|
|
119
124
|
etherAddress: string,
|
|
120
|
-
messageType
|
|
125
|
+
messageType: MessageType,
|
|
126
|
+
chainId: string,
|
|
121
127
|
): Promise<ConfirmationResult> {
|
|
122
128
|
return new Promise((resolve, reject) => {
|
|
123
129
|
const messageHandler = ({ data, origin }: MessageEvent) => {
|
|
@@ -157,10 +163,14 @@ export default class ConfirmationScreen {
|
|
|
157
163
|
};
|
|
158
164
|
|
|
159
165
|
window.addEventListener('message', messageHandler);
|
|
160
|
-
|
|
166
|
+
// Get chain path from chainId (e.g., 'zkevm', 'arbitrum-one')
|
|
167
|
+
const chain = getEvmChainFromChainId(chainId);
|
|
168
|
+
const chainPath = chain.replace('_', '-');
|
|
169
|
+
const href = this.getHref(`${chainPath}/message`, {
|
|
161
170
|
messageID,
|
|
162
171
|
etherAddress,
|
|
163
|
-
|
|
172
|
+
chainID: chainId,
|
|
173
|
+
messageType,
|
|
164
174
|
});
|
|
165
175
|
this.showConfirmationScreen(href, messageHandler, resolve);
|
|
166
176
|
});
|
|
@@ -42,6 +42,18 @@ jest.mock('./zkEvm/zkEvmProvider', () => ({
|
|
|
42
42
|
ZkEvmProvider: jest.fn(),
|
|
43
43
|
}));
|
|
44
44
|
|
|
45
|
+
jest.mock('./sequence/sequenceProvider', () => ({
|
|
46
|
+
SequenceProvider: jest.fn(),
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
jest.mock('./sequence/signer', () => ({
|
|
50
|
+
createSequenceSigner: jest.fn().mockReturnValue({
|
|
51
|
+
getAddress: jest.fn().mockResolvedValue('0x1234'),
|
|
52
|
+
signPayload: jest.fn(),
|
|
53
|
+
signMessage: jest.fn(),
|
|
54
|
+
}),
|
|
55
|
+
}));
|
|
56
|
+
|
|
45
57
|
jest.mock('./provider/eip6963', () => ({
|
|
46
58
|
announceProvider: jest.fn(),
|
|
47
59
|
passportProviderInfo: { name: 'passport', rdns: 'com.immutable.passport', icon: '' },
|
|
@@ -51,8 +63,9 @@ const { connectWallet } = require('./connectWallet');
|
|
|
51
63
|
|
|
52
64
|
const { announceProvider } = jest.requireMock('./provider/eip6963');
|
|
53
65
|
const { ZkEvmProvider } = jest.requireMock('./zkEvm/zkEvmProvider');
|
|
66
|
+
const { SequenceProvider } = jest.requireMock('./sequence/sequenceProvider');
|
|
54
67
|
|
|
55
|
-
const
|
|
68
|
+
const zkEvmChain = {
|
|
56
69
|
chainId: 13473,
|
|
57
70
|
rpcUrl: 'https://rpc.sandbox.immutable.com',
|
|
58
71
|
relayerUrl: 'https://relayer.sandbox.immutable.com',
|
|
@@ -60,6 +73,14 @@ const chain = {
|
|
|
60
73
|
name: 'Immutable zkEVM Testnet',
|
|
61
74
|
};
|
|
62
75
|
|
|
76
|
+
const arbitrumChain = {
|
|
77
|
+
chainId: 42161,
|
|
78
|
+
rpcUrl: 'https://arb1.arbitrum.io/rpc',
|
|
79
|
+
relayerUrl: 'https://next-arbitrum-one-relayer.sequence.app',
|
|
80
|
+
apiUrl: 'https://api.immutable.com',
|
|
81
|
+
name: 'Arbitrum One',
|
|
82
|
+
};
|
|
83
|
+
|
|
63
84
|
const createAuthStub = () => ({
|
|
64
85
|
getConfig: jest.fn().mockReturnValue({
|
|
65
86
|
authenticationDomain: 'https://auth.immutable.com',
|
|
@@ -82,7 +103,7 @@ describe('connectWallet', () => {
|
|
|
82
103
|
it('announces provider by default', async () => {
|
|
83
104
|
const auth = createAuthStub();
|
|
84
105
|
|
|
85
|
-
const provider = await connectWallet({ auth, chains: [
|
|
106
|
+
const provider = await connectWallet({ auth, chains: [zkEvmChain] });
|
|
86
107
|
|
|
87
108
|
expect(ZkEvmProvider).toHaveBeenCalled();
|
|
88
109
|
expect(announceProvider).toHaveBeenCalledWith({
|
|
@@ -94,8 +115,46 @@ describe('connectWallet', () => {
|
|
|
94
115
|
it('does not announce provider when disabled', async () => {
|
|
95
116
|
const auth = createAuthStub();
|
|
96
117
|
|
|
97
|
-
await connectWallet({ auth, chains: [
|
|
118
|
+
await connectWallet({ auth, chains: [zkEvmChain], announceProvider: false });
|
|
98
119
|
|
|
99
120
|
expect(announceProvider).not.toHaveBeenCalled();
|
|
100
121
|
});
|
|
122
|
+
|
|
123
|
+
describe('provider selection', () => {
|
|
124
|
+
it('uses ZkEvmProvider for zkEVM chain (by chainId)', async () => {
|
|
125
|
+
const auth = createAuthStub();
|
|
126
|
+
|
|
127
|
+
await connectWallet({ auth, chains: [zkEvmChain] });
|
|
128
|
+
|
|
129
|
+
expect(ZkEvmProvider).toHaveBeenCalled();
|
|
130
|
+
expect(SequenceProvider).not.toHaveBeenCalled();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('uses ZkEvmProvider for zkEVM devnet chain', async () => {
|
|
134
|
+
const auth = createAuthStub();
|
|
135
|
+
const devChain = {
|
|
136
|
+
chainId: 15003, // zkEVM devnet chainId
|
|
137
|
+
rpcUrl: 'https://rpc.dev.immutable.com',
|
|
138
|
+
relayerUrl: 'https://relayer.dev.immutable.com',
|
|
139
|
+
apiUrl: 'https://api.dev.immutable.com',
|
|
140
|
+
name: 'Dev Chain',
|
|
141
|
+
magicPublishableApiKey: 'pk_test_123',
|
|
142
|
+
magicProviderId: 'provider-123',
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
await connectWallet({ auth, chains: [devChain] });
|
|
146
|
+
|
|
147
|
+
expect(ZkEvmProvider).toHaveBeenCalled();
|
|
148
|
+
expect(SequenceProvider).not.toHaveBeenCalled();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('uses SequenceProvider for non-zkEVM chain (Arbitrum)', async () => {
|
|
152
|
+
const auth = createAuthStub();
|
|
153
|
+
|
|
154
|
+
await connectWallet({ auth, chains: [arbitrumChain] });
|
|
155
|
+
|
|
156
|
+
expect(SequenceProvider).toHaveBeenCalled();
|
|
157
|
+
expect(ZkEvmProvider).not.toHaveBeenCalled();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
101
160
|
});
|
package/src/connectWallet.ts
CHANGED
|
@@ -10,13 +10,21 @@ import {
|
|
|
10
10
|
mr,
|
|
11
11
|
} from '@imtbl/generated-clients';
|
|
12
12
|
import { ZkEvmProvider } from './zkEvm/zkEvmProvider';
|
|
13
|
-
import {
|
|
13
|
+
import { SequenceProvider } from './sequence/sequenceProvider';
|
|
14
|
+
import {
|
|
15
|
+
ConnectWalletOptions, PassportEventMap, ChainConfig, Provider,
|
|
16
|
+
} from './types';
|
|
14
17
|
import { WalletConfiguration } from './config';
|
|
15
18
|
import GuardianClient from './guardian';
|
|
16
19
|
import MagicTEESigner from './magic/magicTEESigner';
|
|
17
20
|
import { announceProvider, passportProviderInfo } from './provider/eip6963';
|
|
18
|
-
import { DEFAULT_CHAINS } from './presets';
|
|
19
|
-
import {
|
|
21
|
+
import { DEFAULT_CHAINS } from './network/presets';
|
|
22
|
+
import {
|
|
23
|
+
MAGIC_CONFIG,
|
|
24
|
+
IMMUTABLE_ZKEVM_TESTNET_CHAIN_ID,
|
|
25
|
+
} from './constants';
|
|
26
|
+
import { ChainId } from './network/chains';
|
|
27
|
+
import { createSequenceSigner } from './sequence/signer';
|
|
20
28
|
|
|
21
29
|
/**
|
|
22
30
|
* Type guard to check if chainId is a valid key for MAGIC_CONFIG
|
|
@@ -64,6 +72,16 @@ const DEFAULT_REDIRECT_FALLBACK = 'https://auth.immutable.com/im-logged-in';
|
|
|
64
72
|
const DEFAULT_AUTHENTICATION_DOMAIN = 'https://auth.immutable.com';
|
|
65
73
|
const SANDBOX_DOMAIN_REGEX = /(sandbox|testnet)/i;
|
|
66
74
|
|
|
75
|
+
const ZKEVM_CHAIN_IDS = [
|
|
76
|
+
ChainId.IMTBL_ZKEVM_MAINNET,
|
|
77
|
+
ChainId.IMTBL_ZKEVM_TESTNET,
|
|
78
|
+
ChainId.IMTBL_ZKEVM_DEVNET,
|
|
79
|
+
];
|
|
80
|
+
|
|
81
|
+
function isZkEvmChain(chain: ChainConfig): boolean {
|
|
82
|
+
return ZKEVM_CHAIN_IDS.includes(chain.chainId);
|
|
83
|
+
}
|
|
84
|
+
|
|
67
85
|
function isSandboxChain(chain: ChainConfig): boolean {
|
|
68
86
|
if (chain.chainId === IMMUTABLE_ZKEVM_TESTNET_CHAIN_ID) {
|
|
69
87
|
return true;
|
|
@@ -156,7 +174,7 @@ function createDefaultAuth(initialChain: ChainConfig, options: ConnectWalletOpti
|
|
|
156
174
|
*/
|
|
157
175
|
export async function connectWallet(
|
|
158
176
|
config: ConnectWalletOptions = {},
|
|
159
|
-
): Promise<
|
|
177
|
+
): Promise<Provider> {
|
|
160
178
|
// Use default chains if not provided (testnet + mainnet)
|
|
161
179
|
const chains = config.chains && config.chains.length > 0
|
|
162
180
|
? config.chains
|
|
@@ -216,7 +234,10 @@ export async function connectWallet(
|
|
|
216
234
|
feeTokenSymbol: config.feeTokenSymbol,
|
|
217
235
|
});
|
|
218
236
|
|
|
219
|
-
// 6. Create
|
|
237
|
+
// 6. Create PassportEventEmitter
|
|
238
|
+
const passportEventEmitter = config.passportEventEmitter || new TypedEventEmitter<PassportEventMap>();
|
|
239
|
+
|
|
240
|
+
// 7. Create GuardianClient
|
|
220
241
|
const guardianApi = new mr.GuardianApi(apiConfig);
|
|
221
242
|
|
|
222
243
|
const guardianClient = new GuardianClient({
|
|
@@ -226,50 +247,66 @@ export async function connectWallet(
|
|
|
226
247
|
authConfig,
|
|
227
248
|
});
|
|
228
249
|
|
|
229
|
-
//
|
|
230
|
-
|
|
250
|
+
// 8. Create provider based on chain type
|
|
251
|
+
let provider: Provider;
|
|
231
252
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
basePath: magicTeeBasePath,
|
|
236
|
-
timeout: 10000,
|
|
237
|
-
magicPublishableApiKey: magicConfig.magicPublishableApiKey,
|
|
238
|
-
magicProviderId: magicConfig.magicProviderId,
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
const ethSigner = new MagicTEESigner(auth, magicTeeApiClients);
|
|
242
|
-
|
|
243
|
-
// 9. Determine session activity API URL (only for mainnet, testnet, devnet)
|
|
244
|
-
let sessionActivityApiUrl: string | null = null;
|
|
245
|
-
if (initialChain.chainId === 13371) {
|
|
246
|
-
// Mainnet
|
|
247
|
-
sessionActivityApiUrl = 'https://api.immutable.com';
|
|
248
|
-
} else if (initialChain.chainId === 13473) {
|
|
249
|
-
// Testnet
|
|
250
|
-
sessionActivityApiUrl = 'https://api.sandbox.immutable.com';
|
|
251
|
-
} else if (initialChain.apiUrl) {
|
|
252
|
-
// Devnet - use the apiUrl from chain config
|
|
253
|
-
sessionActivityApiUrl = initialChain.apiUrl;
|
|
254
|
-
}
|
|
255
|
-
// For any other chain, sessionActivityApiUrl remains null (no session activity tracking)
|
|
253
|
+
if (isZkEvmChain(initialChain)) {
|
|
254
|
+
// 9. Get Magic config for initial chain (from chain config or hard-coded default)
|
|
255
|
+
const magicConfig = getMagicConfigForChain(initialChain);
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
// 10. Create MagicTEESigner with Magic TEE base path (separate from backend API)
|
|
258
|
+
const magicTeeBasePath = initialChain.magicTeeBasePath || 'https://tee.express.magiclabs.com';
|
|
259
|
+
const magicTeeApiClients = new MagicTeeApiClients({
|
|
260
|
+
basePath: magicTeeBasePath,
|
|
261
|
+
timeout: 10000,
|
|
262
|
+
magicPublishableApiKey: magicConfig.magicPublishableApiKey,
|
|
263
|
+
magicProviderId: magicConfig.magicProviderId,
|
|
264
|
+
});
|
|
265
|
+
const ethSigner = new MagicTEESigner(auth, magicTeeApiClients);
|
|
266
|
+
|
|
267
|
+
// 11. Determine session activity API URL (only for mainnet, testnet, devnet)
|
|
268
|
+
let sessionActivityApiUrl: string | null = null;
|
|
269
|
+
if (initialChain.chainId === 13371) {
|
|
270
|
+
// Mainnet
|
|
271
|
+
sessionActivityApiUrl = 'https://api.immutable.com';
|
|
272
|
+
} else if (initialChain.chainId === 13473) {
|
|
273
|
+
// Testnet
|
|
274
|
+
sessionActivityApiUrl = 'https://api.sandbox.immutable.com';
|
|
275
|
+
} else if (initialChain.apiUrl) {
|
|
276
|
+
// Devnet - use the apiUrl from chain config
|
|
277
|
+
sessionActivityApiUrl = initialChain.apiUrl;
|
|
278
|
+
}
|
|
279
|
+
// For any other chain, sessionActivityApiUrl remains null (no session activity tracking)
|
|
280
|
+
|
|
281
|
+
// 12. Create ZkEvmProvider
|
|
282
|
+
provider = new ZkEvmProvider({
|
|
283
|
+
auth,
|
|
284
|
+
config: walletConfig,
|
|
285
|
+
multiRollupApiClients,
|
|
286
|
+
passportEventEmitter,
|
|
287
|
+
guardianClient,
|
|
288
|
+
ethSigner,
|
|
289
|
+
user,
|
|
290
|
+
sessionActivityApiUrl,
|
|
291
|
+
});
|
|
292
|
+
} else {
|
|
293
|
+
// Create Sequence signer based on environment
|
|
294
|
+
const sequenceSigner = createSequenceSigner(auth, authConfig, {
|
|
295
|
+
identityInstrumentEndpoint: initialChain.sequenceIdentityInstrumentEndpoint,
|
|
296
|
+
});
|
|
259
297
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
});
|
|
298
|
+
// Non-zkEVM chain - use SequenceProvider
|
|
299
|
+
provider = new SequenceProvider({
|
|
300
|
+
auth,
|
|
301
|
+
chainConfig: initialChain,
|
|
302
|
+
multiRollupApiClients,
|
|
303
|
+
guardianClient,
|
|
304
|
+
ethSigner: sequenceSigner,
|
|
305
|
+
passportEventEmitter,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
271
308
|
|
|
272
|
-
//
|
|
309
|
+
// 13. Announce provider via EIP-6963
|
|
273
310
|
if (config.announceProvider !== false) {
|
|
274
311
|
announceProvider({
|
|
275
312
|
info: passportProviderInfo,
|