@phantom/browser-sdk 0.3.9 → 1.0.0-beta.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/dist/index.mjs CHANGED
@@ -1,8 +1,12 @@
1
1
  // src/providers/injected/index.ts
2
2
  import { AddressType } from "@phantom/client";
3
- import { createPhantom, createExtensionPlugin } from "@phantom/browser-injected-sdk";
3
+ import {
4
+ createPhantom,
5
+ createExtensionPlugin
6
+ } from "@phantom/browser-injected-sdk";
4
7
  import { createSolanaPlugin } from "@phantom/browser-injected-sdk/solana";
5
8
  import { createEthereumPlugin } from "@phantom/browser-injected-sdk/ethereum";
9
+ import { createAutoConfirmPlugin } from "@phantom/browser-injected-sdk/auto-confirm";
6
10
 
7
11
  // src/debug.ts
8
12
  var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
@@ -78,10 +82,116 @@ var DebugCategory = {
78
82
  SESSION: "Session"
79
83
  };
80
84
 
85
+ // src/providers/injected/chains/SolanaChain.ts
86
+ import { getExplorerUrl, NetworkId } from "@phantom/constants";
87
+ import { Buffer } from "buffer";
88
+ var InjectedSolanaChain = class {
89
+ constructor(phantom) {
90
+ this.phantom = phantom;
91
+ }
92
+ async signMessage(message) {
93
+ const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
94
+ const result = await this.phantom.solana.signMessage(messageBytes);
95
+ const signature = result.signature instanceof Uint8Array ? Buffer.from(result.signature).toString("base64") : result.signature;
96
+ return {
97
+ signature,
98
+ rawSignature: signature
99
+ };
100
+ }
101
+ signTransaction(_transaction) {
102
+ throw new Error("signTransaction not available in browser-injected-sdk, use signAndSendTransaction instead");
103
+ }
104
+ async signAndSendTransaction(transaction) {
105
+ const result = await this.phantom.solana.signAndSendTransaction(transaction);
106
+ return {
107
+ hash: result.signature,
108
+ rawTransaction: result.signature,
109
+ blockExplorer: getExplorerUrl(NetworkId.SOLANA_MAINNET, "transaction", result.signature)
110
+ };
111
+ }
112
+ async connect(_options) {
113
+ const address = await this.phantom.solana.connect();
114
+ if (!address) {
115
+ throw new Error("Failed to connect to Solana wallet");
116
+ }
117
+ return { publicKey: address };
118
+ }
119
+ async disconnect() {
120
+ return await this.phantom.solana.disconnect();
121
+ }
122
+ async switchNetwork(_network) {
123
+ }
124
+ async getPublicKey() {
125
+ try {
126
+ const address = await this.phantom.solana.getAccount();
127
+ return address || null;
128
+ } catch {
129
+ return null;
130
+ }
131
+ }
132
+ isConnected() {
133
+ try {
134
+ return !!this.phantom.extension?.isInstalled();
135
+ } catch {
136
+ return false;
137
+ }
138
+ }
139
+ };
140
+
141
+ // src/providers/injected/chains/EthereumChain.ts
142
+ import { getExplorerUrl as getExplorerUrl2, NetworkId as NetworkId2, chainIdToNetworkId } from "@phantom/constants";
143
+ var InjectedEthereumChain = class {
144
+ constructor(phantom) {
145
+ this.phantom = phantom;
146
+ }
147
+ async request(args) {
148
+ const provider = await this.phantom.ethereum.getProvider();
149
+ return await provider.request(args);
150
+ }
151
+ async signPersonalMessage(message, address) {
152
+ const signature = await this.phantom.ethereum.signPersonalMessage(message, address);
153
+ return {
154
+ signature,
155
+ rawSignature: signature
156
+ };
157
+ }
158
+ async signTypedData(typedData, address) {
159
+ const signature = await this.phantom.ethereum.signTypedData(typedData, address);
160
+ return {
161
+ signature,
162
+ rawSignature: signature
163
+ };
164
+ }
165
+ async sendTransaction(transaction) {
166
+ const hash = await this.phantom.ethereum.sendTransaction(transaction);
167
+ const chainId = await this.getChainId();
168
+ const networkId = chainIdToNetworkId(chainId) || NetworkId2.ETHEREUM_MAINNET;
169
+ return {
170
+ hash,
171
+ rawTransaction: hash,
172
+ blockExplorer: getExplorerUrl2(networkId, "transaction", hash)
173
+ };
174
+ }
175
+ async switchChain(chainId) {
176
+ return await this.phantom.ethereum.switchChain(`0x${chainId.toString(16)}`);
177
+ }
178
+ async getChainId() {
179
+ const chainId = await this.phantom.ethereum.getChainId();
180
+ return parseInt(chainId, 16);
181
+ }
182
+ async getAccounts() {
183
+ return await this.phantom.ethereum.getAccounts();
184
+ }
185
+ isConnected() {
186
+ try {
187
+ return !!this.phantom.extension?.isInstalled();
188
+ } catch {
189
+ return false;
190
+ }
191
+ }
192
+ };
193
+
81
194
  // src/providers/injected/index.ts
