@phantom/browser-sdk 0.3.9 → 1.0.0-beta.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @phantom/browser-sdk
2
2
 
3
- Browser SDK for Phantom Wallet supporting both injected and embedded non-custodial wallets.
3
+ Browser SDK for Phantom Wallet supporting both injected and embedded non-custodial wallets with chain-specific APIs.
4
4
 
5
5
  ## Quick Start
6
6
 
@@ -11,55 +11,164 @@ npm install @phantom/browser-sdk
11
11
  ### Injected Provider (Browser Extension)
12
12
 
13
13
  ```typescript
14
- import { BrowserSDK, NetworkId, AddressType } from "@phantom/browser-sdk";
14
+ import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
15
15
 
16
16
  // Connect to Phantom browser extension
17
17
  const sdk = new BrowserSDK({
18
18
  providerType: "injected",
19
- addressTypes: [AddressType.solana],
19
+ addressTypes: [AddressType.solana, AddressType.ethereum],
20
20
  });
21
21
 
22
22
  const { addresses } = await sdk.connect();
23
23
  console.log("Connected addresses:", addresses);
24
24
 
25
+ // Chain-specific operations
26
+ const message = "Hello from Phantom!";
27
+ const solanaSignature = await sdk.solana.signMessage(message);
28
+
29
+ // Encode the message as hex for EVM
30
+ const encoded = "0x" + Buffer.from(message, "utf8").toString("hex");
31
+ const ethSignature = await sdk.ethereum.signPersonalMessage(encoded, addresses[1].address);
32
+
25
33
  // Sign and send transactions
26
- const result = await sdk.signAndSendTransaction({
27
- networkId: NetworkId.SOLANA_MAINNET,
28
- transaction: mySolanaTransaction,
29
- });
34
+ const solanaResult = await sdk.solana.signAndSendTransaction(mySolanaTransaction);
35
+ const ethResult = await sdk.ethereum.sendTransaction(myEthTransaction);
30
36
  ```
31
37
 
32
38
  ### Embedded Provider
33
39
 
34
40
  ```typescript
35
- import { BrowserSDK, AddressType, NetworkId } from "@phantom/browser-sdk";
41
+ import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
36
42
 
37
43
  // Create embedded non-custodial wallet
38
44
  const sdk = new BrowserSDK({
39
45
  providerType: "embedded",
40
46
  addressTypes: [AddressType.solana, AddressType.ethereum],
41
47
  apiBaseUrl: "https://api.phantom.app/v1/wallets",
42
- organizationId: "your-org-id",
48
+ appId: "your-app-id",
43
49
  });
44
50
 
45
51
  const { addresses } = await sdk.connect();
46
52
  console.log("Addresses:", addresses);
47
53
 
48
- const result = await sdk.signAndSendTransaction({
49
- networkId: NetworkId.SOLANA_MAINNET,
50
- transaction: mySolanaTransaction,
51
- });
54
+ // Use chain-specific APIs
55
+ const solanaResult = await sdk.solana.signAndSendTransaction(mySolanaTransaction);
56
+ const ethResult = await sdk.ethereum.sendTransaction(myEthTransaction);
52
57
  ```
53
58
 
54
59
  ## Features
55
60
 
56
61
  - **🔒 Non-Custodial**: Full user control of private keys for both injected and embedded wallets
57
62
  - **🌐 Dual Provider Support**: Works with Phantom browser extension or creates embedded wallets
63
+ - **⛓️ Chain-Specific APIs**: Dedicated interfaces for Solana and Ethereum operations
58
64
  - **🛠️ Native Transactions**: Work with blockchain-native objects, not base64url strings
59
- - **🔗 Multi-Chain**: Solana, Ethereum, Bitcoin, Sui support
65
+ - **🔗 Multi-Chain**: Solana and Ethereum support with dedicated methods
60
66
  - **⚡ TypeScript**: Full type safety for all transaction formats
61
67
  - **🎯 Unified API**: Same interface for both injected and embedded providers
62
68
 
69
+ ## Connection Flow
70
+
71
+ After instantiating the SDK, use `sdk.connect()` to establish a connection to the wallet:
72
+
73
+ ```typescript
74
+ import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
75
+
76
+ // 1. Create SDK instance
77
+ const sdk = new BrowserSDK({
78
+ providerType: "injected",
79
+ addressTypes: [AddressType.solana, AddressType.ethereum],
80
+ });
81
+
82
+ // 2. Connect to wallet
83
+ const { addresses } = await sdk.connect();
84
+ console.log("Connected addresses:", addresses);
85
+
86
+ // 3. Use chain-specific methods
87
+ const signature = await sdk.solana.signMessage("Hello!");
88
+ const ethResult = await sdk.ethereum.sendTransaction({
89
+ to: "0x...",
90
+ value: "1000000000000000000",
91
+ gas: "21000",
92
+ });
93
+ ```
94
+
95
+ ### Connection Options
96
+
97
+ For embedded user-wallets, you can specify authentication providers:
98
+
99
+ ```typescript
100
+ // Default: Show provider selection screen
101
+ const result = await sdk.connect();
102
+
103
+ // Google authentication (skips provider selection)
104
+ const result = await sdk.connect({
105
+ authOptions: {
106
+ provider: "google",
107
+ },
108
+ });
109
+
110
+ // Apple authentication (skips provider selection)
111
+ const result = await sdk.connect({
112
+ authOptions: {
113
+ provider: "apple",
114
+ },
115
+ });
116
+ ```
117
+
118
+ ## Chain-Specific APIs
119
+
120
+ The SDK provides separate interfaces for each blockchain with optimized methods:
121
+
122
+ ### Solana Chain (`sdk.solana`)
123
+
124
+ ```typescript
125
+ // Message signing
126
+ const signature = await sdk.solana.signMessage("Hello Solana!");
127
+
128
+ // Transaction signing (without sending)
129
+ const signedTx = await sdk.solana.signTransaction(transaction);
130
+
131
+ // Sign and send transaction
132
+ const result = await sdk.solana.signAndSendTransaction(transaction);
133
+
134
+ // Network switching
135
+ await sdk.solana.switchNetwork("devnet");
136
+
137
+ // Utilities
138
+ const publicKey = await sdk.solana.getPublicKey();
139
+ const isConnected = sdk.solana.isConnected();
140
+ ```
141
+
142
+ ### Ethereum Chain (`sdk.ethereum`)
143
+
144
+ ```typescript
145
+ // EIP-1193 requests
146
+ const accounts = await sdk.ethereum.request({ method: "eth_accounts" });
147
+ const chainId = await sdk.ethereum.request({ method: "eth_chainId" });
148
+
149
+ // Message signing
150
+ const signature = await sdk.ethereum.signPersonalMessage(message, address);
151
+
152
+ // EIP-712 typed data signing
153
+ const typedDataSignature = await sdk.ethereum.signTypedData(typedData, address);
154
+
155
+ // Transaction sending
156
+ const result = await sdk.ethereum.sendTransaction({
157
+ to: "0x...",
158
+ value: "1000000000000000000", // 1 ETH in wei
159
+ gas: "21000",
160
+ });
161
+
162
+ // Network switching
163
+ await sdk.ethereum.switchChain(1); // Ethereum mainnet
164
+ await sdk.ethereum.switchChain(137); // Polygon
165
+
166
+ // Utilities
167
+ const chainId = await sdk.ethereum.getChainId();
168
+ const accounts = await sdk.ethereum.getAccounts();
169
+ const isConnected = sdk.ethereum.isConnected();
170
+ ```
171
+
63
172
  ## Provider Types
