@imtbl/wallet 2.12.6 → 2.12.7-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +688 -0
- package/dist/browser/index.js +47 -47
- package/dist/node/index.cjs +65 -69
- package/dist/node/index.js +50 -50
- package/dist/types/connectWallet.d.ts +13 -19
- package/dist/types/guardian/index.d.ts +10 -5
- package/dist/types/magic/magicTEESigner.d.ts +3 -4
- package/dist/types/sequence/sequenceProvider.d.ts +4 -4
- package/dist/types/sequence/signer/identityInstrumentSigner.d.ts +2 -2
- package/dist/types/sequence/signer/index.d.ts +5 -4
- package/dist/types/sequence/signer/privateKeySigner.d.ts +2 -2
- package/dist/types/sequence/user/registerUser.d.ts +3 -3
- package/dist/types/types.d.ts +39 -9
- package/dist/types/zkEvm/relayerClient.d.ts +8 -4
- package/dist/types/zkEvm/user/registerZkEvmUser.d.ts +7 -4
- package/dist/types/zkEvm/zkEvmProvider.d.ts +13 -5
- package/package.json +7 -7
- package/src/connectWallet.test.ts +16 -22
- package/src/connectWallet.ts +79 -53
- package/src/guardian/index.ts +40 -25
- package/src/magic/magicTEESigner.ts +8 -6
- package/src/sequence/sequenceProvider.ts +17 -9
- package/src/sequence/signer/identityInstrumentSigner.ts +8 -6
- package/src/sequence/signer/index.ts +8 -12
- package/src/sequence/signer/privateKeySigner.ts +6 -5
- package/src/sequence/user/registerUser.ts +5 -4
- package/src/types.ts +44 -12
- package/src/zkEvm/relayerClient.ts +22 -6
- package/src/zkEvm/user/registerZkEvmUser.ts +16 -5
- package/src/zkEvm/zkEvmProvider.ts +56 -29
package/README.md
ADDED
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
# @imtbl/wallet
|
|
2
|
+
|
|
3
|
+
The Immutable Wallet SDK provides an EIP-1193 compliant Ethereum provider for interacting with Immutable's zkEVM and other supported blockchains. It handles authentication, transaction signing, wallet management, and external wallet linking out of the box.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Quick Start](#quick-start)
|
|
9
|
+
- [Configuration Options](#configuration-options)
|
|
10
|
+
- [Using External Auth Packages](#using-external-auth-packages)
|
|
11
|
+
- [API Reference](#api-reference)
|
|
12
|
+
- [Chain Configuration](#chain-configuration)
|
|
13
|
+
- [Wallet Linking](#wallet-linking)
|
|
14
|
+
- [EIP-6963 Provider Discovery](#eip-6963-provider-discovery)
|
|
15
|
+
- [Events](#events)
|
|
16
|
+
- [Error Handling](#error-handling)
|
|
17
|
+
- [TypeScript](#typescript)
|
|
18
|
+
- [Related Packages](#related-packages)
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @imtbl/wallet
|
|
24
|
+
# or
|
|
25
|
+
yarn add @imtbl/wallet
|
|
26
|
+
# or
|
|
27
|
+
pnpm add @imtbl/wallet
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
Connect to Immutable zkEVM with just a few lines of code:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { connectWallet } from '@imtbl/wallet';
|
|
36
|
+
|
|
37
|
+
// Create a wallet provider
|
|
38
|
+
const provider = await connectWallet();
|
|
39
|
+
|
|
40
|
+
// Request accounts (triggers login if user is not authenticated)
|
|
41
|
+
const accounts = await provider.request({ method: 'eth_requestAccounts' });
|
|
42
|
+
console.log('Connected:', accounts[0]);
|
|
43
|
+
|
|
44
|
+
// Send a transaction
|
|
45
|
+
const txHash = await provider.request({
|
|
46
|
+
method: 'eth_sendTransaction',
|
|
47
|
+
params: [{
|
|
48
|
+
to: '0x...',
|
|
49
|
+
value: '0x...',
|
|
50
|
+
}],
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
That's it! The wallet handles authentication, user registration, and transaction signing automatically.
|
|
55
|
+
|
|
56
|
+
## Configuration Options
|
|
57
|
+
|
|
58
|
+
### Custom Client ID
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const provider = await connectWallet({
|
|
62
|
+
clientId: 'your-client-id',
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Chain Selection
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import {
|
|
70
|
+
connectWallet,
|
|
71
|
+
IMMUTABLE_ZKEVM_MAINNET_CHAIN,
|
|
72
|
+
IMMUTABLE_ZKEVM_TESTNET_CHAIN,
|
|
73
|
+
} from '@imtbl/wallet';
|
|
74
|
+
|
|
75
|
+
// Connect to mainnet
|
|
76
|
+
const provider = await connectWallet({
|
|
77
|
+
chains: [IMMUTABLE_ZKEVM_MAINNET_CHAIN],
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Connect to testnet (default)
|
|
81
|
+
const provider = await connectWallet({
|
|
82
|
+
chains: [IMMUTABLE_ZKEVM_TESTNET_CHAIN],
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Popup Overlay Options
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const provider = await connectWallet({
|
|
90
|
+
popupOverlayOptions: {
|
|
91
|
+
disableGenericPopupOverlay: true,
|
|
92
|
+
disableBlockedPopupOverlay: true,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Using External Auth Packages
|
|
100
|
+
|
|
101
|
+
By default, `@imtbl/wallet` handles authentication internally. However, if your application already uses Immutable's auth packages for session management, you can integrate them with the wallet.
|
|
102
|
+
|
|
103
|
+
| Package | Use Case |
|
|
104
|
+
|---------|----------|
|
|
105
|
+
| `@imtbl/auth-next-client` | Next.js apps with server-side session management |
|
|
106
|
+
| `@imtbl/auth` | Non-Next.js apps needing custom auth control |
|
|
107
|
+
|
|
108
|
+
### With @imtbl/auth-next-client (Next.js)
|
|
109
|
+
|
|
110
|
+
If you're using NextAuth for server-side session management, pass the `getUser` function from `useImmutableSession`:
|
|
111
|
+
|
|
112
|
+
**Install dependencies:**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm install @imtbl/wallet @imtbl/auth-next-client @imtbl/auth-next-server next-auth@5
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Integrate with the wallet:**
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
'use client';
|
|
122
|
+
|
|
123
|
+
import { connectWallet } from '@imtbl/wallet';
|
|
124
|
+
import { useImmutableSession } from '@imtbl/auth-next-client';
|
|
125
|
+
import { useState } from 'react';
|
|
126
|
+
|
|
127
|
+
export function WalletConnect() {
|
|
128
|
+
const { getUser } = useImmutableSession();
|
|
129
|
+
const [provider, setProvider] = useState(null);
|
|
130
|
+
|
|
131
|
+
const handleConnect = async () => {
|
|
132
|
+
// Pass getUser to share session with the wallet
|
|
133
|
+
const walletProvider = await connectWallet({ getUser });
|
|
134
|
+
|
|
135
|
+
const accounts = await walletProvider.request({
|
|
136
|
+
method: 'eth_requestAccounts'
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
console.log('Connected:', accounts[0]);
|
|
140
|
+
setProvider(walletProvider);
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return <button onClick={handleConnect}>Connect Wallet</button>;
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Benefits:**
|
|
148
|
+
- Server-side session management with secure token storage
|
|
149
|
+
- Automatic token refresh via NextAuth callbacks
|
|
150
|
+
- SSR compatibility
|
|
151
|
+
- Single source of truth for authentication state
|
|
152
|
+
|
|
153
|
+
### With @imtbl/auth (Direct)
|
|
154
|
+
|
|
155
|
+
For applications needing full control over authentication without NextAuth:
|
|
156
|
+
|
|
157
|
+
**Install dependencies:**
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npm install @imtbl/wallet @imtbl/auth
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Integrate with the wallet:**
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { connectWallet } from '@imtbl/wallet';
|
|
167
|
+
import { Auth } from '@imtbl/auth';
|
|
168
|
+
|
|
169
|
+
// Create your Auth instance
|
|
170
|
+
const auth = new Auth({
|
|
171
|
+
clientId: 'your-client-id',
|
|
172
|
+
redirectUri: 'https://your-app.com/callback',
|
|
173
|
+
// ... other options
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Create a getUser function that wraps your Auth instance
|
|
177
|
+
const getUser = async (forceRefresh?: boolean) => {
|
|
178
|
+
if (forceRefresh) {
|
|
179
|
+
return auth.forceUserRefresh();
|
|
180
|
+
}
|
|
181
|
+
return auth.getUser();
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// Pass to connectWallet
|
|
185
|
+
const provider = await connectWallet({ getUser });
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**When to use this approach:**
|
|
189
|
+
- You need custom login/logout flows
|
|
190
|
+
- You want to manage auth state outside the wallet
|
|
191
|
+
- You're integrating with an existing auth system
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## API Reference
|
|
196
|
+
|
|
197
|
+
### `connectWallet(options?)`
|
|
198
|
+
|
|
199
|
+
Creates an EIP-1193 compliant provider for Immutable zkEVM or other supported chains.
|
|
200
|
+
|
|
201
|
+
#### Options
|
|
202
|
+
|
|
203
|
+
| Option | Type | Default | Description |
|
|
204
|
+
|--------|------|---------|-------------|
|
|
205
|
+
| `clientId` | `string` | Auto-detected | Immutable client ID |
|
|
206
|
+
| `chains` | `ChainConfig[]` | `[testnet, mainnet]` | Chain configurations |
|
|
207
|
+
| `initialChainId` | `number` | First chain | Initial chain to connect to |
|
|
208
|
+
| `popupOverlayOptions` | `PopupOverlayOptions` | - | Options for login popup overlays |
|
|
209
|
+
| `announceProvider` | `boolean` | `true` | Whether to announce via EIP-6963 |
|
|
210
|
+
| `feeTokenSymbol` | `string` | `'IMX'` | Preferred token symbol for relayer fees |
|
|
211
|
+
| `jsonRpcReferrer` | `string` | - | Referrer URL sent with JSON-RPC requests |
|
|
212
|
+
| `crossSdkBridgeEnabled` | `boolean` | `false` | Enable cross-SDK bridge mode |
|
|
213
|
+
| `forceScwDeployBeforeMessageSignature` | `boolean` | `false` | Force SCW deployment before message signature |
|
|
214
|
+
| `getUser` | `GetUserFunction` | Internal | Custom function to get user (for external auth integration) |
|
|
215
|
+
|
|
216
|
+
#### Returns
|
|
217
|
+
|
|
218
|
+
`Promise<Provider>` - An EIP-1193 compliant provider.
|
|
219
|
+
|
|
220
|
+
### Provider Methods
|
|
221
|
+
|
|
222
|
+
The returned provider supports standard Ethereum JSON-RPC methods:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Get accounts (triggers login if needed)
|
|
226
|
+
const accounts = await provider.request({ method: 'eth_requestAccounts' });
|
|
227
|
+
|
|
228
|
+
// Get current accounts (returns empty if not connected)
|
|
229
|
+
const accounts = await provider.request({ method: 'eth_accounts' });
|
|
230
|
+
|
|
231
|
+
// Get chain ID
|
|
232
|
+
const chainId = await provider.request({ method: 'eth_chainId' });
|
|
233
|
+
|
|
234
|
+
// Send transaction
|
|
235
|
+
const txHash = await provider.request({
|
|
236
|
+
method: 'eth_sendTransaction',
|
|
237
|
+
params: [{
|
|
238
|
+
to: '0x...',
|
|
239
|
+
value: '0x...',
|
|
240
|
+
data: '0x...',
|
|
241
|
+
}],
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Sign message (personal_sign)
|
|
245
|
+
const signature = await provider.request({
|
|
246
|
+
method: 'personal_sign',
|
|
247
|
+
params: ['0x...message', '0x...address'],
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
// Sign typed data (EIP-712)
|
|
251
|
+
const signature = await provider.request({
|
|
252
|
+
method: 'eth_signTypedData_v4',
|
|
253
|
+
params: ['0x...address', JSON.stringify(typedData)],
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Chain Configuration
|
|
260
|
+
|
|
261
|
+
### Chain ID Constants
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import {
|
|
265
|
+
IMMUTABLE_ZKEVM_MAINNET_CHAIN_ID, // 13371
|
|
266
|
+
IMMUTABLE_ZKEVM_TESTNET_CHAIN_ID, // 13473
|
|
267
|
+
ARBITRUM_ONE_CHAIN_ID, // 42161
|
|
268
|
+
ARBITRUM_SEPOLIA_CHAIN_ID, // 421614
|
|
269
|
+
} from '@imtbl/wallet';
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Preset Chain Configurations
|
|
273
|
+
|
|
274
|
+
#### Immutable zkEVM
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import {
|
|
278
|
+
IMMUTABLE_ZKEVM_MAINNET_CHAIN, // Mainnet config
|
|
279
|
+
IMMUTABLE_ZKEVM_TESTNET_CHAIN, // Testnet config
|
|
280
|
+
DEFAULT_CHAINS, // [testnet, mainnet]
|
|
281
|
+
} from '@imtbl/wallet';
|
|
282
|
+
|
|
283
|
+
// Use testnet only
|
|
284
|
+
const provider = await connectWallet({
|
|
285
|
+
chains: [IMMUTABLE_ZKEVM_TESTNET_CHAIN],
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// Use mainnet only
|
|
289
|
+
const provider = await connectWallet({
|
|
290
|
+
chains: [IMMUTABLE_ZKEVM_MAINNET_CHAIN],
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Use both (default)
|
|
294
|
+
const provider = await connectWallet({
|
|
295
|
+
chains: DEFAULT_CHAINS,
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### Arbitrum (Multi-chain Support)
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
import {
|
|
303
|
+
ARBITRUM_ONE_CHAIN, // Arbitrum One Mainnet
|
|
304
|
+
ARBITRUM_SEPOLIA_CHAIN, // Arbitrum Sepolia Testnet
|
|
305
|
+
} from '@imtbl/wallet';
|
|
306
|
+
|
|
307
|
+
// Connect to Arbitrum One
|
|
308
|
+
const provider = await connectWallet({
|
|
309
|
+
chains: [ARBITRUM_ONE_CHAIN],
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Chain Presets (Spread-friendly)
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
import {
|
|
317
|
+
IMMUTABLE_ZKEVM_MAINNET, // { chains: [mainnet] }
|
|
318
|
+
IMMUTABLE_ZKEVM_TESTNET, // { chains: [testnet] }
|
|
319
|
+
IMMUTABLE_ZKEVM_MULTICHAIN, // { chains: [testnet, mainnet] }
|
|
320
|
+
ARBITRUM_ONE, // { chains: [arbitrum one] }
|
|
321
|
+
ARBITRUM_SEPOLIA, // { chains: [arbitrum sepolia] }
|
|
322
|
+
} from '@imtbl/wallet';
|
|
323
|
+
|
|
324
|
+
// Easy to spread into connectWallet
|
|
325
|
+
const provider = await connectWallet({
|
|
326
|
+
...IMMUTABLE_ZKEVM_MAINNET,
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Custom Chain Configuration
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
import type { ChainConfig } from '@imtbl/wallet';
|
|
334
|
+
|
|
335
|
+
const customChain: ChainConfig = {
|
|
336
|
+
chainId: 13473,
|
|
337
|
+
name: 'Immutable zkEVM Testnet',
|
|
338
|
+
rpcUrl: 'https://rpc.testnet.immutable.com',
|
|
339
|
+
relayerUrl: 'https://api.sandbox.immutable.com/relayer-mr',
|
|
340
|
+
apiUrl: 'https://api.sandbox.immutable.com',
|
|
341
|
+
passportDomain: 'https://passport.sandbox.immutable.com',
|
|
342
|
+
// Optional: Magic TEE config for dev environments
|
|
343
|
+
magicPublishableApiKey: 'pk_...',
|
|
344
|
+
magicProviderId: '...',
|
|
345
|
+
magicTeeBasePath: 'https://tee.express.magiclabs.com',
|
|
346
|
+
// Optional: Fee token (defaults to 'IMX')
|
|
347
|
+
feeTokenSymbol: 'IMX',
|
|
348
|
+
};
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Chain Registry Utilities
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
import { getChainConfig, getEvmChainFromChainId } from '@imtbl/wallet';
|
|
355
|
+
|
|
356
|
+
// Get chain config by chain ID
|
|
357
|
+
const config = getChainConfig(13371); // Returns IMMUTABLE_ZKEVM_MAINNET_CHAIN
|
|
358
|
+
|
|
359
|
+
// Get EVM chain type from chain ID
|
|
360
|
+
const evmChain = getEvmChainFromChainId(13371); // Returns EvmChain.ZKEVM
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Wallet Linking
|
|
366
|
+
|
|
367
|
+
Link external wallets (e.g., MetaMask, hardware wallets) to a user's Immutable Passport account.
|
|
368
|
+
|
|
369
|
+
### Get Linked Addresses
|
|
370
|
+
|
|
371
|
+
Retrieve all wallet addresses linked to the current user's account:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
import { getLinkedAddresses } from '@imtbl/wallet';
|
|
375
|
+
import { Auth } from '@imtbl/auth';
|
|
376
|
+
import { MultiRollupApiClients, createConfig } from '@imtbl/generated-clients';
|
|
377
|
+
|
|
378
|
+
const auth = new Auth({ /* ... */ });
|
|
379
|
+
const apiConfig = createConfig({ basePath: 'https://api.immutable.com' });
|
|
380
|
+
const apiClient = new MultiRollupApiClients({
|
|
381
|
+
indexer: apiConfig,
|
|
382
|
+
orderBook: apiConfig,
|
|
383
|
+
passport: apiConfig,
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
const linkedAddresses = await getLinkedAddresses(auth, apiClient);
|
|
387
|
+
console.log('Linked wallets:', linkedAddresses);
|
|
388
|
+
// ['0x1234...', '0x5678...']
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Link External Wallet
|
|
392
|
+
|
|
393
|
+
Link a new external wallet to the user's account:
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { linkExternalWallet } from '@imtbl/wallet';
|
|
397
|
+
import type { LinkWalletParams, LinkedWallet } from '@imtbl/wallet';
|
|
398
|
+
|
|
399
|
+
// 1. Get a signature from the external wallet
|
|
400
|
+
const walletAddress = '0x...'; // Address from MetaMask/external wallet
|
|
401
|
+
const nonce = 'unique-nonce-123'; // Generate a unique nonce
|
|
402
|
+
const message = `Link wallet ${walletAddress} with nonce ${nonce}`;
|
|
403
|
+
|
|
404
|
+
// Sign the message with the external wallet (e.g., using ethers.js or viem)
|
|
405
|
+
const signature = await externalWallet.signMessage(message);
|
|
406
|
+
|
|
407
|
+
// 2. Link the wallet
|
|
408
|
+
const params: LinkWalletParams = {
|
|
409
|
+
type: 'metamask', // Wallet type identifier
|
|
410
|
+
walletAddress,
|
|
411
|
+
signature,
|
|
412
|
+
nonce,
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const linkedWallet: LinkedWallet = await linkExternalWallet(
|
|
416
|
+
auth,
|
|
417
|
+
apiClient,
|
|
418
|
+
params
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
console.log('Linked wallet:', linkedWallet);
|
|
422
|
+
// {
|
|
423
|
+
// address: '0x...',
|
|
424
|
+
// type: 'metamask',
|
|
425
|
+
// created_at: '2024-01-01T00:00:00Z',
|
|
426
|
+
// updated_at: '2024-01-01T00:00:00Z',
|
|
427
|
+
// clientName: 'your-client'
|
|
428
|
+
// }
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Linking Errors
|
|
432
|
+
|
|
433
|
+
The wallet linking API may return specific error codes:
|
|
434
|
+
|
|
435
|
+
| Error Code | Description |
|
|
436
|
+
|------------|-------------|
|
|
437
|
+
| `ALREADY_LINKED` | This wallet is already linked to an account |
|
|
438
|
+
| `MAX_WALLETS_LINKED` | Maximum number of linked wallets reached |
|
|
439
|
+
| `DUPLICATE_NONCE` | The nonce has already been used |
|
|
440
|
+
| `VALIDATION_ERROR` | Invalid signature or parameters |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## EIP-6963 Provider Discovery
|
|
445
|
+
|
|
446
|
+
The wallet automatically announces itself via [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963) for wallet discovery by dApps.
|
|
447
|
+
|
|
448
|
+
### Automatic Announcement
|
|
449
|
+
|
|
450
|
+
By default, `connectWallet` announces the provider:
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
const provider = await connectWallet();
|
|
454
|
+
// Provider is automatically announced via EIP-6963
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Disable Announcement
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
const provider = await connectWallet({
|
|
461
|
+
announceProvider: false, // Don't announce via EIP-6963
|
|
462
|
+
});
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Manual Announcement
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
import { announceProvider, passportProviderInfo } from '@imtbl/wallet';
|
|
469
|
+
|
|
470
|
+
// Manually announce a provider
|
|
471
|
+
announceProvider({
|
|
472
|
+
info: passportProviderInfo,
|
|
473
|
+
provider: yourProvider,
|
|
474
|
+
});
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Provider Info
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
import { passportProviderInfo } from '@imtbl/wallet';
|
|
481
|
+
|
|
482
|
+
console.log(passportProviderInfo);
|
|
483
|
+
// {
|
|
484
|
+
// uuid: '...',
|
|
485
|
+
// name: 'Immutable Passport',
|
|
486
|
+
// icon: '...',
|
|
487
|
+
// rdns: 'com.immutable.passport'
|
|
488
|
+
// }
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
---
|
|
492
|
+
|
|
493
|
+
## Events
|
|
494
|
+
|
|
495
|
+
The provider emits standard EIP-1193 events:
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
// Account changes
|
|
499
|
+
provider.on('accountsChanged', (accounts: string[]) => {
|
|
500
|
+
console.log('Accounts changed:', accounts);
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
// Chain changes
|
|
504
|
+
provider.on('chainChanged', (chainId: string) => {
|
|
505
|
+
console.log('Chain changed:', chainId);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
// Disconnection
|
|
509
|
+
provider.on('disconnect', (error: Error) => {
|
|
510
|
+
console.log('Disconnected:', error);
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
// Remove listener
|
|
514
|
+
provider.removeListener('accountsChanged', handler);
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## Error Handling
|
|
520
|
+
|
|
521
|
+
### WalletError
|
|
522
|
+
|
|
523
|
+
The SDK throws `WalletError` for wallet-related errors:
|
|
524
|
+
|
|
525
|
+
```typescript
|
|
526
|
+
import { connectWallet, WalletError, WalletErrorType } from '@imtbl/wallet';
|
|
527
|
+
|
|
528
|
+
try {
|
|
529
|
+
const provider = await connectWallet();
|
|
530
|
+
const accounts = await provider.request({ method: 'eth_requestAccounts' });
|
|
531
|
+
} catch (error) {
|
|
532
|
+
if (error instanceof WalletError) {
|
|
533
|
+
switch (error.type) {
|
|
534
|
+
case WalletErrorType.NOT_LOGGED_IN_ERROR:
|
|
535
|
+
console.log('User is not logged in');
|
|
536
|
+
break;
|
|
537
|
+
case WalletErrorType.WALLET_CONNECTION_ERROR:
|
|
538
|
+
console.log('Failed to connect wallet:', error.message);
|
|
539
|
+
break;
|
|
540
|
+
case WalletErrorType.TRANSACTION_REJECTED:
|
|
541
|
+
console.log('User rejected the transaction');
|
|
542
|
+
break;
|
|
543
|
+
case WalletErrorType.UNAUTHORIZED:
|
|
544
|
+
console.log('Unauthorized - call eth_requestAccounts first');
|
|
545
|
+
break;
|
|
546
|
+
case WalletErrorType.GUARDIAN_ERROR:
|
|
547
|
+
console.log('Guardian validation failed');
|
|
548
|
+
break;
|
|
549
|
+
case WalletErrorType.INVALID_CONFIGURATION:
|
|
550
|
+
console.log('Invalid wallet configuration');
|
|
551
|
+
break;
|
|
552
|
+
case WalletErrorType.SERVICE_UNAVAILABLE_ERROR:
|
|
553
|
+
console.log('Service temporarily unavailable');
|
|
554
|
+
break;
|
|
555
|
+
default:
|
|
556
|
+
console.error('Wallet error:', error.message);
|
|
557
|
+
}
|
|
558
|
+
} else {
|
|
559
|
+
console.error('Unexpected error:', error);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Error Types
|
|
565
|
+
|
|
566
|
+
| Error Type | Description |
|
|
567
|
+
|------------|-------------|
|
|
568
|
+
| `NOT_LOGGED_IN_ERROR` | User is not authenticated |
|
|
569
|
+
| `WALLET_CONNECTION_ERROR` | Failed to connect or link wallet |
|
|
570
|
+
| `TRANSACTION_REJECTED` | User rejected a transaction |
|
|
571
|
+
| `UNAUTHORIZED` | Operation requires authentication |
|
|
572
|
+
| `GUARDIAN_ERROR` | Guardian (security) validation failed |
|
|
573
|
+
| `INVALID_CONFIGURATION` | Invalid wallet configuration |
|
|
574
|
+
| `SERVICE_UNAVAILABLE_ERROR` | Backend service unavailable |
|
|
575
|
+
|
|
576
|
+
### JSON-RPC Errors
|
|
577
|
+
|
|
578
|
+
For low-level RPC errors:
|
|
579
|
+
|
|
580
|
+
```typescript
|
|
581
|
+
import { JsonRpcError, ProviderErrorCode, RpcErrorCode } from '@imtbl/wallet';
|
|
582
|
+
|
|
583
|
+
// Standard provider error codes (EIP-1193)
|
|
584
|
+
ProviderErrorCode.USER_REJECTED_REQUEST // 4001
|
|
585
|
+
ProviderErrorCode.UNAUTHORIZED // 4100
|
|
586
|
+
ProviderErrorCode.UNSUPPORTED_METHOD // 4200
|
|
587
|
+
ProviderErrorCode.DISCONNECTED // 4900
|
|
588
|
+
|
|
589
|
+
// Standard RPC error codes
|
|
590
|
+
RpcErrorCode.INVALID_REQUEST // -32600
|
|
591
|
+
RpcErrorCode.METHOD_NOT_FOUND // -32601
|
|
592
|
+
RpcErrorCode.INVALID_PARAMS // -32602
|
|
593
|
+
RpcErrorCode.INTERNAL_ERROR // -32603
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## TypeScript
|
|
599
|
+
|
|
600
|
+
Full TypeScript support is included:
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
import type {
|
|
604
|
+
// Connection options
|
|
605
|
+
ConnectWalletOptions,
|
|
606
|
+
ChainConfig,
|
|
607
|
+
PopupOverlayOptions,
|
|
608
|
+
|
|
609
|
+
// Provider types
|
|
610
|
+
Provider,
|
|
611
|
+
RequestArguments,
|
|
612
|
+
|
|
613
|
+
// User types
|
|
614
|
+
GetUserFunction,
|
|
615
|
+
User,
|
|
616
|
+
UserProfile,
|
|
617
|
+
UserZkEvm,
|
|
618
|
+
|
|
619
|
+
// Wallet linking
|
|
620
|
+
LinkWalletParams,
|
|
621
|
+
LinkedWallet,
|
|
622
|
+
|
|
623
|
+
// Transaction types
|
|
624
|
+
TypedDataPayload,
|
|
625
|
+
MetaTransaction,
|
|
626
|
+
RelayerTransaction,
|
|
627
|
+
RelayerTransactionStatus,
|
|
628
|
+
FeeOption,
|
|
629
|
+
|
|
630
|
+
// Event types
|
|
631
|
+
WalletEventMap,
|
|
632
|
+
ProviderEventMap,
|
|
633
|
+
AccountsChangedEvent,
|
|
634
|
+
|
|
635
|
+
// EIP-6963
|
|
636
|
+
EIP6963ProviderDetail,
|
|
637
|
+
EIP6963ProviderInfo,
|
|
638
|
+
} from '@imtbl/wallet';
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
## Advanced Usage
|
|
644
|
+
|
|
645
|
+
### Direct Provider Access
|
|
646
|
+
|
|
647
|
+
For advanced use cases, you can access the provider classes directly:
|
|
648
|
+
|
|
649
|
+
```typescript
|
|
650
|
+
import { ZkEvmProvider, SequenceProvider } from '@imtbl/wallet';
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### Relayer Client
|
|
654
|
+
|
|
655
|
+
For direct relayer interaction:
|
|
656
|
+
|
|
657
|
+
```typescript
|
|
658
|
+
import { RelayerClient } from '@imtbl/wallet';
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Wallet Helpers
|
|
662
|
+
|
|
663
|
+
Utility functions for wallet operations:
|
|
664
|
+
|
|
665
|
+
```typescript
|
|
666
|
+
import * as walletHelpers from '@imtbl/wallet';
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## Related Packages
|
|
672
|
+
|
|
673
|
+
### Optional Auth Integrations
|
|
674
|
+
|
|
675
|
+
These packages are only needed if you want to manage authentication separately from the wallet:
|
|
676
|
+
|
|
677
|
+
| Package | Description |
|
|
678
|
+
|---------|-------------|
|
|
679
|
+
| [`@imtbl/auth-next-client`](../auth-next-client/README.md) | NextAuth client-side hooks for Next.js apps |
|
|
680
|
+
| [`@imtbl/auth-next-server`](../auth-next-server/README.md) | NextAuth server-side configuration |
|
|
681
|
+
| [`@imtbl/auth`](../auth/README.md) | Core authentication for custom auth flows |
|
|
682
|
+
|
|
683
|
+
### Other Immutable Packages
|
|
684
|
+
|
|
685
|
+
| Package | Description |
|
|
686
|
+
|---------|-------------|
|
|
687
|
+
| [`@imtbl/generated-clients`](../generated-clients/README.md) | API clients for Immutable services |
|
|
688
|
+
| [`@imtbl/metrics`](../metrics/README.md) | Metrics and analytics utilities |
|