82
- import { base64urlEncode } from "@phantom/base64url";
83
- import { getExplorerUrl } from "@phantom/constants";
84
- import bs58 from "bs58";
85
195
  var InjectedProvider = class {
86
196
  constructor(config) {
87
197
  this.connected = false;
@@ -102,12 +212,38 @@ var InjectedProvider = class {
102
212
  plugins.push(createEthereumPlugin());
103
213
  debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
104
214
  }
215
+ plugins.push(createAutoConfirmPlugin());
216
+ debug.log(DebugCategory.INJECTED_PROVIDER, "AutoConfirm plugin added");
105
217
  debug.log(DebugCategory.INJECTED_PROVIDER, "Creating Phantom instance with plugins", {
106
218
  pluginCount: plugins.length
107
219
  });
108
220
  this.phantom = createPhantom({ plugins });
109
221
  debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
110
222
  }
223
+ /**
224
+ * Access to Solana chain operations
225
+ */
226
+ get solana() {
227
+ if (!this.addressTypes.includes(AddressType.solana)) {
228
+ throw new Error("Solana not enabled for this provider");
229
+ }
230
+ if (!this._solanaChain) {
231
+ this._solanaChain = new InjectedSolanaChain(this.phantom);
232
+ }
233
+ return this._solanaChain;
234
+ }
235
+ /**
236
+ * Access to Ethereum chain operations
237
+ */
238
+ get ethereum() {
239
+ if (!this.addressTypes.includes(AddressType.ethereum)) {
240
+ throw new Error("Ethereum not enabled for this provider");
241
+ }
242
+ if (!this._ethereumChain) {
243
+ this._ethereumChain = new InjectedEthereumChain(this.phantom);
244
+ }
245
+ return this._ethereumChain;
246
+ }
111
247
  async connect(authOptions) {
112
248
  debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider connect", {
113
249
  addressTypes: this.addressTypes,
@@ -119,7 +255,7 @@ var InjectedProvider = class {
119
255
  providerType: "injected"
120
256
  });
121
257
  try {
122
- if (!this.phantom.extension.isInstalled()) {
258
+ if (!this.phantom.extension?.isInstalled?.()) {
123
259
  debug.error(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found");
124
260
  const error = new Error("Phantom wallet not found");
125
261
  this.emit("connect_error", {
@@ -133,13 +269,13 @@ var InjectedProvider = class {
133
269
  if (this.addressTypes.includes(AddressType.solana)) {
134
270
  debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
135
271
  try {
136
- const publicKey = await this.phantom.solana.connect();
137
- if (publicKey) {
272
+ const result2 = await this.solana.connect();
273
+ if (result2.publicKey) {
138
274
  connectedAddresses.push({
139
275
  addressType: AddressType.solana,
140
- address: publicKey
276
+ address: result2.publicKey
141
277
  });
142
- debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
278
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: result2.publicKey });
143
279
  }
144
280
  } catch (err) {
145
281
  debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
@@ -147,7 +283,7 @@ var InjectedProvider = class {
147
283
  }
148
284
  if (this.addressTypes.includes(AddressType.ethereum)) {
149
285
  try {
150
- const accounts = await this.phantom.ethereum.connect();
286
+ const accounts = await this.ethereum.getAccounts();
151
287
  if (accounts && accounts.length > 0) {
152
288
  connectedAddresses.push(
153
289
  ...accounts.map((address) => ({
@@ -155,6 +291,7 @@ var InjectedProvider = class {
155
291
  address
156
292
  }))
157
293
  );
294
+ debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum connected successfully", { addresses: accounts });
158
295
  }
159
296
  } catch (err) {
160
297
  debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum", { error: err });
@@ -194,20 +331,17 @@ var InjectedProvider = class {
194
331
  debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
195
332
  if (this.addressTypes.includes(AddressType.solana)) {
196
333
  try {
197
- await this.phantom.solana.disconnect();
334
+ await this.solana.disconnect();
198
335
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
199
336
  } catch (err) {
200
337
  debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
201
338
  }
202
339
  }
203
340
  if (this.addressTypes.includes(AddressType.ethereum)) {
204
- try {
205
- await this.phantom.ethereum.disconnect();
206
- debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected successfully");
207
- } catch (err) {
208
- debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Ethereum", { error: err });
209
- }
341
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected (no-op)");
210
342
  }
343
+ this._solanaChain = void 0;
344
+ this._ethereumChain = void 0;
211
345
  this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
212
346
  this.browserInjectedCleanupFunctions = [];
213
347
  this.connected = false;
@@ -217,77 +351,29 @@ var InjectedProvider = class {
217
351
  });
218
352
  debug.info(DebugCategory.INJECTED_PROVIDER, "Injected provider disconnected successfully");
219
353
  }
220
- async signMessage(params) {
221
- if (!this.connected) {
222
- throw new Error("Wallet not connected");
223
- }
224
- const networkPrefix = params.networkId.split(":")[0].toLowerCase();
225
- let signatureResult;
226
- if (networkPrefix === "solana") {
227
- const { signature } = await this.phantom.solana.signMessage(new TextEncoder().encode(params.message));
228
- signatureResult = bs58.encode(signature);
229
- } else if (networkPrefix === "ethereum" || networkPrefix === "polygon" || networkPrefix === "eip155") {
230
- const address = this.addresses.find((addr) => addr.addressType === AddressType.ethereum)?.address;
231
- if (!address) {
232
- throw new Error("No address available");
233
- }
234
- const signature = await this.phantom.ethereum.signPersonalMessage(params.message, address);
235
- signatureResult = signature;
236
- } else {
237
- throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
238
- }
239
- return {
240
- signature: signatureResult,
241
- rawSignature: base64urlEncode(signatureResult)
242
- };
243
- }
244
- async signAndSendTransaction(params) {
245
- if (!this.connected) {
246
- throw new Error("Wallet not connected");
247
- }
248
- const networkPrefix = params.networkId.split(":")[0].toLowerCase();
249
- if (networkPrefix === "solana") {
250
- const transaction = params.transaction;
251
- const result = await this.phantom.solana.signAndSendTransaction(transaction);
252
- return {
253
- hash: result.signature,
254
- rawTransaction: base64urlEncode(result.signature),
255
- blockExplorer: getExplorerUrl(params.networkId, "transaction", result.signature)
256
- };
257
- } else if (networkPrefix === "ethereum" || networkPrefix === "polygon" || networkPrefix === "eip155") {
258
- const toHex = (value) => {
259
- if (!value)
260
- return void 0;
261
- if (typeof value === "string" && value.startsWith("0x"))
262
- return value;
263
- if (typeof value === "string")
264
- return value;
265
- return "0x" + value.toString(16);
266
- };
267
- const txRequest = {
268
- to: params.transaction.to,
269
- value: params.transaction.value ? toHex(params.transaction.value) : "0x0",
270
- gas: toHex(params.transaction.gas),
271
- gasPrice: toHex(params.transaction.gasPrice),
272
- maxFeePerGas: toHex(params.transaction.maxFeePerGas),
273
- maxPriorityFeePerGas: toHex(params.transaction.maxPriorityFeePerGas),
274
- data: params.transaction.data || "0x"
275
- };
276
- const txHash = await this.phantom.ethereum.sendTransaction(txRequest);
277
- return {
278
- hash: txHash,
279
- rawTransaction: base64urlEncode(txHash),
280
- blockExplorer: getExplorerUrl(params.networkId, "transaction", txHash)
281
- };
282
- }
283
- throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
284
- }
285
354
  getAddresses() {
286
355
  return this.addresses;
287
356
  }
288
357
  isConnected() {
289
358
  return this.connected;
290
359
  }
360
+ // AutoConfirm methods - only available for injected providers
361
+ async enableAutoConfirm(params) {
362
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Enabling autoConfirm", { params });
363
+ return await this.phantom.autoConfirm.autoConfirmEnable(params);
364
+ }
365
+ async disableAutoConfirm() {
366
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Disabling autoConfirm");
367
+ await this.phantom.autoConfirm.autoConfirmDisable();
368
+ }
369
+ async getAutoConfirmStatus() {
370
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Getting autoConfirm status");
371
+ return await this.phantom.autoConfirm.autoConfirmStatus();
372
+ }
373
+ async getSupportedAutoConfirmChains() {
374
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Getting supported autoConfirm chains");
375
+ return await this.phantom.autoConfirm.autoConfirmSupportedChains();
376
+ }
291
377
  // Event management methods - implementing unified event interface
292
378
  on(event, callback) {
293
379
  debug.log(DebugCategory.INJECTED_PROVIDER, "Adding event listener", { event });
@@ -328,16 +414,16 @@ var InjectedProvider = class {
328
414
  }
329
415
  setupBrowserInjectedEvents() {
330
416
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
331
- if (this.addressTypes.includes(AddressType.solana) && this.phantom.solana) {
417
+ if (this.addressTypes.includes(AddressType.solana)) {
332
418
  this.setupSolanaEvents();
333
419
  }
334
- if (this.addressTypes.includes(AddressType.ethereum) && this.phantom.ethereum) {
420
+ if (this.addressTypes.includes(AddressType.ethereum)) {
335
421
  this.setupEthereumEvents();
336
422
  }
337
423
  }
338
424
  setupSolanaEvents() {
339
425
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
340
- const solanaConnectCleanup = this.phantom.solana.addEventListener("connect", (publicKey) => {
426
+ const handleSolanaConnect = (publicKey) => {
341
427
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
342
428
  const solanaAddress = { addressType: AddressType.solana, address: publicKey };
343
429
  if (!this.addresses.find((addr) => addr.addressType === AddressType.solana)) {
@@ -348,16 +434,16 @@ var InjectedProvider = class {
348
434
  addresses: this.addresses,
349
435
  source: "injected-extension"
350
436
  });
351
- });
352
- const solanaDisconnectCleanup = this.phantom.solana.addEventListener("disconnect", () => {
437
+ };
438
+ const handleSolanaDisconnect = () => {
353
439
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received");
354
440
  this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType.solana);
355
441
  this.connected = this.addresses.length > 0;
356
442
  this.emit("disconnect", {
357
443
  source: "injected-extension"
358
444
  });
359
- });
360
- const solanaAccountChangedCleanup = this.phantom.solana.addEventListener("accountChanged", (publicKey) => {
445
+ };
446
+ const handleSolanaAccountChanged = (publicKey) => {
361
447
  debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
362
448
  const solanaIndex = this.addresses.findIndex((addr) => addr.addressType === AddressType.solana);
363
449
  if (solanaIndex >= 0) {
@@ -369,16 +455,19 @@ var InjectedProvider = class {
369
455
  addresses: this.addresses,
370
456
  source: "injected-extension-account-change"
371
457
  });
372
- });
458
+ };
459
+ const cleanupConnect = this.phantom.solana.addEventListener("connect", handleSolanaConnect);
460
+ const cleanupDisconnect = this.phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
461
+ const cleanupAccountChanged = this.phantom.solana.addEventListener("accountChanged", handleSolanaAccountChanged);
373
462
  this.browserInjectedCleanupFunctions.push(
374
- solanaConnectCleanup,
375
- solanaDisconnectCleanup,
376
- solanaAccountChangedCleanup
463
+ cleanupConnect,
464
+ cleanupDisconnect,
465
+ cleanupAccountChanged
377
466
  );
378
467
  }
379
468
  setupEthereumEvents() {
380
469
  debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
381
- const ethConnectCleanup = this.phantom.ethereum.addEventListener("connect", (accounts) => {
470
+ const handleEthereumConnect = (accounts) => {
382
471
  debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
383
472
  this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType.ethereum);
384
473
  if (accounts && accounts.length > 0) {
@@ -392,17 +481,17 @@ var InjectedProvider = class {
392
481
  addresses: this.addresses,
393
482
  source: "injected-extension"
394
483
  });
395
- });
396
- const ethDisconnectCleanup = this.phantom.ethereum.addEventListener("disconnect", () => {
484
+ };
485
+ const handleEthereumDisconnect = () => {
397
486
  debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
398
487
  this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType.ethereum);
399
488
  this.connected = this.addresses.length > 0;
400
489
  this.emit("disconnect", {
401
490
  source: "injected-extension"
402
491
  });
403
- });
404
- const ethAccountChangedCleanup = this.phantom.ethereum.addEventListener("accountChanged", (accounts) => {
405
- debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum account changed event received", { accounts });
492
+ };
493
+ const handleEthereumAccountsChanged = (accounts) => {
494
+ debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
406
495
  this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType.ethereum);
407
496
  if (accounts && accounts.length > 0) {
408
497
  this.addresses.push(...accounts.map((address) => ({
@@ -414,11 +503,14 @@ var InjectedProvider = class {
414
503
  addresses: this.addresses,
415
504
  source: "injected-extension-account-change"
416
505
  });
417
- });
506
+ };
507
+ const cleanupConnect = this.phantom.ethereum.addEventListener("connect", handleEthereumConnect);
508
+ const cleanupDisconnect = this.phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
509
+ const cleanupAccountsChanged = this.phantom.ethereum.addEventListener("accountsChanged", handleEthereumAccountsChanged);
418
510
  this.browserInjectedCleanupFunctions.push(
419
- ethConnectCleanup,
420
- ethDisconnectCleanup,
421
- ethAccountChangedCleanup
511
+ cleanupConnect,
512
+ cleanupDisconnect,
513
+ cleanupAccountsChanged
422
514
  );
423
515
  }
424
516
  };
@@ -882,24 +974,6 @@ var ProviderManager = class {
882
974
  await this.currentProvider.disconnect();
883
975
  this.walletId = null;
884
976
  }
885
- /**
886
- * Sign a message using current provider
887
- */
888
- async signMessage(params) {
889
- if (!this.currentProvider) {
890
- throw new Error("No provider connected");
891
- }
892
- return this.currentProvider.signMessage(params);
893
- }
894
- /**
895
- * Sign and send transaction using current provider
896
- */
897
- async signAndSendTransaction(params) {
898
- if (!this.currentProvider) {
899
- throw new Error("No provider connected");
900
- }
901
- return this.currentProvider.signAndSendTransaction(params);
902
- }
903
977
  /**
904
978
  * Get addresses from current provider
905
979
  */
@@ -1098,145 +1172,109 @@ var BrowserSDK = class {
1098
1172
  `Invalid embeddedWalletType: ${config.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
1099
1173
  );
1100
1174
  }
1101
- config.embeddedWalletType = embeddedWalletType;
1102
- debug.log(DebugCategory.BROWSER_SDK, "Creating ProviderManager", { config });
1103
1175
  this.providerManager = new ProviderManager(config);
1104
- debug.info(DebugCategory.BROWSER_SDK, "BrowserSDK initialized successfully");
1105
1176
  }
1177
+ // ===== CHAIN API =====
1106
1178
  /**
1107
- * Connect to the wallet with optional provider switching
1179
+ * Access Solana chain operations
1108
1180
  */
1109
- async connect(options) {
1110
- debug.info(DebugCategory.BROWSER_SDK, "Starting connect process", { options });
1111
- if (options?.providerType) {
1112
- debug.log(DebugCategory.BROWSER_SDK, "Provider switch requested", {
1113
- providerType: options.providerType,
1114
- embeddedWalletType: options.embeddedWalletType
1115
- });
1116
- if (!["injected", "embedded"].includes(options.providerType)) {
1117
- debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType in connect options", {
1118
- providerType: options.providerType
1119
- });
1120
- throw new Error(`Invalid providerType: ${options.providerType}. Must be "injected" or "embedded".`);
1121
- }
1122
- if (options.embeddedWalletType && !["app-wallet", "user-wallet"].includes(options.embeddedWalletType)) {
1123
- debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType in connect options", {
1124
- embeddedWalletType: options.embeddedWalletType
1125
- });
1126
- throw new Error(
1127
- `Invalid embeddedWalletType: ${options.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
1128
- );
1129
- }
1130
- debug.log(DebugCategory.BROWSER_SDK, "Switching provider", {
1131
- providerType: options.providerType,
1132
- embeddedWalletType: options.embeddedWalletType
1133
- });
1134
- await this.providerManager.switchProvider(options.providerType, {
1135
- embeddedWalletType: options.embeddedWalletType
1136
- });
1181
+ get solana() {
1182
+ const currentProvider = this.providerManager.getCurrentProvider();
1183
+ if (!currentProvider) {
1184
+ throw new Error("No provider available. Call connect() first.");
1137
1185
  }
1138
- debug.log(DebugCategory.BROWSER_SDK, "Delegating to ProviderManager.connect", {
1139
- authOptions: options?.authOptions
1140
- });
1141
- const result = await this.providerManager.connect(options?.authOptions);
1142
- debug.info(DebugCategory.BROWSER_SDK, "Connect completed successfully", result);
1143
- return result;
1186
+ return currentProvider.solana;
1144
1187
  }
1145
1188
  /**
1146
- * Switch to a different provider type
1189
+ * Access Ethereum chain operations
1147
1190
  */
1148
- async switchProvider(type, options) {
1149
- if (!["injected", "embedded"].includes(type)) {
1150
- throw new Error(`Invalid providerType: ${type}. Must be "injected" or "embedded".`);
1191
+ get ethereum() {
1192
+ const currentProvider = this.providerManager.getCurrentProvider();
1193
+ if (!currentProvider) {
1194
+ throw new Error("No provider available. Call connect() first.");
1151
1195
  }
1152
- await this.providerManager.switchProvider(type, options);
1153
- }
1154
- /**
1155
- * Get current provider information
1156
- */
1157
- getCurrentProviderInfo() {
1158
- return this.providerManager.getCurrentProviderInfo();
1196
+ return currentProvider.ethereum;
1159
1197
  }
1198
+ // ===== CONNECTION MANAGEMENT =====
1160
1199
  /**
1161
- * Wait for Phantom extension to become available
1200
+ * Connect to the wallet
1162
1201
  */
1163
- async waitForPhantomExtension(timeoutMs) {
1164
- const isInstalled = async (retries = 3, timeAccumulated = 0) => {
1165
- const installed = isPhantomExtensionInstalled();
1166
- if (installed)
1167
- return true;
1168
- if (retries <= 0)
1169
- return false;
1170
- if (timeAccumulated >= (timeoutMs || 3e3))
1171
- return false;
1172
- return new Promise((resolve) => {
1173
- setTimeout(async () => {
1174
- const result = await isInstalled(retries - 1, timeAccumulated + 100);
1175
- resolve(result);
1176
- }, 100);
1202
+ async connect(options) {
1203
+ debug.info(DebugCategory.BROWSER_SDK, "Starting connection", options);
1204
+ try {
1205
+ const result = await this.providerManager.connect(options);
1206
+ debug.info(DebugCategory.BROWSER_SDK, "Connection successful", {
1207
+ addressCount: result.addresses.length,
1208
+ walletId: result.walletId,
1209
+ status: result.status
1177
1210
  });
1178
- };
1179
- return isInstalled();
1211
+ return result;
1212
+ } catch (error) {
1213
+ debug.error(DebugCategory.BROWSER_SDK, "Connection failed", { error: error.message });
1214
+ throw error;
1215
+ }
1180
1216
  }
1181
1217
  /**
1182
1218
  * Disconnect from the wallet
1183
1219
  */
1184
1220
  async disconnect() {
1185
- return this.providerManager.disconnect();
1221
+ debug.info(DebugCategory.BROWSER_SDK, "Disconnecting");
1222
+ try {
1223
+ await this.providerManager.disconnect();
1224
+ debug.info(DebugCategory.BROWSER_SDK, "Disconnection successful");
1225
+ } catch (error) {
1226
+ debug.error(DebugCategory.BROWSER_SDK, "Disconnection failed", { error: error.message });
1227
+ throw error;
1228
+ }
1186
1229
  }
1187
1230
  /**
1188
- * Sign a message
1189
- * @param message - Message string to sign
1190
- * @param networkId - Network identifier
1191
- * @returns Signature string
1231
+ * Switch between provider types (injected vs embedded)
1192
1232
  */
1193
- async signMessage(params) {
1194
- debug.info(DebugCategory.BROWSER_SDK, "Signing message", {
1195
- message: params.message,
1196
- networkId: params.networkId
1197
- });
1198
- const result = await this.providerManager.signMessage(params);
1199
- debug.info(DebugCategory.BROWSER_SDK, "Message signed successfully", {
1200
- message: params.message,
1201
- networkId: params.networkId,
1202
- result
1203
- });
1204
- return result;
1233
+ async switchProvider(type, options) {
1234
+ debug.info(DebugCategory.BROWSER_SDK, "Switching provider", { type, options });
1235
+ try {
1236
+ await this.providerManager.switchProvider(type, options);
1237
+ debug.info(DebugCategory.BROWSER_SDK, "Provider switch successful", { type });
1238
+ } catch (error) {
1239
+ debug.error(DebugCategory.BROWSER_SDK, "Provider switch failed", {
1240
+ type,
1241
+ error: error.message
1242
+ });
1243
+ throw error;
1244
+ }
1205
1245
  }
1246
+ // ===== STATE QUERIES =====
1206
1247
  /**
1207
- * Sign and send a transaction
1208
- * @param params - Transaction parameters with native transaction object
1209
- * @returns Transaction result
1248
+ * Check if the SDK is connected to a wallet
1210
1249
  */
1211
- async signAndSendTransaction(params) {
1212
- debug.info(DebugCategory.BROWSER_SDK, "Signing and sending transaction", {
1213
- networkId: params.networkId
1214
- });
1215
- const result = await this.providerManager.signAndSendTransaction(params);
1216
- debug.info(DebugCategory.BROWSER_SDK, "Transaction signed and sent successfully", {
1217
- networkId: params.networkId,
1218
- result
1219
- });
1220
- return result;
1250
+ isConnected() {
1251
+ return this.providerManager.isConnected();
1221
1252
  }
1222
1253
  /**
1223
- * Get wallet addresses
1254
+ * Get all connected wallet addresses
1224
1255
  */
1225
1256
  getAddresses() {
1226
1257
  return this.providerManager.getAddresses();
1227
1258
  }
1228
1259
  /**
1229
- * Check if wallet is connected
1260
+ * Get information about the current provider
1230
1261
  */
1231
- isConnected() {
1232
- return this.providerManager.isConnected();
1262
+ getCurrentProviderInfo() {
1263
+ return this.providerManager.getCurrentProviderInfo();
1233
1264
  }
1234
1265
  /**
1235
- * Get the current wallet ID (for embedded wallets)
1266
+ * Get the wallet ID (for embedded wallets)
1236
1267
  */
1237
1268
  getWalletId() {
1238
1269
  return this.providerManager.getWalletId();
1239
1270
  }
1271
+ // ===== UTILITY METHODS =====
1272
+ /**
1273
+ * Check if Phantom extension is installed
1274
+ */
1275
+ static isPhantomInstalled() {
1276
+ return isPhantomExtensionInstalled();
1277
+ }
1240
1278
  /**
1241
1279
  * Add event listener for provider events (connect, connect_start, connect_error, disconnect, error)
1242
1280
  * Works with both embedded and injected providers
@@ -1318,13 +1356,101 @@ var BrowserSDK = class {
1318
1356
  this.setDebugCallback(config.callback);
1319
1357
  }
1320
1358
  }
1359
+ // ===== AUTO-CONFIRM METHODS (Injected Provider Only) =====
1360
+ /**
1361
+ * Enable auto-confirm for transactions
1362
+ * Only available for injected providers
1363
+ */
1364
+ async enableAutoConfirm(params) {
1365
+ debug.info(DebugCategory.BROWSER_SDK, "Enabling auto-confirm", { params });
1366
+ const currentProvider = this.providerManager.getCurrentProvider();
1367
+ if (!currentProvider) {
1368
+ throw new Error("No provider available. Call connect() first.");
1369
+ }
1370
+ if (!("enableAutoConfirm" in currentProvider)) {
1371
+ throw new Error("Auto-confirm is only available for injected providers");
1372
+ }
1373
+ try {
1374
+ const result = await currentProvider.enableAutoConfirm(params);
1375
+ debug.info(DebugCategory.BROWSER_SDK, "Auto-confirm enabled successfully", { result });
1376
+ return result;
1377
+ } catch (error) {
1378
+ debug.error(DebugCategory.BROWSER_SDK, "Failed to enable auto-confirm", { error: error.message });
1379
+ throw error;
1380
+ }
1381
+ }
1382
+ /**
1383
+ * Disable auto-confirm for transactions
1384
+ * Only available for injected providers
1385
+ */
1386
+ async disableAutoConfirm() {
1387
+ debug.info(DebugCategory.BROWSER_SDK, "Disabling auto-confirm");
1388
+ const currentProvider = this.providerManager.getCurrentProvider();
1389
+ if (!currentProvider) {
1390
+ throw new Error("No provider available. Call connect() first.");
1391
+ }
1392
+ if (!("disableAutoConfirm" in currentProvider)) {
1393
+ throw new Error("Auto-confirm is only available for injected providers");
1394
+ }
1395
+ try {
1396
+ await currentProvider.disableAutoConfirm();
1397
+ debug.info(DebugCategory.BROWSER_SDK, "Auto-confirm disabled successfully");
1398
+ } catch (error) {
1399
+ debug.error(DebugCategory.BROWSER_SDK, "Failed to disable auto-confirm", { error: error.message });
1400
+ throw error;
1401
+ }
1402
+ }
1403
+ /**
1404
+ * Get current auto-confirm status
1405
+ * Only available for injected providers
1406
+ */
1407
+ async getAutoConfirmStatus() {
1408
+ debug.info(DebugCategory.BROWSER_SDK, "Getting auto-confirm status");
1409
+ const currentProvider = this.providerManager.getCurrentProvider();
1410
+ if (!currentProvider) {
1411
+ throw new Error("No provider available. Call connect() first.");
1412
+ }
1413
+ if (!("getAutoConfirmStatus" in currentProvider)) {
1414
+ throw new Error("Auto-confirm is only available for injected providers");
1415
+ }
1416
+ try {
1417
+ const result = await currentProvider.getAutoConfirmStatus();
1418
+ debug.info(DebugCategory.BROWSER_SDK, "Got auto-confirm status", { result });
1419
+ return result;
1420
+ } catch (error) {
1421
+ debug.error(DebugCategory.BROWSER_SDK, "Failed to get auto-confirm status", { error: error.message });
1422
+ throw error;
1423
+ }
1424
+ }
1425
+ /**
1426
+ * Get supported chains for auto-confirm
1427
+ * Only available for injected providers
1428
+ */
1429
+ async getSupportedAutoConfirmChains() {
1430
+ debug.info(DebugCategory.BROWSER_SDK, "Getting supported auto-confirm chains");
1431
+ const currentProvider = this.providerManager.getCurrentProvider();
1432
+ if (!currentProvider) {
1433
+ throw new Error("No provider available. Call connect() first.");
1434
+ }
1435
+ if (!("getSupportedAutoConfirmChains" in currentProvider)) {
1436
+ throw new Error("Auto-confirm is only available for injected providers");
1437
+ }
1438
+ try {
1439
+ const result = await currentProvider.getSupportedAutoConfirmChains();
1440
+ debug.info(DebugCategory.BROWSER_SDK, "Got supported auto-confirm chains", { result });
1441
+ return result;
1442
+ } catch (error) {
1443
+ debug.error(DebugCategory.BROWSER_SDK, "Failed to get supported auto-confirm chains", { error: error.message });
1444
+ throw error;
1445
+ }
1446
+ }
1321
1447
  };
1322
1448
 
1323
1449
  // src/types.ts
1324
1450
  import { AddressType as AddressType2 } from "@phantom/client";
1325
1451
 
1326
1452
  // src/index.ts
1327
- import { NetworkId } from "@phantom/constants";
1453
+ import { NetworkId as NetworkId3 } from "@phantom/constants";
1328
1454
  import { AddressType as AddressType3 } from "@phantom/client";
1329
1455
  export {
1330
1456
  AddressType3 as AddressType,
@@ -1333,7 +1459,7 @@ export {
1333
1459
  DEFAULT_WALLET_API_URL,
1334
1460
  DebugCategory,
1335
1461
  DebugLevel,
1336
- NetworkId,
1462
+ NetworkId3 as NetworkId,
1337
1463
  debug,
1338
1464
  detectBrowser,
1339
1465
  getBrowserDisplayName,