64
173
 
65
174
  ### Injected Provider
@@ -69,7 +178,7 @@ Uses the Phantom browser extension installed by the user. No additional configur
69
178
  ```typescript
70
179
  const sdk = new BrowserSDK({
71
180
  providerType: "injected",
72
- addressTypes: [AddressType.solana],
181
+ addressTypes: [AddressType.solana, AddressType.ethereum],
73
182
  });
74
183
  ```
75
184
 
@@ -82,14 +191,12 @@ const sdk = new BrowserSDK({
82
191
  providerType: "embedded",
83
192
  addressTypes: [AddressType.solana, AddressType.ethereum],
84
193
  apiBaseUrl: "https://api.phantom.app/v1/wallets",
85
- organizationId: "your-org-id",
194
+ appId: "your-app-id",
86
195
  embeddedWalletType: "app-wallet", // or 'user-wallet'
87
196
  authOptions: {
88
197
  authUrl: "https://auth.phantom.app", // optional, defaults to "https://connect.phantom.app"
89
198
  redirectUrl: "https://yourapp.com/callback", // optional, defaults to current page
90
199
  },
91
- appName: "My DApp", // optional, for branding
92
- appLogo: "https://myapp.com/logo.png", // optional, for branding
93
200
  autoConnect: true, // optional, auto-connect to existing session (default: true for embedded)
94
201
  });
95
202
  ```
@@ -128,14 +235,12 @@ const sdk = new BrowserSDK({
128
235
  });
129
236
  ```
130
237
 
131
- ### Available AddressTypes (Embedded Only)
238
+ ### Available AddressTypes
132
239
 
133
- | AddressType | Networks Supported |
134
- | --------------------------- | ------------------------------------------- |
135
- | `AddressType.solana` | Solana Mainnet, Devnet, Testnet |
136
- | `AddressType.ethereum` | Ethereum, Polygon, Arbitrum, Optimism, Base |
137
- | `AddressType.bitcoinSegwit` | Bitcoin Mainnet, Testnet |
138
- | `AddressType.sui` | Sui Mainnet, Testnet, Devnet |
240
+ | AddressType | Supported Chains |
241
+ | ---------------------- | ------------------------------------- |
242
+ | `AddressType.solana` | Solana Mainnet, Devnet, Testnet |
243
+ | `AddressType.ethereum` | Ethereum, Polygon, Arbitrum, and more |
139
244
 
140
245
  ### Solana Provider Configuration
141
246
 
@@ -212,13 +317,11 @@ new BrowserSDK(config: BrowserSDKConfig)
212
317
  ```typescript
213
318
  interface BrowserSDKConfig {
214
319
  providerType: "injected" | "embedded";
215
- appName?: string; // Optional app name for branding
216
- appLogo?: string; // Optional app logo URL for branding
217
320
  addressTypes?: [AddressType, ...AddressType[]]; // Networks to enable (e.g., [AddressType.solana])
218
321
 
219
322
  // Required for embedded provider only
220
323
  apiBaseUrl?: string; // Phantom API base URL
221
- organizationId?: string; // Your organization ID
324
+ appId?: string; // Your app ID (required for embedded provider)
222
325
  authOptions?: {
223
326
  authUrl?: string; // Custom auth URL (default: "https://connect.phantom.app")
224
327
  redirectUrl?: string; // Custom redirect URL after authentication
@@ -229,7 +332,23 @@ interface BrowserSDKConfig {
229
332
  }
230
333
  ```
231
334
 
232
- ### Methods
335
+ ### Extension Detection
336
+
337
+ For injected provider usage, you can check if the Phantom extension is installed:
338
+
339
+ ```typescript
340
+ import { waitForPhantomExtension } from "@phantom/browser-sdk";
341
+
342
+ const isAvailable = await waitForPhantomExtension(5000);
343
+
344
+ if (isAvailable) {
345
+ console.log("Phantom extension is available!");
346
+ } else {
347
+ console.log("Phantom extension not found");
348
+ }
349
+ ```
350
+
351
+ ### Core Methods
233
352
 
234
353
  #### connect()
235
354
 
