@phantom/browser-sdk 0.3.8 → 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/README.md +457 -430
- package/dist/index.d.ts +58 -30
- package/dist/index.js +351 -235
- package/dist/index.mjs +355 -226
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -36,7 +26,7 @@ __export(src_exports, {
|
|
|
36
26
|
DEFAULT_WALLET_API_URL: () => DEFAULT_WALLET_API_URL,
|
|
37
27
|
DebugCategory: () => DebugCategory,
|
|
38
28
|
DebugLevel: () => DebugLevel,
|
|
39
|
-
NetworkId: () =>
|
|
29
|
+
NetworkId: () => import_constants4.NetworkId,
|
|
40
30
|
debug: () => debug,
|
|
41
31
|
detectBrowser: () => detectBrowser,
|
|
42
32
|
getBrowserDisplayName: () => getBrowserDisplayName,
|
|
@@ -50,6 +40,7 @@ var import_client = require("@phantom/client");
|
|
|
50
40
|
var import_browser_injected_sdk = require("@phantom/browser-injected-sdk");
|
|
51
41
|
var import_solana = require("@phantom/browser-injected-sdk/solana");
|
|
52
42
|
var import_ethereum = require("@phantom/browser-injected-sdk/ethereum");
|
|
43
|
+
var import_auto_confirm = require("@phantom/browser-injected-sdk/auto-confirm");
|
|
53
44
|
|
|
54
45
|
// src/debug.ts
|
|
55
46
|
var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
|
|
@@ -125,10 +116,116 @@ var DebugCategory = {
|
|
|
125
116
|
SESSION: "Session"
|
|
126
117
|
};
|
|
127
118
|
|
|
128
|
-
// src/providers/injected/
|
|
129
|
-
var import_base64url = require("@phantom/base64url");
|
|
119
|
+
// src/providers/injected/chains/SolanaChain.ts
|
|
130
120
|
var import_constants = require("@phantom/constants");
|
|
131
|
-
var
|
|
121
|
+
var import_buffer = require("buffer");
|
|
122
|
+
var InjectedSolanaChain = class {
|
|
123
|
+
constructor(phantom) {
|
|
124
|
+
this.phantom = phantom;
|
|
125
|
+
}
|
|
126
|
+
async signMessage(message) {
|
|
127
|
+
const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
128
|
+
const result = await this.phantom.solana.signMessage(messageBytes);
|
|
129
|
+
const signature = result.signature instanceof Uint8Array ? import_buffer.Buffer.from(result.signature).toString("base64") : result.signature;
|
|
130
|
+
return {
|
|
131
|
+
signature,
|
|
132
|
+
rawSignature: signature
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
signTransaction(_transaction) {
|
|
136
|
+
throw new Error("signTransaction not available in browser-injected-sdk, use signAndSendTransaction instead");
|
|
137
|
+
}
|
|
138
|
+
async signAndSendTransaction(transaction) {
|
|
139
|
+
const result = await this.phantom.solana.signAndSendTransaction(transaction);
|
|
140
|
+
return {
|
|
141
|
+
hash: result.signature,
|
|
142
|
+
rawTransaction: result.signature,
|
|
143
|
+
blockExplorer: (0, import_constants.getExplorerUrl)(import_constants.NetworkId.SOLANA_MAINNET, "transaction", result.signature)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async connect(_options) {
|
|
147
|
+
const address = await this.phantom.solana.connect();
|
|
148
|
+
if (!address) {
|
|
149
|
+
throw new Error("Failed to connect to Solana wallet");
|
|
150
|
+
}
|
|
151
|
+
return { publicKey: address };
|
|
152
|
+
}
|
|
153
|
+
async disconnect() {
|
|
154
|
+
return await this.phantom.solana.disconnect();
|
|
155
|
+
}
|
|
156
|
+
async switchNetwork(_network) {
|
|
157
|
+
}
|
|
158
|
+
async getPublicKey() {
|
|
159
|
+
try {
|
|
160
|
+
const address = await this.phantom.solana.getAccount();
|
|
161
|
+
return address || null;
|
|
162
|
+
} catch {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
isConnected() {
|
|
167
|
+
try {
|
|
168
|
+
return !!this.phantom.extension?.isInstalled();
|
|
169
|
+
} catch {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// src/providers/injected/chains/EthereumChain.ts
|
|
176
|
+
var import_constants2 = require("@phantom/constants");
|
|
177
|
+
var InjectedEthereumChain = class {
|
|
178
|
+
constructor(phantom) {
|
|
179
|
+
this.phantom = phantom;
|
|
180
|
+
}
|
|
181
|
+
async request(args) {
|
|
182
|
+
const provider = await this.phantom.ethereum.getProvider();
|
|
183
|
+
return await provider.request(args);
|
|
184
|
+
}
|
|
185
|
+
async signPersonalMessage(message, address) {
|
|
186
|
+
const signature = await this.phantom.ethereum.signPersonalMessage(message, address);
|
|
187
|
+
return {
|
|
188
|
+
signature,
|
|
189
|
+
rawSignature: signature
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
async signTypedData(typedData, address) {
|
|
193
|
+
const signature = await this.phantom.ethereum.signTypedData(typedData, address);
|
|
194
|
+
return {
|
|
195
|
+
signature,
|
|
196
|
+
rawSignature: signature
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
async sendTransaction(transaction) {
|
|
200
|
+
const hash = await this.phantom.ethereum.sendTransaction(transaction);
|
|
201
|
+
const chainId = await this.getChainId();
|
|
202
|
+
const networkId = (0, import_constants2.chainIdToNetworkId)(chainId) || import_constants2.NetworkId.ETHEREUM_MAINNET;
|
|
203
|
+
return {
|
|
204
|
+
hash,
|
|
205
|
+
rawTransaction: hash,
|
|
206
|
+
blockExplorer: (0, import_constants2.getExplorerUrl)(networkId, "transaction", hash)
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
async switchChain(chainId) {
|
|
210
|
+
return await this.phantom.ethereum.switchChain(`0x${chainId.toString(16)}`);
|
|
211
|
+
}
|
|
212
|
+
async getChainId() {
|
|
213
|
+
const chainId = await this.phantom.ethereum.getChainId();
|
|
214
|
+
return parseInt(chainId, 16);
|
|
215
|
+
}
|
|
216
|
+
async getAccounts() {
|
|
217
|
+
return await this.phantom.ethereum.getAccounts();
|
|
218
|
+
}
|
|
219
|
+
isConnected() {
|
|
220
|
+
try {
|
|
221
|
+
return !!this.phantom.extension?.isInstalled();
|
|
222
|
+
} catch {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// src/providers/injected/index.ts
|
|
132
229
|
var InjectedProvider = class {
|
|
133
230
|
constructor(config) {
|
|
134
231
|
this.connected = false;
|
|
@@ -149,12 +246,38 @@ var InjectedProvider = class {
|
|
|
149
246
|
plugins.push((0, import_ethereum.createEthereumPlugin)());
|
|
150
247
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
|
|
151
248
|
}
|
|
249
|
+
plugins.push((0, import_auto_confirm.createAutoConfirmPlugin)());
|
|
250
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "AutoConfirm plugin added");
|
|
152
251
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Creating Phantom instance with plugins", {
|
|
153
252
|
pluginCount: plugins.length
|
|
154
253
|
});
|
|
155
254
|
this.phantom = (0, import_browser_injected_sdk.createPhantom)({ plugins });
|
|
156
255
|
debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
|
|
157
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Access to Solana chain operations
|
|
259
|
+
*/
|
|
260
|
+
get solana() {
|
|
261
|
+
if (!this.addressTypes.includes(import_client.AddressType.solana)) {
|
|
262
|
+
throw new Error("Solana not enabled for this provider");
|
|
263
|
+
}
|
|
264
|
+
if (!this._solanaChain) {
|
|
265
|
+
this._solanaChain = new InjectedSolanaChain(this.phantom);
|
|
266
|
+
}
|
|
267
|
+
return this._solanaChain;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Access to Ethereum chain operations
|
|
271
|
+
*/
|
|
272
|
+
get ethereum() {
|
|
273
|
+
if (!this.addressTypes.includes(import_client.AddressType.ethereum)) {
|
|
274
|
+
throw new Error("Ethereum not enabled for this provider");
|
|
275
|
+
}
|
|
276
|
+
if (!this._ethereumChain) {
|
|
277
|
+
this._ethereumChain = new InjectedEthereumChain(this.phantom);
|
|
278
|
+
}
|
|
279
|
+
return this._ethereumChain;
|
|
280
|
+
}
|
|
158
281
|
async connect(authOptions) {
|
|
159
282
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider connect", {
|
|
160
283
|
addressTypes: this.addressTypes,
|
|
@@ -166,7 +289,7 @@ var InjectedProvider = class {
|
|
|
166
289
|
providerType: "injected"
|
|
167
290
|
});
|
|
168
291
|
try {
|
|
169
|
-
if (!this.phantom.extension
|
|
292
|
+
if (!this.phantom.extension?.isInstalled?.()) {
|
|
170
293
|
debug.error(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found");
|
|
171
294
|
const error = new Error("Phantom wallet not found");
|
|
172
295
|
this.emit("connect_error", {
|
|
@@ -180,13 +303,13 @@ var InjectedProvider = class {
|
|
|
180
303
|
if (this.addressTypes.includes(import_client.AddressType.solana)) {
|
|
181
304
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
|
|
182
305
|
try {
|
|
183
|
-
const
|
|
184
|
-
if (publicKey) {
|
|
306
|
+
const result2 = await this.solana.connect();
|
|
307
|
+
if (result2.publicKey) {
|
|
185
308
|
connectedAddresses.push({
|
|
186
309
|
addressType: import_client.AddressType.solana,
|
|
187
|
-
address: publicKey
|
|
310
|
+
address: result2.publicKey
|
|
188
311
|
});
|
|
189
|
-
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
|
|
312
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: result2.publicKey });
|
|
190
313
|
}
|
|
191
314
|
} catch (err) {
|
|
192
315
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
|
|
@@ -194,7 +317,7 @@ var InjectedProvider = class {
|
|
|
194
317
|
}
|
|
195
318
|
if (this.addressTypes.includes(import_client.AddressType.ethereum)) {
|
|
196
319
|
try {
|
|
197
|
-
const accounts = await this.
|
|
320
|
+
const accounts = await this.ethereum.getAccounts();
|
|
198
321
|
if (accounts && accounts.length > 0) {
|
|
199
322
|
connectedAddresses.push(
|
|
200
323
|
...accounts.map((address) => ({
|
|
@@ -202,6 +325,7 @@ var InjectedProvider = class {
|
|
|
202
325
|
address
|
|
203
326
|
}))
|
|
204
327
|
);
|
|
328
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Ethereum connected successfully", { addresses: accounts });
|
|
205
329
|
}
|
|
206
330
|
} catch (err) {
|
|
207
331
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum", { error: err });
|
|
@@ -241,20 +365,17 @@ var InjectedProvider = class {
|
|
|
241
365
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
|
|
242
366
|
if (this.addressTypes.includes(import_client.AddressType.solana)) {
|
|
243
367
|
try {
|
|
244
|
-
await this.
|
|
368
|
+
await this.solana.disconnect();
|
|
245
369
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
|
|
246
370
|
} catch (err) {
|
|
247
371
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
|
|
248
372
|
}
|
|
249
373
|
}
|
|
250
374
|
if (this.addressTypes.includes(import_client.AddressType.ethereum)) {
|
|
251
|
-
|
|
252
|
-
await this.phantom.ethereum.disconnect();
|
|
253
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected successfully");
|
|
254
|
-
} catch (err) {
|
|
255
|
-
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Ethereum", { error: err });
|
|
256
|
-
}
|
|
375
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected (no-op)");
|
|
257
376
|
}
|
|
377
|
+
this._solanaChain = void 0;
|
|
378
|
+
this._ethereumChain = void 0;
|
|
258
379
|
this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
|
|
259
380
|
this.browserInjectedCleanupFunctions = [];
|
|
260
381
|
this.connected = false;
|
|
@@ -264,77 +385,29 @@ var InjectedProvider = class {
|
|
|
264
385
|
});
|
|
265
386
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Injected provider disconnected successfully");
|
|
266
387
|
}
|
|
267
|
-
async signMessage(params) {
|
|
268
|
-
if (!this.connected) {
|
|
269
|
-
throw new Error("Wallet not connected");
|
|
270
|
-
}
|
|
271
|
-
const networkPrefix = params.networkId.split(":")[0].toLowerCase();
|
|
272
|
-
let signatureResult;
|
|
273
|
-
if (networkPrefix === "solana") {
|
|
274
|
-
const { signature } = await this.phantom.solana.signMessage(new TextEncoder().encode(params.message));
|
|
275
|
-
signatureResult = import_bs58.default.encode(signature);
|
|
276
|
-
} else if (networkPrefix === "ethereum" || networkPrefix === "polygon" || networkPrefix === "eip155") {
|
|
277
|
-
const address = this.addresses.find((addr) => addr.addressType === import_client.AddressType.ethereum)?.address;
|
|
278
|
-
if (!address) {
|
|
279
|
-
throw new Error("No address available");
|
|
280
|
-
}
|
|
281
|
-
const signature = await this.phantom.ethereum.signPersonalMessage(params.message, address);
|
|
282
|
-
signatureResult = signature;
|
|
283
|
-
} else {
|
|
284
|
-
throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
|
|
285
|
-
}
|
|
286
|
-
return {
|
|
287
|
-
signature: signatureResult,
|
|
288
|
-
rawSignature: (0, import_base64url.base64urlEncode)(signatureResult)
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
async signAndSendTransaction(params) {
|
|
292
|
-
if (!this.connected) {
|
|
293
|
-
throw new Error("Wallet not connected");
|
|
294
|
-
}
|
|
295
|
-
const networkPrefix = params.networkId.split(":")[0].toLowerCase();
|
|
296
|
-
if (networkPrefix === "solana") {
|
|
297
|
-
const transaction = params.transaction;
|
|
298
|
-
const result = await this.phantom.solana.signAndSendTransaction(transaction);
|
|
299
|
-
return {
|
|
300
|
-
hash: result.signature,
|
|
301
|
-
rawTransaction: (0, import_base64url.base64urlEncode)(result.signature),
|
|
302
|
-
blockExplorer: (0, import_constants.getExplorerUrl)(params.networkId, "transaction", result.signature)
|
|
303
|
-
};
|
|
304
|
-
} else if (networkPrefix === "ethereum" || networkPrefix === "polygon" || networkPrefix === "eip155") {
|
|
305
|
-
const toHex = (value) => {
|
|
306
|
-
if (!value)
|
|
307
|
-
return void 0;
|
|
308
|
-
if (typeof value === "string" && value.startsWith("0x"))
|
|
309
|
-
return value;
|
|
310
|
-
if (typeof value === "string")
|
|
311
|
-
return value;
|
|
312
|
-
return "0x" + value.toString(16);
|
|
313
|
-
};
|
|
314
|
-
const txRequest = {
|
|
315
|
-
to: params.transaction.to,
|
|
316
|
-
value: params.transaction.value ? toHex(params.transaction.value) : "0x0",
|
|
317
|
-
gas: toHex(params.transaction.gas),
|
|
318
|
-
gasPrice: toHex(params.transaction.gasPrice),
|
|
319
|
-
maxFeePerGas: toHex(params.transaction.maxFeePerGas),
|
|
320
|
-
maxPriorityFeePerGas: toHex(params.transaction.maxPriorityFeePerGas),
|
|
321
|
-
data: params.transaction.data || "0x"
|
|
322
|
-
};
|
|
323
|
-
const txHash = await this.phantom.ethereum.sendTransaction(txRequest);
|
|
324
|
-
return {
|
|
325
|
-
hash: txHash,
|
|
326
|
-
rawTransaction: (0, import_base64url.base64urlEncode)(txHash),
|
|
327
|
-
blockExplorer: (0, import_constants.getExplorerUrl)(params.networkId, "transaction", txHash)
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
throw new Error(`Network ${params.networkId} is not supported for injected wallets`);
|
|
331
|
-
}
|
|
332
388
|
getAddresses() {
|
|
333
389
|
return this.addresses;
|
|
334
390
|
}
|
|
335
391
|
isConnected() {
|
|
336
392
|
return this.connected;
|
|
337
393
|
}
|
|
394
|
+
// AutoConfirm methods - only available for injected providers
|
|
395
|
+
async enableAutoConfirm(params) {
|
|
396
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Enabling autoConfirm", { params });
|
|
397
|
+
return await this.phantom.autoConfirm.autoConfirmEnable(params);
|
|
398
|
+
}
|
|
399
|
+
async disableAutoConfirm() {
|
|
400
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Disabling autoConfirm");
|
|
401
|
+
await this.phantom.autoConfirm.autoConfirmDisable();
|
|
402
|
+
}
|
|
403
|
+
async getAutoConfirmStatus() {
|
|
404
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Getting autoConfirm status");
|
|
405
|
+
return await this.phantom.autoConfirm.autoConfirmStatus();
|
|
406
|
+
}
|
|
407
|
+
async getSupportedAutoConfirmChains() {
|
|
408
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Getting supported autoConfirm chains");
|
|
409
|
+
return await this.phantom.autoConfirm.autoConfirmSupportedChains();
|
|
410
|
+
}
|
|
338
411
|
// Event management methods - implementing unified event interface
|
|
339
412
|
on(event, callback) {
|
|
340
413
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Adding event listener", { event });
|
|
@@ -375,16 +448,16 @@ var InjectedProvider = class {
|
|
|
375
448
|
}
|
|
376
449
|
setupBrowserInjectedEvents() {
|
|
377
450
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
|
|
378
|
-
if (this.addressTypes.includes(import_client.AddressType.solana)
|
|
451
|
+
if (this.addressTypes.includes(import_client.AddressType.solana)) {
|
|
379
452
|
this.setupSolanaEvents();
|
|
380
453
|
}
|
|
381
|
-
if (this.addressTypes.includes(import_client.AddressType.ethereum)
|
|
454
|
+
if (this.addressTypes.includes(import_client.AddressType.ethereum)) {
|
|
382
455
|
this.setupEthereumEvents();
|
|
383
456
|
}
|
|
384
457
|
}
|
|
385
458
|
setupSolanaEvents() {
|
|
386
459
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
|
|
387
|
-
const
|
|
460
|
+
const handleSolanaConnect = (publicKey) => {
|
|
388
461
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
|
|
389
462
|
const solanaAddress = { addressType: import_client.AddressType.solana, address: publicKey };
|
|
390
463
|
if (!this.addresses.find((addr) => addr.addressType === import_client.AddressType.solana)) {
|
|
@@ -395,16 +468,16 @@ var InjectedProvider = class {
|
|
|
395
468
|
addresses: this.addresses,
|
|
396
469
|
source: "injected-extension"
|
|
397
470
|
});
|
|
398
|
-
}
|
|
399
|
-
const
|
|
471
|
+
};
|
|
472
|
+
const handleSolanaDisconnect = () => {
|
|
400
473
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received");
|
|
401
474
|
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client.AddressType.solana);
|
|
402
475
|
this.connected = this.addresses.length > 0;
|
|
403
476
|
this.emit("disconnect", {
|
|
404
477
|
source: "injected-extension"
|
|
405
478
|
});
|
|
406
|
-
}
|
|
407
|
-
const
|
|
479
|
+
};
|
|
480
|
+
const handleSolanaAccountChanged = (publicKey) => {
|
|
408
481
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
|
|
409
482
|
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType === import_client.AddressType.solana);
|
|
410
483
|
if (solanaIndex >= 0) {
|
|
@@ -416,16 +489,19 @@ var InjectedProvider = class {
|
|
|
416
489
|
addresses: this.addresses,
|
|
417
490
|
source: "injected-extension-account-change"
|
|
418
491
|
});
|
|
419
|
-
}
|
|
492
|
+
};
|
|
493
|
+
const cleanupConnect = this.phantom.solana.addEventListener("connect", handleSolanaConnect);
|
|
494
|
+
const cleanupDisconnect = this.phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
|
|
495
|
+
const cleanupAccountChanged = this.phantom.solana.addEventListener("accountChanged", handleSolanaAccountChanged);
|
|
420
496
|
this.browserInjectedCleanupFunctions.push(
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
497
|
+
cleanupConnect,
|
|
498
|
+
cleanupDisconnect,
|
|
499
|
+
cleanupAccountChanged
|
|
424
500
|
);
|
|
425
501
|
}
|
|
426
502
|
setupEthereumEvents() {
|
|
427
503
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
|
|
428
|
-
const
|
|
504
|
+
const handleEthereumConnect = (accounts) => {
|
|
429
505
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
|
|
430
506
|
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client.AddressType.ethereum);
|
|
431
507
|
if (accounts && accounts.length > 0) {
|
|
@@ -439,17 +515,17 @@ var InjectedProvider = class {
|
|
|
439
515
|
addresses: this.addresses,
|
|
440
516
|
source: "injected-extension"
|
|
441
517
|
});
|
|
442
|
-
}
|
|
443
|
-
const
|
|
518
|
+
};
|
|
519
|
+
const handleEthereumDisconnect = () => {
|
|
444
520
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
|
|
445
521
|
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client.AddressType.ethereum);
|
|
446
522
|
this.connected = this.addresses.length > 0;
|
|
447
523
|
this.emit("disconnect", {
|
|
448
524
|
source: "injected-extension"
|
|
449
525
|
});
|
|
450
|
-
}
|
|
451
|
-
const
|
|
452
|
-
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum
|
|
526
|
+
};
|
|
527
|
+
const handleEthereumAccountsChanged = (accounts) => {
|
|
528
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
|
|
453
529
|
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client.AddressType.ethereum);
|
|
454
530
|
if (accounts && accounts.length > 0) {
|
|
455
531
|
this.addresses.push(...accounts.map((address) => ({
|
|
@@ -461,11 +537,14 @@ var InjectedProvider = class {
|
|
|
461
537
|
addresses: this.addresses,
|
|
462
538
|
source: "injected-extension-account-change"
|
|
463
539
|
});
|
|
464
|
-
}
|
|
540
|
+
};
|
|
541
|
+
const cleanupConnect = this.phantom.ethereum.addEventListener("connect", handleEthereumConnect);
|
|
542
|
+
const cleanupDisconnect = this.phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
|
|
543
|
+
const cleanupAccountsChanged = this.phantom.ethereum.addEventListener("accountsChanged", handleEthereumAccountsChanged);
|
|
465
544
|
this.browserInjectedCleanupFunctions.push(
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
545
|
+
cleanupConnect,
|
|
546
|
+
cleanupDisconnect,
|
|
547
|
+
cleanupAccountsChanged
|
|
469
548
|
);
|
|
470
549
|
}
|
|
471
550
|
};
|
|
@@ -630,6 +709,7 @@ var BrowserAuthProvider = class {
|
|
|
630
709
|
try {
|
|
631
710
|
const walletId = this.urlParamsAccessor.getParam("wallet_id");
|
|
632
711
|
const sessionId = this.urlParamsAccessor.getParam("session_id");
|
|
712
|
+
const accountDerivationIndex = this.urlParamsAccessor.getParam("selected_account_index");
|
|
633
713
|
const error = this.urlParamsAccessor.getParam("error");
|
|
634
714
|
const errorDescription = this.urlParamsAccessor.getParam("error_description");
|
|
635
715
|
if (error) {
|
|
@@ -673,11 +753,13 @@ var BrowserAuthProvider = class {
|
|
|
673
753
|
sessionStorage.removeItem("phantom-auth-context");
|
|
674
754
|
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Successfully resumed auth from redirect", {
|
|
675
755
|
walletId,
|
|
676
|
-
sessionId
|
|
756
|
+
sessionId,
|
|
757
|
+
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : void 0
|
|
677
758
|
});
|
|
678
759
|
return {
|
|
679
760
|
walletId,
|
|
680
|
-
userInfo: context
|
|
761
|
+
userInfo: context,
|
|
762
|
+
accountDerivationIndex: accountDerivationIndex ? parseInt(accountDerivationIndex) : void 0
|
|
681
763
|
};
|
|
682
764
|
} catch (error) {
|
|
683
765
|
sessionStorage.removeItem("phantom-auth-context");
|
|
@@ -926,24 +1008,6 @@ var ProviderManager = class {
|
|
|
926
1008
|
await this.currentProvider.disconnect();
|
|
927
1009
|
this.walletId = null;
|
|
928
1010
|
}
|
|
929
|
-
/**
|
|
930
|
-
* Sign a message using current provider
|
|
931
|
-
*/
|
|
932
|
-
async signMessage(params) {
|
|
933
|
-
if (!this.currentProvider) {
|
|
934
|
-
throw new Error("No provider connected");
|
|
935
|
-
}
|
|
936
|
-
return this.currentProvider.signMessage(params);
|
|
937
|
-
}
|
|
938
|
-
/**
|
|
939
|
-
* Sign and send transaction using current provider
|
|
940
|
-
*/
|
|
941
|
-
async signAndSendTransaction(params) {
|
|
942
|
-
if (!this.currentProvider) {
|
|
943
|
-
throw new Error("No provider connected");
|
|
944
|
-
}
|
|
945
|
-
return this.currentProvider.signAndSendTransaction(params);
|
|
946
|
-
}
|
|
947
1011
|
/**
|
|
948
1012
|
* Get addresses from current provider
|
|
949
1013
|
*/
|
|
@@ -1142,145 +1206,109 @@ var BrowserSDK = class {
|
|
|
1142
1206
|
`Invalid embeddedWalletType: ${config.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
|
|
1143
1207
|
);
|
|
1144
1208
|
}
|
|
1145
|
-
config.embeddedWalletType = embeddedWalletType;
|
|
1146
|
-
debug.log(DebugCategory.BROWSER_SDK, "Creating ProviderManager", { config });
|
|
1147
1209
|
this.providerManager = new ProviderManager(config);
|
|
1148
|
-
debug.info(DebugCategory.BROWSER_SDK, "BrowserSDK initialized successfully");
|
|
1149
1210
|
}
|
|
1211
|
+
// ===== CHAIN API =====
|
|
1150
1212
|
/**
|
|
1151
|
-
*
|
|
1213
|
+
* Access Solana chain operations
|
|
1152
1214
|
*/
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
if (
|
|
1156
|
-
|
|
1157
|
-
providerType: options.providerType,
|
|
1158
|
-
embeddedWalletType: options.embeddedWalletType
|
|
1159
|
-
});
|
|
1160
|
-
if (!["injected", "embedded"].includes(options.providerType)) {
|
|
1161
|
-
debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType in connect options", {
|
|
1162
|
-
providerType: options.providerType
|
|
1163
|
-
});
|
|
1164
|
-
throw new Error(`Invalid providerType: ${options.providerType}. Must be "injected" or "embedded".`);
|
|
1165
|
-
}
|
|
1166
|
-
if (options.embeddedWalletType && !["app-wallet", "user-wallet"].includes(options.embeddedWalletType)) {
|
|
1167
|
-
debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType in connect options", {
|
|
1168
|
-
embeddedWalletType: options.embeddedWalletType
|
|
1169
|
-
});
|
|
1170
|
-
throw new Error(
|
|
1171
|
-
`Invalid embeddedWalletType: ${options.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
|
|
1172
|
-
);
|
|
1173
|
-
}
|
|
1174
|
-
debug.log(DebugCategory.BROWSER_SDK, "Switching provider", {
|
|
1175
|
-
providerType: options.providerType,
|
|
1176
|
-
embeddedWalletType: options.embeddedWalletType
|
|
1177
|
-
});
|
|
1178
|
-
await this.providerManager.switchProvider(options.providerType, {
|
|
1179
|
-
embeddedWalletType: options.embeddedWalletType
|
|
1180
|
-
});
|
|
1215
|
+
get solana() {
|
|
1216
|
+
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1217
|
+
if (!currentProvider) {
|
|
1218
|
+
throw new Error("No provider available. Call connect() first.");
|
|
1181
1219
|
}
|
|
1182
|
-
|
|
1183
|
-
authOptions: options?.authOptions
|
|
1184
|
-
});
|
|
1185
|
-
const result = await this.providerManager.connect(options?.authOptions);
|
|
1186
|
-
debug.info(DebugCategory.BROWSER_SDK, "Connect completed successfully", result);
|
|
1187
|
-
return result;
|
|
1220
|
+
return currentProvider.solana;
|
|
1188
1221
|
}
|
|
1189
1222
|
/**
|
|
1190
|
-
*
|
|
1223
|
+
* Access Ethereum chain operations
|
|
1191
1224
|
*/
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1225
|
+
get ethereum() {
|
|
1226
|
+
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1227
|
+
if (!currentProvider) {
|
|
1228
|
+
throw new Error("No provider available. Call connect() first.");
|
|
1195
1229
|
}
|
|
1196
|
-
|
|
1197
|
-
}
|
|
1198
|
-
/**
|
|
1199
|
-
* Get current provider information
|
|
1200
|
-
*/
|
|
1201
|
-
getCurrentProviderInfo() {
|
|
1202
|
-
return this.providerManager.getCurrentProviderInfo();
|
|
1230
|
+
return currentProvider.ethereum;
|
|
1203
1231
|
}
|
|
1232
|
+
// ===== CONNECTION MANAGEMENT =====
|
|
1204
1233
|
/**
|
|
1205
|
-
*
|
|
1234
|
+
* Connect to the wallet
|
|
1206
1235
|
*/
|
|
1207
|
-
async
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
return false;
|
|
1216
|
-
return new Promise((resolve) => {
|
|
1217
|
-
setTimeout(async () => {
|
|
1218
|
-
const result = await isInstalled(retries - 1, timeAccumulated + 100);
|
|
1219
|
-
resolve(result);
|
|
1220
|
-
}, 100);
|
|
1236
|
+
async connect(options) {
|
|
1237
|
+
debug.info(DebugCategory.BROWSER_SDK, "Starting connection", options);
|
|
1238
|
+
try {
|
|
1239
|
+
const result = await this.providerManager.connect(options);
|
|
1240
|
+
debug.info(DebugCategory.BROWSER_SDK, "Connection successful", {
|
|
1241
|
+
addressCount: result.addresses.length,
|
|
1242
|
+
walletId: result.walletId,
|
|
1243
|
+
status: result.status
|
|
1221
1244
|
});
|
|
1222
|
-
|
|
1223
|
-
|
|
1245
|
+
return result;
|
|
1246
|
+
} catch (error) {
|
|
1247
|
+
debug.error(DebugCategory.BROWSER_SDK, "Connection failed", { error: error.message });
|
|
1248
|
+
throw error;
|
|
1249
|
+
}
|
|
1224
1250
|
}
|
|
1225
1251
|
/**
|
|
1226
1252
|
* Disconnect from the wallet
|
|
1227
1253
|
*/
|
|
1228
1254
|
async disconnect() {
|
|
1229
|
-
|
|
1255
|
+
debug.info(DebugCategory.BROWSER_SDK, "Disconnecting");
|
|
1256
|
+
try {
|
|
1257
|
+
await this.providerManager.disconnect();
|
|
1258
|
+
debug.info(DebugCategory.BROWSER_SDK, "Disconnection successful");
|
|
1259
|
+
} catch (error) {
|
|
1260
|
+
debug.error(DebugCategory.BROWSER_SDK, "Disconnection failed", { error: error.message });
|
|
1261
|
+
throw error;
|
|
1262
|
+
}
|
|
1230
1263
|
}
|
|
1231
1264
|
/**
|
|
1232
|
-
*
|
|
1233
|
-
* @param message - Message string to sign
|
|
1234
|
-
* @param networkId - Network identifier
|
|
1235
|
-
* @returns Signature string
|
|
1265
|
+
* Switch between provider types (injected vs embedded)
|
|
1236
1266
|
*/
|
|
1237
|
-
async
|
|
1238
|
-
debug.info(DebugCategory.BROWSER_SDK, "
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1267
|
+
async switchProvider(type, options) {
|
|
1268
|
+
debug.info(DebugCategory.BROWSER_SDK, "Switching provider", { type, options });
|
|
1269
|
+
try {
|
|
1270
|
+
await this.providerManager.switchProvider(type, options);
|
|
1271
|
+
debug.info(DebugCategory.BROWSER_SDK, "Provider switch successful", { type });
|
|
1272
|
+
} catch (error) {
|
|
1273
|
+
debug.error(DebugCategory.BROWSER_SDK, "Provider switch failed", {
|
|
1274
|
+
type,
|
|
1275
|
+
error: error.message
|
|
1276
|
+
});
|
|
1277
|
+
throw error;
|
|
1278
|
+
}
|
|
1249
1279
|
}
|
|
1280
|
+
// ===== STATE QUERIES =====
|
|
1250
1281
|
/**
|
|
1251
|
-
*
|
|
1252
|
-
* @param params - Transaction parameters with native transaction object
|
|
1253
|
-
* @returns Transaction result
|
|
1282
|
+
* Check if the SDK is connected to a wallet
|
|
1254
1283
|
*/
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
networkId: params.networkId
|
|
1258
|
-
});
|
|
1259
|
-
const result = await this.providerManager.signAndSendTransaction(params);
|
|
1260
|
-
debug.info(DebugCategory.BROWSER_SDK, "Transaction signed and sent successfully", {
|
|
1261
|
-
networkId: params.networkId,
|
|
1262
|
-
result
|
|
1263
|
-
});
|
|
1264
|
-
return result;
|
|
1284
|
+
isConnected() {
|
|
1285
|
+
return this.providerManager.isConnected();
|
|
1265
1286
|
}
|
|
1266
1287
|
/**
|
|
1267
|
-
* Get wallet addresses
|
|
1288
|
+
* Get all connected wallet addresses
|
|
1268
1289
|
*/
|
|
1269
1290
|
getAddresses() {
|
|
1270
1291
|
return this.providerManager.getAddresses();
|
|
1271
1292
|
}
|
|
1272
1293
|
/**
|
|
1273
|
-
*
|
|
1294
|
+
* Get information about the current provider
|
|
1274
1295
|
*/
|
|
1275
|
-
|
|
1276
|
-
return this.providerManager.
|
|
1296
|
+
getCurrentProviderInfo() {
|
|
1297
|
+
return this.providerManager.getCurrentProviderInfo();
|
|
1277
1298
|
}
|
|
1278
1299
|
/**
|
|
1279
|
-
* Get the
|
|
1300
|
+
* Get the wallet ID (for embedded wallets)
|
|
1280
1301
|
*/
|
|
1281
1302
|
getWalletId() {
|
|
1282
1303
|
return this.providerManager.getWalletId();
|
|
1283
1304
|
}
|
|
1305
|
+
// ===== UTILITY METHODS =====
|
|
1306
|
+
/**
|
|
1307
|
+
* Check if Phantom extension is installed
|
|
1308
|
+
*/
|
|
1309
|
+
static isPhantomInstalled() {
|
|
1310
|
+
return (0, import_browser_injected_sdk2.isPhantomExtensionInstalled)();
|
|
1311
|
+
}
|
|
1284
1312
|
/**
|
|
1285
1313
|
* Add event listener for provider events (connect, connect_start, connect_error, disconnect, error)
|
|
1286
1314
|
* Works with both embedded and injected providers
|
|
@@ -1362,11 +1390,99 @@ var BrowserSDK = class {
|
|
|
1362
1390
|
this.setDebugCallback(config.callback);
|
|
1363
1391
|
}
|
|
1364
1392
|
}
|
|
1393
|
+
// ===== AUTO-CONFIRM METHODS (Injected Provider Only) =====
|
|
1394
|
+
/**
|
|
1395
|
+
* Enable auto-confirm for transactions
|
|
1396
|
+
* Only available for injected providers
|
|
1397
|
+
*/
|
|
1398
|
+
async enableAutoConfirm(params) {
|
|
1399
|
+
debug.info(DebugCategory.BROWSER_SDK, "Enabling auto-confirm", { params });
|
|
1400
|
+
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1401
|
+
if (!currentProvider) {
|
|
1402
|
+
throw new Error("No provider available. Call connect() first.");
|
|
1403
|
+
}
|
|
1404
|
+
if (!("enableAutoConfirm" in currentProvider)) {
|
|
1405
|
+
throw new Error("Auto-confirm is only available for injected providers");
|
|
1406
|
+
}
|
|
1407
|
+
try {
|
|
1408
|
+
const result = await currentProvider.enableAutoConfirm(params);
|
|
1409
|
+
debug.info(DebugCategory.BROWSER_SDK, "Auto-confirm enabled successfully", { result });
|
|
1410
|
+
return result;
|
|
1411
|
+
} catch (error) {
|
|
1412
|
+
debug.error(DebugCategory.BROWSER_SDK, "Failed to enable auto-confirm", { error: error.message });
|
|
1413
|
+
throw error;
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Disable auto-confirm for transactions
|
|
1418
|
+
* Only available for injected providers
|
|
1419
|
+
*/
|
|
1420
|
+
async disableAutoConfirm() {
|
|
1421
|
+
debug.info(DebugCategory.BROWSER_SDK, "Disabling auto-confirm");
|
|
1422
|
+
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1423
|
+
if (!currentProvider) {
|
|
1424
|
+
throw new Error("No provider available. Call connect() first.");
|
|
1425
|
+
}
|
|
1426
|
+
if (!("disableAutoConfirm" in currentProvider)) {
|
|
1427
|
+
throw new Error("Auto-confirm is only available for injected providers");
|
|
1428
|
+
}
|
|
1429
|
+
try {
|
|
1430
|
+
await currentProvider.disableAutoConfirm();
|
|
1431
|
+
debug.info(DebugCategory.BROWSER_SDK, "Auto-confirm disabled successfully");
|
|
1432
|
+
} catch (error) {
|
|
1433
|
+
debug.error(DebugCategory.BROWSER_SDK, "Failed to disable auto-confirm", { error: error.message });
|
|
1434
|
+
throw error;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Get current auto-confirm status
|
|
1439
|
+
* Only available for injected providers
|
|
1440
|
+
*/
|
|
1441
|
+
async getAutoConfirmStatus() {
|
|
1442
|
+
debug.info(DebugCategory.BROWSER_SDK, "Getting auto-confirm status");
|
|
1443
|
+
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1444
|
+
if (!currentProvider) {
|
|
1445
|
+
throw new Error("No provider available. Call connect() first.");
|
|
1446
|
+
}
|
|
1447
|
+
if (!("getAutoConfirmStatus" in currentProvider)) {
|
|
1448
|
+
throw new Error("Auto-confirm is only available for injected providers");
|
|
1449
|
+
}
|
|
1450
|
+
try {
|
|
1451
|
+
const result = await currentProvider.getAutoConfirmStatus();
|
|
1452
|
+
debug.info(DebugCategory.BROWSER_SDK, "Got auto-confirm status", { result });
|
|
1453
|
+
return result;
|
|
1454
|
+
} catch (error) {
|
|
1455
|
+
debug.error(DebugCategory.BROWSER_SDK, "Failed to get auto-confirm status", { error: error.message });
|
|
1456
|
+
throw error;
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Get supported chains for auto-confirm
|
|
1461
|
+
* Only available for injected providers
|
|
1462
|
+
*/
|
|
1463
|
+
async getSupportedAutoConfirmChains() {
|
|
1464
|
+
debug.info(DebugCategory.BROWSER_SDK, "Getting supported auto-confirm chains");
|
|
1465
|
+
const currentProvider = this.providerManager.getCurrentProvider();
|
|
1466
|
+
if (!currentProvider) {
|
|
1467
|
+
throw new Error("No provider available. Call connect() first.");
|
|
1468
|
+
}
|
|
1469
|
+
if (!("getSupportedAutoConfirmChains" in currentProvider)) {
|
|
1470
|
+
throw new Error("Auto-confirm is only available for injected providers");
|
|
1471
|
+
}
|
|
1472
|
+
try {
|
|
1473
|
+
const result = await currentProvider.getSupportedAutoConfirmChains();
|
|
1474
|
+
debug.info(DebugCategory.BROWSER_SDK, "Got supported auto-confirm chains", { result });
|
|
1475
|
+
return result;
|
|
1476
|
+
} catch (error) {
|
|
1477
|
+
debug.error(DebugCategory.BROWSER_SDK, "Failed to get supported auto-confirm chains", { error: error.message });
|
|
1478
|
+
throw error;
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1365
1481
|
};
|
|
1366
1482
|
|
|
1367
1483
|
// src/types.ts
|
|
1368
1484
|
var import_client2 = require("@phantom/client");
|
|
1369
1485
|
|
|
1370
1486
|
// src/index.ts
|
|
1371
|
-
var
|
|
1487
|
+
var import_constants4 = require("@phantom/constants");
|
|
1372
1488
|
var import_client3 = require("@phantom/client");
|