@@ -237,114 +356,210 @@ Connect to wallet and get addresses for configured AddressTypes.
237
356
 
238
357
  ```typescript
239
358
  const result = await sdk.connect();
240
- // Returns: { walletId: string, addresses: WalletAddress[] }
359
+ // Returns: { walletId?: string, addresses: WalletAddress[] }
241
360
  // addresses only includes types from addressTypes config
242
361
  ```
243
362
 
244
- For embedded user-wallets, you can specify authentication options:
363
+ #### getAddresses()
364
+
365
+ Get connected wallet addresses.
245
366
 
246
367
  ```typescript
247
- // Phantom Connect with provider selection (default)
248
- const result = await sdk.connect();
368
+ const addresses = await sdk.getAddresses();
369
+ // Returns addresses matching configured AddressTypes
370
+ ```
249
371
 
250
- // Phantom Connect with Google authentication (skips provider selection)
251
- const result = await sdk.connect({
252
- authOptions: {
253
- provider: "google",
254
- },
255
- });
372
+ #### disconnect()
256
373
 
257
- // Phantom Connect with Apple authentication (skips provider selection)
258
- const result = await sdk.connect({
259
- authOptions: {
260
- provider: "apple",
261
- },
262
- });
374
+ Disconnect from wallet and clear session.
263
375
 
264
- // JWT authentication (direct API call)
265
- const result = await sdk.connect({
266
- authOptions: {
267
- provider: "jwt",
268
- jwtToken: "your-jwt-token",
269
- customAuthData: { userId: "user123" },
270
- },
271
- });
376
+ ```typescript
377
+ await sdk.disconnect();
378
+ ```
379
+
380
+ #### isConnected()
381
+
382
+ Check if SDK is connected to a wallet.
383
+
384
+ ```typescript
385
+ const connected = sdk.isConnected();
272
386
  ```
273
387
 
274
- **Authentication Options:**
388
+ #### getWalletId()
275
389
 
276
- - `provider` - Authentication method: `"google"`, `"apple"`, or `"jwt"`
277
- - If not specified: Shows provider selection screen on Phantom Connect
278
- - If `"google"` or `"apple"`: Skips provider selection and uses specified provider
279
- - If `"jwt"`: Uses JWT authentication flow via API call
280
- - `jwtToken` - Required when `provider` is `"jwt"`. Your JWT token for authentication
281
- - `customAuthData` - Additional data to pass to authentication service
390
+ Get the wallet ID (embedded wallets only).
282
391
 
283
- **Authentication Flow Types:**
392
+ ```typescript
393
+ const walletId = sdk.getWalletId();
394
+ // Returns string for embedded wallets, null for injected
395
+ ```
284
396
 
285
- 1. **Phantom Connect (Redirect-based)**: Used when `provider` is undefined, `"google"`, or `"apple"`
286
- - Redirects to `https://connect.phantom.app` (or custom `authOptions.authUrl` from config)
287
- - Handles OAuth flow with selected provider
288
- - Returns to your app with authentication result using `authOptions.redirectUrl` or current page
397
+ ### Solana Chain Methods
289
398
 
290
- 2. **JWT Authentication (API-based)**: Used when `provider` is `"jwt"`
291
- - Makes direct API call to `/api/auth/jwt` endpoint
292
- - Validates JWT token server-side
293
- - Returns wallet immediately without redirect
399
+ #### signMessage(message)
400
+
401
+ Sign a message with the Solana wallet.
402
+
403
+ ```typescript
404
+ const signature = await sdk.solana.signMessage("Hello Solana!");
405
+ // Returns: { signature: string, rawSignature: string }
406
+ ```
407
+
408
+ #### signTransaction(transaction)
409
+
410
+ Sign a transaction without sending it.
411
+
412
+ ```typescript
413
+ const signedTx = await sdk.solana.signTransaction(transaction);
414
+ // Returns the signed transaction object
415
+ ```
294
416
 
295
417
  #### signAndSendTransaction(transaction)
296
418
 
297
- Sign and send a native transaction object.
419
+ Sign and send a transaction to the Solana network.
298
420
 
299
421
  ```typescript
300
- // Solana transaction
301
- const result = await sdk.signAndSendTransaction({
302
- networkId: NetworkId.SOLANA_MAINNET,
303
- transaction: solanaTransaction, // Native Transaction or VersionedTransaction
422
+ const result = await sdk.solana.signAndSendTransaction(transaction);
423
+ // Returns: { hash: string, rawTransaction: string, blockExplorer?: string }
424
+ ```
425
+
426
+ #### switchNetwork(network)
427
+
428
+ Switch between Solana networks.
429
+
430
+ ```typescript
431
+ await sdk.solana.switchNetwork("mainnet");
432
+ await sdk.solana.switchNetwork("devnet");
433
+ ```
434
+
435
+ #### getPublicKey()
436
+
437
+ Get the current Solana public key.
438
+
439
+ ```typescript
440
+ const publicKey = await sdk.solana.getPublicKey();
441
+ // Returns: string | null
442
+ ```
443
+
444
+ #### isConnected()
445
+
446
+ Check if connected to Solana wallet.
447
+
448
+ ```typescript
449
+ const connected = sdk.solana.isConnected();
450
+ // Returns: boolean
451
+ ```
452
+
453
+ ### Ethereum Chain Methods
454
+
455
+ #### request(args)
456
+
457
+ Make an EIP-1193 compatible request.
458
+
459
+ ```typescript
460
+ const accounts = await sdk.ethereum.request({ method: "eth_accounts" });
461
+ const chainId = await sdk.ethereum.request({ method: "eth_chainId" });
462
+ const balance = await sdk.ethereum.request({
463
+ method: "eth_getBalance",
464
+ params: [address, "latest"],
304
465
  });
466
+ ```
467
+
468
+ #### signPersonalMessage(message, address)
469
+
470
+ Sign a personal message.
471
+
472
+ ```typescript
473
+ const signature = await sdk.ethereum.signPersonalMessage("Hello Ethereum!", address);
474
+ // Returns: { signature: string, rawSignature: string }
475
+ ```
476
+
477
+ #### signTypedData(typedData, address)
478
+
479
+ Sign EIP-712 typed data.
305
480
 
306
- // Ethereum transaction
307
- const result = await sdk.signAndSendTransaction({
308
- networkId: NetworkId.ETHEREUM_MAINNET,
309
- transaction: {
310
- to: "0x...",
311
- value: parseEther("1"), // 1 ETH
312
- gas: 21000n,
481
+ ```typescript
482
+ const typedData = {
483
+ types: {
484
+ EIP712Domain: [
485
+ { name: "name", type: "string" },
486
+ { name: "version", type: "string" },
487
+ { name: "chainId", type: "uint256" },
488
+ { name: "verifyingContract", type: "address" },
489
+ ],
490
+ Mail: [
491
+ { name: "from", type: "string" },
492
+ { name: "to", type: "string" },
493
+ { name: "contents", type: "string" },
494
+ ],
313
495
  },
314
- });
496
+ primaryType: "Mail",
497
+ domain: {
498
+ name: "Ether Mail",
499
+ version: "1",
500
+ chainId: 1,
501
+ verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
502
+ },
503
+ message: {
504
+ from: "Alice",
505
+ to: "Bob",
506
+ contents: "Hello!",
507
+ },
508
+ };
509
+
510
+ const signature = await sdk.ethereum.signTypedData(typedData, address);
511
+ // Returns: { signature: string, rawSignature: string }
315
512
  ```
316
513
 
317
- #### signMessage(params)
514
+ #### sendTransaction(transaction)
318
515
 
319
- Sign a message string.
516
+ Send an Ethereum transaction.
320
517
 
321
518
  ```typescript
322
- const signature = await sdk.signMessage({
323
- message: "Hello from Phantom!",
324
- networkId: NetworkId.SOLANA_MAINNET,
519
+ const result = await sdk.ethereum.sendTransaction({
520
+ to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
521
+ value: "1000000000000000000", // 1 ETH in wei
522
+ gas: "21000",
523
+ gasPrice: "20000000000", // 20 gwei
325
524
  });
525
+ // Returns: { hash: string, rawTransaction: string, blockExplorer?: string }
326
526
  ```
327
527
 
328
- **Parameters:**
528
+ #### switchChain(chainId)
329
529
 
330
- - `params.message` (string) - Message to sign
331
- - `params.networkId` (NetworkId) - Network identifier
530
+ Switch to a different Ethereum chain.
332
531
 
333
- #### getAddresses()
532
+ ```typescript
533
+ await sdk.ethereum.switchChain(1); // Ethereum mainnet
534
+ await sdk.ethereum.switchChain(137); // Polygon
535
+ await sdk.ethereum.switchChain(42161); // Arbitrum One
536
+ ```
334
537
 
335
- Get connected wallet addresses.
538
+ #### getChainId()
539
+
540
+ Get the current chain ID.
336
541
 
337
542
  ```typescript
338
- const addresses = await sdk.getAddresses();
339
- // Returns addresses matching configured AddressTypes
543
+ const chainId = await sdk.ethereum.getChainId();
544
+ // Returns: number
340
545
  ```
341
546
 
342
- #### disconnect()
547
+ #### getAccounts()
343
548
 
344
- Disconnect from wallet and clear session.
549
+ Get connected Ethereum accounts.
345
550
 
346
551
  ```typescript
347
- await sdk.disconnect();
552
+ const accounts = await sdk.ethereum.getAccounts();
553
+ // Returns: string[]
554
+ ```
555
+
556
+ #### isConnected()
557
+
558
+ Check if connected to Ethereum wallet.
559
+
560
+ ```typescript
561
+ const connected = sdk.ethereum.isConnected();
562
+ // Returns: boolean
348
563
  ```
349
564
 
350
565
  #### autoConnect()
@@ -355,6 +570,99 @@ Attempt auto-connection using existing session. Should be called after setting u
355
570
  await sdk.autoConnect();
356
571
  ```
357
572
 
573
+ ### Auto-Confirm Methods (Injected Provider Only)
574
+
575
+ The SDK provides auto-confirm functionality that allows automatic transaction confirmation for specified chains. This feature is only available when using the injected provider (Phantom browser extension).
576
+
577
+ #### enableAutoConfirm(params?)
578
+
579
+ Enable auto-confirm for specific chains or all supported chains.
580
+
581
+ ```typescript
582
+ import { NetworkId } from "@phantom/browser-sdk";
583
+
584
+ // Enable auto-confirm for specific chains
585
+ const result = await sdk.enableAutoConfirm({
586
+ chains: [NetworkId.SOLANA_MAINNET, NetworkId.ETHEREUM_MAINNET],
587
+ });
588
+
589
+ // Enable auto-confirm for all supported chains
590
+ const result = await sdk.enableAutoConfirm();
591
+
592
+ console.log("Auto-confirm enabled:", result.enabled);
593
+ console.log("Enabled chains:", result.chains);
594
+ // Returns: { enabled: boolean, chains: NetworkId[] }
595
+ ```
596
+
597
+ #### disableAutoConfirm()
598
+
599
+ Disable auto-confirm for all chains.
600
+
601
+ ```typescript
602
+ const result = await sdk.disableAutoConfirm();
603
+ console.log("Auto-confirm disabled:", !result.enabled);
604
+ // Returns: { enabled: boolean, chains: NetworkId[] }
605
+ ```
606
+
607
+ #### getAutoConfirmStatus()
608
+
609
+ Get the current auto-confirm status and enabled chains.
610
+
611
+ ```typescript
612
+ const status = await sdk.getAutoConfirmStatus();
613
+ console.log("Auto-confirm enabled:", status.enabled);
614
+ console.log("Enabled chains:", status.chains);
615
+ // Returns: { enabled: boolean, chains: NetworkId[] }
616
+ ```
617
+
618
+ #### getSupportedAutoConfirmChains()
619
+
620
+ Get the list of chains that support auto-confirm functionality.
621
+
622
+ ```typescript
623
+ const supportedChains = await sdk.getSupportedAutoConfirmChains();
624
+ console.log("Supported chains:", supportedChains.chains);
625
+ // Returns: { chains: NetworkId[] }
626
+ ```
627
+
628
+ #### Available NetworkId Values
629
+
630
+ ```typescript
631
+ import { NetworkId } from "@phantom/browser-sdk";
632
+
633
+ // Solana networks
634
+ NetworkId.SOLANA_MAINNET; // "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
635
+ NetworkId.SOLANA_DEVNET; // "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
636
+ NetworkId.SOLANA_TESTNET; // "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z"
637
+
638
+ // Ethereum networks
639
+ NetworkId.ETHEREUM_MAINNET; // "eip155:1"
640
+ NetworkId.ETHEREUM_SEPOLIA; // "eip155:11155111"
641
+
642
+ // Polygon networks
643
+ NetworkId.POLYGON_MAINNET; // "eip155:137"
644
+ NetworkId.POLYGON_AMOY; // "eip155:80002"
645
+
646
+ // Arbitrum networks
647
+ NetworkId.ARBITRUM_ONE; // "eip155:42161"
648
+ NetworkId.ARBITRUM_SEPOLIA; // "eip155:421614"
649
+
650
+ // Optimism networks
651
+ NetworkId.OPTIMISM_MAINNET; // "eip155:10"
652
+ NetworkId.OPTIMISM_GOERLI; // "eip155:420"
653
+
654
+ // Base networks
655
+ NetworkId.BASE_MAINNET; // "eip155:8453"
656
+ NetworkId.BASE_SEPOLIA; // "eip155:84532"
657
+ ```
658
+
659
+ **Important Notes:**
660
+
661
+ - Auto-confirm methods are **only available for injected providers** (Phantom browser extension)
662
+ - Calling these methods on embedded providers will throw an error
663
+ - Auto-confirm applies to transaction confirmations, not initial connection prompts
664
+ - Users can override auto-confirm settings directly in the Phantom extension UI
665
+
358
666
  ## Debug Configuration
359
667
 
360
668
  The BrowserSDK provides dynamic debug configuration that can be changed at runtime without reinstantiating the SDK. This provides better performance and cleaner architecture.
@@ -365,14 +673,14 @@ The BrowserSDK provides dynamic debug configuration that can be changed at runti
365
673
  // Enable debug logging
366
674
  sdk.enableDebug();
367
675
 
368
- // Disable debug logging
676
+ // Disable debug logging
369
677
  sdk.disableDebug();
370
678
 
371
679
  // Set debug level
372
680
  sdk.setDebugLevel(DebugLevel.INFO);
373
681
 
374
682
  // Set debug callback function
375
- sdk.setDebugCallback((message) => {
683
+ sdk.setDebugCallback(message => {
376
684
  console.log(`[${message.category}] ${message.message}`, message.data);
377
685
  });
378
686
 
@@ -380,10 +688,10 @@ sdk.setDebugCallback((message) => {
380
688
  sdk.configureDebug({
381
689
  enabled: true,
382
690
  level: DebugLevel.DEBUG,
383
- callback: (message) => {
691
+ callback: message => {
384
692
  // Handle debug messages
385
693
  console.log(`[${message.level}] ${message.category}: ${message.message}`);
386
- }
694
+ },
387
695
  });
388
696
  ```
389
697
 
@@ -393,10 +701,10 @@ sdk.configureDebug({
393
701
  import { DebugLevel } from "@phantom/browser-sdk";
394
702
 
395
703
  // Available debug levels (in order of verbosity)
396
- DebugLevel.ERROR // 0 - Only error messages
397
- DebugLevel.WARN // 1 - Warning and error messages
398
- DebugLevel.INFO // 2 - Info, warning, and error messages
399
- DebugLevel.DEBUG // 3 - All debug messages (most verbose)
704
+ DebugLevel.ERROR; // 0 - Only error messages
705
+ DebugLevel.WARN; // 1 - Warning and error messages
706
+ DebugLevel.INFO; // 2 - Info, warning, and error messages
707
+ DebugLevel.DEBUG; // 3 - All debug messages (most verbose)
400
708
  ```
401
709
 
402
710
  ### Debug Message Structure
@@ -405,11 +713,11 @@ Debug callbacks receive a `DebugMessage` object:
405
713
 
406
714
  ```typescript
407
715
  interface DebugMessage {
408
- timestamp: number; // Unix timestamp
409
- level: DebugLevel; // Message level
410
- category: string; // Component category (e.g., "BrowserSDK", "ProviderManager")
411
- message: string; // Debug message text
412
- data?: any; // Additional debug data (optional)
716
+ timestamp: number; // Unix timestamp
717
+ level: DebugLevel; // Message level
718
+ category: string; // Component category (e.g., "BrowserSDK", "ProviderManager")
719
+ message: string; // Debug message text
720
+ data?: any; // Additional debug data (optional)
413
721
  }
414
722
  ```
415
723
 
@@ -430,17 +738,17 @@ const debugMessages: DebugMessage[] = [];
430
738
  sdk.configureDebug({
431
739
  enabled: true,
432
740
  level: DebugLevel.INFO,
433
- callback: (message) => {
741
+ callback: message => {
434
742
  debugMessages.push(message);
435
-
743
+
436
744
  // Keep only last 100 messages
437
745
  if (debugMessages.length > 100) {
438
746
  debugMessages.shift();
439
747
  }
440
-
748
+
441
749
  // Update UI
442
750
  updateDebugConsole();
443
- }
751
+ },
444
752
  });
445
753
 
446
754
  // Dynamic debug level changing
@@ -482,13 +790,22 @@ import {
482
790
  LAMPORTS_PER_SOL,
483
791
  Connection,
484
792
  } from "@solana/web3.js";
485
- import { BrowserSDK, NetworkId } from "@phantom/browser-sdk";
793
+ import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
794
+
795
+ const sdk = new BrowserSDK({
796
+ providerType: "injected",
797
+ addressTypes: [AddressType.solana],
798
+ solanaProvider: "web3js",
799
+ });
800
+
801
+ await sdk.connect();
486
802
 
487
803
  // Get recent blockhash
488
804
  const connection = new Connection("https://api.mainnet-beta.solana.com");
489
805
  const { blockhash } = await connection.getLatestBlockhash();
490
806
 
491
807
  // Create transfer instruction
808
+ const fromAddress = await sdk.solana.getPublicKey();
492
809
  const transferInstruction = SystemProgram.transfer({
493
810
  fromPubkey: new PublicKey(fromAddress),
494
811
  toPubkey: new PublicKey(toAddress),
@@ -504,26 +821,9 @@ const messageV0 = new TransactionMessage({
504
821
 
505
822
  const transaction = new VersionedTransaction(messageV0);
506
823
 
507
- // Send native transaction object - no encoding needed!
508
- const result = await sdk.signAndSendTransaction({
509
- networkId: NetworkId.SOLANA_MAINNET,
510
- transaction: transaction,
511
- });
512
-
513
- console.log("Transaction signature:", result.rawTransaction);
514
- ```
515
-
516
- **VersionedTransaction with @solana/web3.js:**
517
-
518
- ```typescript
519
- import { VersionedTransaction } from "@solana/web3.js";
520
-
521
- const versionedTx = new VersionedTransaction(message);
522
-
523
- const result = await sdk.signAndSendTransaction({
524
- networkId: NetworkId.SOLANA_DEVNET,
525
- transaction: versionedTx,
526
- });
824
+ // Send transaction using chain-specific API
825
+ const result = await sdk.solana.signAndSendTransaction(transaction);
826
+ console.log("Transaction signature:", result.hash);
527
827
  ```
528
828
 
529
829
  #### Option 2: @solana/kit (Modern Library)
@@ -544,12 +844,21 @@ import {
544
844
  address,
545
845
  compileTransaction,
546
846
  } from "@solana/kit";
547
- import { BrowserSDK, NetworkId } from "@phantom/browser-sdk";
847
+ import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
848
+
849
+ const sdk = new BrowserSDK({
850
+ providerType: "injected",
851
+ addressTypes: [AddressType.solana],
852
+ solanaProvider: "kit",
853
+ });
854
+
855
+ await sdk.connect();
548
856
 
549
857
  // Create transaction with @solana/kit
550
858
  const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
551
859
  const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
552
860
 
861
+ const userPublicKey = await sdk.solana.getPublicKey();
553
862
  const transactionMessage = pipe(
554
863
  createTransactionMessage({ version: 0 }),
555
864
  tx => setTransactionMessageFeePayer(address(userPublicKey), tx),
@@ -558,345 +867,74 @@ const transactionMessage = pipe(
558
867
 
559
868
  const transaction = compileTransaction(transactionMessage);
560
869
 
561
- const result = await sdk.signAndSendTransaction({
562
- networkId: NetworkId.SOLANA_MAINNET,
563
- transaction: transaction,
564
- });
565
- ```
566
-
567
- ### Ethereum Transactions (with Viem)
568
-
569
- ```typescript
570
- import { parseEther, parseGwei, encodeFunctionData } from "viem";
571
- import { BrowserSDK, NetworkId } from "@phantom/browser-sdk";
572
-
573
- // Simple ETH transfer
574
- const result = await sdk.signAndSendTransaction({
575
- networkId: NetworkId.ETHEREUM_MAINNET,
576
- transaction: {
577
- to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
578
- value: parseEther("1"), // 1 ETH
579
- gas: 21000n,
580
- gasPrice: parseGwei("20"), // 20 gwei
581
- },
582
- });
583
-
584
- // EIP-1559 transaction with maxFeePerGas
585
- const result = await sdk.signAndSendTransaction({
586
- networkId: NetworkId.ETHEREUM_MAINNET,
587
- transaction: {
588
- to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
589
- value: parseEther("1"),
590
- data: encodeFunctionData({
591
- abi: tokenAbi,
592
- functionName: "transfer",
593
- args: ["0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E", parseEther("1")],
594
- }),
595
- gas: 50000n,
596
- maxFeePerGas: parseGwei("30"), // 30 gwei
597
- maxPriorityFeePerGas: parseGwei("2"), // 2 gwei
598
- type: "eip1559",
599
- },
600
- });
870
+ // Send using chain-specific API
871
+ const result = await sdk.solana.signAndSendTransaction(transaction);
872
+ console.log("Transaction signature:", result.hash);
601
873
  ```
602
874
 
603
- #### Other EVM Networks
875
+ ### Ethereum Transactions
604
876
 
605
877
  ```typescript
606
- // Polygon transaction
607
- const result = await sdk.signAndSendTransaction({
608
- networkId: NetworkId.POLYGON_MAINNET,
609
- transaction: {
610
- to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
611
- value: parseEther("1"), // 1 MATIC
612
- gas: 21000n,
613
- },
614
- });
615
-
616
- // Arbitrum transaction
617
- const result = await sdk.signAndSendTransaction({
618
- networkId: NetworkId.ARBITRUM_ONE,
619
- transaction: {
620
- to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
621
- value: parseEther("0.1"), // 0.1 ETH
622
- gas: 21000n,
623
- },
624
- });
625
- ```
626
-
627
- ### Bitcoin Transactions
628
-
629
- ```typescript
630
- // Bitcoin transaction
631
- const result = await sdk.signAndSendTransaction({
632
- networkId: NetworkId.BITCOIN_MAINNET,
633
- transaction: {
634
- inputs: [
635
- {
636
- txid: "previous-transaction-id",
637
- vout: 0,
638
- scriptSig: "...",
639
- },
640
- ],
641
- outputs: [
642
- {
643
- value: 50000, // satoshis
644
- scriptPubKey: "76a914...88ac", // P2PKH script
645
- },
646
- ],
647
- version: 2,
648
- locktime: 0,
649
- },
650
- });
878
+ import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
651
879
 
652
- // Bitcoin testnet
653
- const result = await sdk.signAndSendTransaction({
654
- networkId: NetworkId.BITCOIN_TESTNET,
655
- transaction: {
656
- // ... transaction details
657
- },
880
+ const sdk = new BrowserSDK({
881
+ providerType: "injected",
882
+ addressTypes: [AddressType.ethereum],
658
883
  });
659
- ```
660
884
 
661
- ### Sui Transactions
662
-
663
- ```typescript
664
- import { TransactionBlock } from "@mysten/sui.js/transactions";
665
-
666
- // Create Sui transaction block
667
- const txb = new TransactionBlock();
668
- txb.transferObjects([coin], recipientAddress);
885
+ await sdk.connect();
669
886
 
670
- const result = await sdk.signAndSendTransaction({
671
- networkId: NetworkId.SUI_MAINNET,
672
- transaction: {
673
- kind: "moveCall", // or 'transferObject', 'transferSui', 'pay'
674
- data: txb, // TransactionBlock from @mysten/sui.js
675
- },
887
+ // Simple ETH transfer
888
+ const result = await sdk.ethereum.sendTransaction({
889
+ to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
890
+ value: "1000000000000000000", // 1 ETH in wei
891
+ gas: "21000",
892
+ gasPrice: "20000000000", // 20 gwei
676
893
  });
677
894
 
678
- // Sui testnet
679
- const result = await sdk.signAndSendTransaction({
680
- networkId: NetworkId.SUI_TESTNET,
681
- transaction: {
682
- kind: "transferSui",
683
- data: suiTransactionData,
684
- },
895
+ // EIP-1559 transaction with maxFeePerGas
896
+ const result = await sdk.ethereum.sendTransaction({
897
+ to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
898
+ value: "1000000000000000000", // 1 ETH in wei
899
+ data: "0x...", // contract call data
900
+ gas: "50000",
901
+ maxFeePerGas: "30000000000", // 30 gwei
902
+ maxPriorityFeePerGas: "2000000000", // 2 gwei
685
903
  });
686
- ```
687
-
688
- ## Network IDs Reference
689
904
 
690
- Use the exported `NetworkId` enum for type safety:
691
-
692
- ```typescript
693
- import { NetworkId } from "@phantom/browser-sdk";
905
+ console.log("Transaction hash:", result.hash);
694
906
  ```
695
907
 
696
- ### Solana
697
-
698
- - `NetworkId.SOLANA_MAINNET` - Solana Mainnet Beta
699
- - `NetworkId.SOLANA_DEVNET` - Solana Devnet
700
- - `NetworkId.SOLANA_TESTNET` - Solana Testnet
701
-
702
- ### Ethereum/EVM
703
-
704
- - `NetworkId.ETHEREUM_MAINNET` - Ethereum Mainnet
705
- - `NetworkId.ETHEREUM_SEPOLIA` - Ethereum Sepolia Testnet
706
- - `NetworkId.POLYGON_MAINNET` - Polygon Mainnet
707
- - `NetworkId.ARBITRUM_ONE` - Arbitrum One
708
- - `NetworkId.OPTIMISM_MAINNET` - Optimism Mainnet
709
- - `NetworkId.BASE_MAINNET` - Base Mainnet
710
-
711
- ### Bitcoin
712
-
713
- - `NetworkId.BITCOIN_MAINNET` - Bitcoin Mainnet
714
- - `NetworkId.BITCOIN_TESTNET` - Bitcoin Testnet
715
-
716
- ### Sui
717
-
718
- - `NetworkId.SUI_MAINNET` - Sui Mainnet
719
- - `NetworkId.SUI_TESTNET` - Sui Testnet
720
- - `NetworkId.SUI_DEVNET` - Sui Devnet
721
-
722
- ## Advanced Usage
723
-
724
- ### Multi-Chain Application
908
+ #### Working with Viem
725
909
 
726
910
  ```typescript
911
+ import { parseEther, parseGwei, encodeFunctionData } from "viem";
727
912
  import { BrowserSDK, AddressType } from "@phantom/browser-sdk";
728
913
 
729
914
  const sdk = new BrowserSDK({
730
- addressTypes: [AddressType.solana, AddressType.ethereum, AddressType.sui],
731
- apiBaseUrl: "https://api.phantom.app/v1/wallets",
732
- organizationId: "your-org-id",
915
+ providerType: "embedded",
916
+ addressTypes: [AddressType.ethereum],
917
+ // ... config
733
918
  });
734
919
 
735
- class MultiChainWallet {
736
- async sendSolana(amount: number, recipient: string) {
737
- // Get recent blockhash
738
- const connection = new Connection("https://api.mainnet-beta.solana.com");
739
- const { blockhash } = await connection.getLatestBlockhash();
740
-
741
- // Create transfer instruction
742
- const transferInstruction = SystemProgram.transfer({
743
- fromPubkey: new PublicKey(this.solanaAddress),
744
- toPubkey: new PublicKey(recipient),
745
- lamports: amount * LAMPORTS_PER_SOL,
746
- });
747
-
748
- // Create VersionedTransaction
749
- const messageV0 = new TransactionMessage({
750
- payerKey: new PublicKey(this.solanaAddress),
751
- recentBlockhash: blockhash,
752
- instructions: [transferInstruction],
753
- }).compileToV0Message();
754
-
755
- const transaction = new VersionedTransaction(messageV0);
756
-
757
- return await sdk.signAndSendTransaction({
758
- networkId: NetworkId.SOLANA_MAINNET,
759
- transaction,
760
- });
761
- }
762
-
763
- async sendEthereum(amount: string, recipient: string) {
764
- return await sdk.signAndSendTransaction({
765
- networkId: NetworkId.ETHEREUM_MAINNET,
766
- transaction: {
767
- to: recipient,
768
- value: parseEther(amount),
769
- gas: 21000n,
770
- },
771
- });
772
- }
773
-
774
- async sendSui(coinId: string, recipient: string) {
775
- const txb = new TransactionBlock();
776
- txb.transferObjects([coinId], recipient);
777
-
778
- return await sdk.signAndSendTransaction({
779
- networkId: NetworkId.SUI_MAINNET,
780
- transaction: {
781
- kind: "transferObject",
782
- data: txb,
783
- },
784
- });
785
- }
786
- }
787
- ```
788
-
789
- ### Error Handling
920
+ // Simple transfer with viem utilities
921
+ const result = await sdk.ethereum.sendTransaction({
922
+ to: "0x742d35Cc6634C0532925a3b8D4C8db86fB5C4A7E",
923
+ value: parseEther("1").toString(), // 1 ETH
924
+ gas: "21000",
925
+ gasPrice: parseGwei("20").toString(), // 20 gwei
926
+ });
790
927
 
791
- ```typescript
792
- try {
793
- const result = await sdk.signAndSendTransaction({
794
- networkId: NetworkId.SOLANA_MAINNET,
795
- transaction: myTransaction,
796
- });
797
- console.log("Success:", result);
798
- } catch (error) {
799
- if (error.message.includes("User rejected")) {
800
- console.log("User cancelled the transaction");
801
- } else if (error.message.includes("insufficient funds")) {
802
- console.log("Not enough balance");
803
- } else {
804
- console.error("Transaction failed:", error);
805
- }
806
- }
928
+ // Contract interaction
929
+ const result = await sdk.ethereum.sendTransaction({
930
+ to: tokenContractAddress,
931
+ data: encodeFunctionData({
932
+ abi: tokenAbi,
933
+ functionName: "transfer",
934
+ args: [recipientAddress, parseEther("100")],
935
+ }),
936
+ gas: "50000",
937
+ maxFeePerGas: parseGwei("30").toString(),
938
+ maxPriorityFeePerGas: parseGwei("2").toString(),
939
+ });
807
940
  ```
808
-
809
- ### Bundle Optimization Tips
810
-
811
- 1. **Only include networks you need**:
812
-
813
- ```typescript
814
- // Good: Only Solana (~250KB)
815
- addressTypes: [AddressType.solana];
816
-
817
- // Avoid: All networks if not needed (~800KB+)
818
- addressTypes: [AddressType.solana, AddressType.ethereum, AddressType.sui, AddressType.bitcoinSegwit];
819
- ```
820
-
821
- 2. **Install dependencies based on enabled networks**:
822
-
823
- | AddressType | Required Dependencies |
824
- | --------------------------- | ---------------------------------- |
825
- | `AddressType.solana` | `@solana/web3.js` OR `@solana/kit` |
826
- | `AddressType.ethereum` | `viem` |
827
- | `AddressType.bitcoinSegwit` | `bitcoinjs-lib` |
828
- | `AddressType.sui` | `@mysten/sui.js` |
829
-
830
- **Example package.json for Solana + Ethereum (using @solana/web3.js)**:
831
-
832
- ```json
833
- {
834
- "dependencies": {
835
- "@phantom/browser-sdk": "^1.0.0",
836
- "@solana/web3.js": "^1.87.0",
837
- "viem": "^2.0.0"
838
- }
839
- }
840
- ```
841
-
842
- **Example package.json for Solana + Ethereum (using @solana/kit)**:
843
-
844
- ```json
845
- {
846
- "dependencies": {
847
- "@phantom/browser-sdk": "^1.0.0",
848
- "@solana/kit": "^2.0.0",
849
- "viem": "^2.0.0"
850
- }
851
- }
852
- ```
853
-
854
- **Example package.json for Solana only (using @solana/web3.js)**:
855
-
856
- ```json
857
- {
858
- "dependencies": {
859
- "@phantom/browser-sdk": "^1.0.0",
860
- "@solana/web3.js": "^1.87.0"
861
- }
862
- }
863
- ```
864
-
865
- **Example package.json for Solana only (using @solana/kit)**:
866
-
867
- ```json
868
- {
869
- "dependencies": {
870
- "@phantom/browser-sdk": "^1.0.0",
871
- "@solana/kit": "^2.0.0"
872
- }
873
- }
874
- ```
875
-
876
- **Example package.json for all networks (using @solana/web3.js)**:
877
-
878
- ```json
879
- {
880
- "dependencies": {
881
- "@phantom/browser-sdk": "^1.0.0",
882
- "@solana/web3.js": "^1.87.0",
883
- "viem": "^2.0.0",
884
- "bitcoinjs-lib": "^6.1.0",
885
- "@mysten/sui.js": "^0.50.0"
886
- }
887
- }
888
- ```
889
-
890
- **Example package.json for all networks (using @solana/kit)**:
891
-
892
- ```json
893
- {
894
- "dependencies": {
895
- "@phantom/browser-sdk": "^1.0.0",
896
- "@solana/kit": "^2.0.0",
897
- "viem": "^2.0.0",
898
- "bitcoinjs-lib": "^6.1.0",
899
- "@mysten/sui.js": "^0.50.0"
900
- }
901
- }
902
- ```