@phantom/browser-sdk 1.0.0-beta.0 → 1.0.0-beta.2
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 +96 -65
- package/dist/index.d.ts +21 -3
- package/dist/index.js +325 -131
- package/dist/index.mjs +329 -136
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -20,23 +20,24 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
AddressType: () =>
|
|
23
|
+
AddressType: () => import_client5.AddressType,
|
|
24
24
|
BrowserSDK: () => BrowserSDK,
|
|
25
25
|
DEFAULT_AUTH_URL: () => DEFAULT_AUTH_URL,
|
|
26
26
|
DEFAULT_WALLET_API_URL: () => DEFAULT_WALLET_API_URL,
|
|
27
27
|
DebugCategory: () => DebugCategory,
|
|
28
28
|
DebugLevel: () => DebugLevel,
|
|
29
|
-
NetworkId: () =>
|
|
29
|
+
NetworkId: () => import_constants2.NetworkId,
|
|
30
30
|
debug: () => debug,
|
|
31
31
|
detectBrowser: () => detectBrowser,
|
|
32
32
|
getBrowserDisplayName: () => getBrowserDisplayName,
|
|
33
33
|
getPlatformName: () => getPlatformName,
|
|
34
|
-
parseBrowserFromUserAgent: () => parseBrowserFromUserAgent
|
|
34
|
+
parseBrowserFromUserAgent: () => parseBrowserFromUserAgent,
|
|
35
|
+
waitForPhantomExtension: () => waitForPhantomExtension
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(src_exports);
|
|
37
38
|
|
|
38
39
|
// src/providers/injected/index.ts
|
|
39
|
-
var
|
|
40
|
+
var import_client3 = require("@phantom/client");
|
|
40
41
|
var import_browser_injected_sdk = require("@phantom/browser-injected-sdk");
|
|
41
42
|
var import_solana = require("@phantom/browser-injected-sdk/solana");
|
|
42
43
|
var import_ethereum = require("@phantom/browser-injected-sdk/ethereum");
|
|
@@ -117,97 +118,187 @@ var DebugCategory = {
|
|
|
117
118
|
};
|
|
118
119
|
|
|
119
120
|
// src/providers/injected/chains/SolanaChain.ts
|
|
120
|
-
var
|
|
121
|
+
var import_eventemitter3 = require("eventemitter3");
|
|
122
|
+
var import_client = require("@phantom/client");
|
|
121
123
|
var import_buffer = require("buffer");
|
|
122
124
|
var InjectedSolanaChain = class {
|
|
123
|
-
constructor(phantom) {
|
|
125
|
+
constructor(phantom, callbacks) {
|
|
126
|
+
this._connected = false;
|
|
127
|
+
this._publicKey = null;
|
|
128
|
+
this.eventEmitter = new import_eventemitter3.EventEmitter();
|
|
124
129
|
this.phantom = phantom;
|
|
130
|
+
this.callbacks = callbacks;
|
|
131
|
+
this.setupEventListeners();
|
|
132
|
+
this.syncInitialState();
|
|
133
|
+
}
|
|
134
|
+
// Wallet adapter compliant properties
|
|
135
|
+
get connected() {
|
|
136
|
+
return this._connected;
|
|
137
|
+
}
|
|
138
|
+
get publicKey() {
|
|
139
|
+
return this._publicKey;
|
|
140
|
+
}
|
|
141
|
+
// Connection methods - delegate to provider
|
|
142
|
+
connect(_options) {
|
|
143
|
+
if (!this.callbacks.isConnected()) {
|
|
144
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
145
|
+
}
|
|
146
|
+
const addresses = this.callbacks.getAddresses();
|
|
147
|
+
const solanaAddress = addresses.find((addr) => addr.addressType === import_client.AddressType.solana);
|
|
148
|
+
if (!solanaAddress) {
|
|
149
|
+
return Promise.reject(new Error("Solana not enabled for this provider"));
|
|
150
|
+
}
|
|
151
|
+
this.updateConnectionState(true, solanaAddress.address);
|
|
152
|
+
return Promise.resolve({ publicKey: solanaAddress.address });
|
|
153
|
+
}
|
|
154
|
+
async disconnect() {
|
|
155
|
+
await this.callbacks.disconnect();
|
|
125
156
|
}
|
|
157
|
+
// Standard wallet adapter methods
|
|
126
158
|
async signMessage(message) {
|
|
127
159
|
const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
128
160
|
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
161
|
return {
|
|
131
|
-
signature,
|
|
132
|
-
|
|
162
|
+
signature: result.signature instanceof Uint8Array ? result.signature : new Uint8Array(import_buffer.Buffer.from(result.signature, "base64")),
|
|
163
|
+
publicKey: this._publicKey || ""
|
|
133
164
|
};
|
|
134
165
|
}
|
|
135
|
-
signTransaction(
|
|
136
|
-
|
|
166
|
+
async signTransaction(transaction) {
|
|
167
|
+
if (!this.callbacks.isConnected()) {
|
|
168
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const result = await this.phantom.solana.signTransaction(transaction);
|
|
172
|
+
return result;
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return Promise.reject(error);
|
|
175
|
+
}
|
|
137
176
|
}
|
|
138
177
|
async signAndSendTransaction(transaction) {
|
|
139
178
|
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
|
-
};
|
|
179
|
+
return { signature: result.signature };
|
|
145
180
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (!address) {
|
|
149
|
-
throw new Error("Failed to connect to Solana wallet");
|
|
150
|
-
}
|
|
151
|
-
return { publicKey: address };
|
|
181
|
+
signAllTransactions(_transactions) {
|
|
182
|
+
return Promise.reject(new Error("Sign-only transactions not supported by injected provider"));
|
|
152
183
|
}
|
|
153
|
-
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
async switchNetwork(_network) {
|
|
184
|
+
switchNetwork(_network) {
|
|
185
|
+
return Promise.resolve();
|
|
157
186
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return address || null;
|
|
162
|
-
} catch {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
187
|
+
// Legacy methods
|
|
188
|
+
getPublicKey() {
|
|
189
|
+
return Promise.resolve(this._publicKey);
|
|
165
190
|
}
|
|
166
191
|
isConnected() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
192
|
+
return this._connected && this.callbacks.isConnected();
|
|
193
|
+
}
|
|
194
|
+
setupEventListeners() {
|
|
195
|
+
this.phantom.solana.addEventListener("connect", (publicKey) => {
|
|
196
|
+
this.updateConnectionState(true, publicKey);
|
|
197
|
+
this.eventEmitter.emit("connect", publicKey);
|
|
198
|
+
});
|
|
199
|
+
this.phantom.solana.addEventListener("disconnect", () => {
|
|
200
|
+
this.updateConnectionState(false, null);
|
|
201
|
+
this.eventEmitter.emit("disconnect");
|
|
202
|
+
});
|
|
203
|
+
this.phantom.solana.addEventListener("accountChanged", (publicKey) => {
|
|
204
|
+
this._publicKey = publicKey;
|
|
205
|
+
this.eventEmitter.emit("accountChanged", publicKey);
|
|
206
|
+
});
|
|
207
|
+
this.callbacks.on("connect", (data) => {
|
|
208
|
+
const solanaAddress = data.addresses?.find((addr) => addr.addressType === import_client.AddressType.solana);
|
|
209
|
+
if (solanaAddress) {
|
|
210
|
+
this.updateConnectionState(true, solanaAddress.address);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
this.callbacks.on("disconnect", () => {
|
|
214
|
+
this.updateConnectionState(false, null);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
syncInitialState() {
|
|
218
|
+
if (this.callbacks.isConnected()) {
|
|
219
|
+
const solanaAddress = this.callbacks.getAddresses().find((addr) => addr.addressType === import_client.AddressType.solana);
|
|
220
|
+
if (solanaAddress) {
|
|
221
|
+
this.updateConnectionState(true, solanaAddress.address);
|
|
222
|
+
}
|
|
171
223
|
}
|
|
172
224
|
}
|
|
225
|
+
updateConnectionState(connected, publicKey) {
|
|
226
|
+
this._connected = connected;
|
|
227
|
+
this._publicKey = publicKey;
|
|
228
|
+
}
|
|
229
|
+
// Event methods for interface compliance
|
|
230
|
+
on(event, listener) {
|
|
231
|
+
this.eventEmitter.on(event, listener);
|
|
232
|
+
}
|
|
233
|
+
off(event, listener) {
|
|
234
|
+
this.eventEmitter.off(event, listener);
|
|
235
|
+
}
|
|
173
236
|
};
|
|
174
237
|
|
|
175
238
|
// src/providers/injected/chains/EthereumChain.ts
|
|
176
|
-
var
|
|
239
|
+
var import_eventemitter32 = require("eventemitter3");
|
|
240
|
+
var import_client2 = require("@phantom/client");
|
|
177
241
|
var InjectedEthereumChain = class {
|
|
178
|
-
constructor(phantom) {
|
|
242
|
+
constructor(phantom, callbacks) {
|
|
243
|
+
this._connected = false;
|
|
244
|
+
this._chainId = "0x1";
|
|
245
|
+
this._accounts = [];
|
|
246
|
+
this.eventEmitter = new import_eventemitter32.EventEmitter();
|
|
179
247
|
this.phantom = phantom;
|
|
248
|
+
this.callbacks = callbacks;
|
|
249
|
+
this.setupEventListeners();
|
|
250
|
+
this.syncInitialState();
|
|
251
|
+
}
|
|
252
|
+
// EIP-1193 compliant properties
|
|
253
|
+
get connected() {
|
|
254
|
+
return this._connected;
|
|
255
|
+
}
|
|
256
|
+
get chainId() {
|
|
257
|
+
return this._chainId;
|
|
180
258
|
}
|
|
259
|
+
get accounts() {
|
|
260
|
+
return this._accounts;
|
|
261
|
+
}
|
|
262
|
+
// EIP-1193 core method with eth_signTransaction support
|
|
181
263
|
async request(args) {
|
|
264
|
+
if (args.method === "eth_signTransaction") {
|
|
265
|
+
const [transaction] = args.params;
|
|
266
|
+
const result = await this.signTransaction(transaction);
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
182
269
|
const provider = await this.phantom.ethereum.getProvider();
|
|
183
270
|
return await provider.request(args);
|
|
184
271
|
}
|
|
272
|
+
// Connection methods - delegate to provider
|
|
273
|
+
connect() {
|
|
274
|
+
if (!this.callbacks.isConnected()) {
|
|
275
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
276
|
+
}
|
|
277
|
+
const addresses = this.callbacks.getAddresses();
|
|
278
|
+
const ethAddresses = addresses.filter((addr) => addr.addressType === import_client2.AddressType.ethereum).map((addr) => addr.address);
|
|
279
|
+
this.updateConnectionState(true, ethAddresses);
|
|
280
|
+
return Promise.resolve(ethAddresses);
|
|
281
|
+
}
|
|
282
|
+
async disconnect() {
|
|
283
|
+
await this.callbacks.disconnect();
|
|
284
|
+
}
|
|
285
|
+
// Standard compliant methods (return raw values, not wrapped objects)
|
|
185
286
|
async signPersonalMessage(message, address) {
|
|
186
|
-
|
|
187
|
-
return {
|
|
188
|
-
signature,
|
|
189
|
-
rawSignature: signature
|
|
190
|
-
};
|
|
287
|
+
return await this.phantom.ethereum.signPersonalMessage(message, address);
|
|
191
288
|
}
|
|
192
289
|
async signTypedData(typedData, address) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
};
|
|
290
|
+
return await this.phantom.ethereum.signTypedData(typedData, address);
|
|
291
|
+
}
|
|
292
|
+
async signTransaction(transaction) {
|
|
293
|
+
return await this.phantom.ethereum.signTransaction(transaction);
|
|
198
294
|
}
|
|
199
295
|
async sendTransaction(transaction) {
|
|
200
|
-
|
|
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
|
-
};
|
|
296
|
+
return await this.phantom.ethereum.sendTransaction(transaction);
|
|
208
297
|
}
|
|
209
298
|
async switchChain(chainId) {
|
|
210
|
-
|
|
299
|
+
await this.phantom.ethereum.switchChain(`0x${chainId.toString(16)}`);
|
|
300
|
+
this._chainId = `0x${chainId.toString(16)}`;
|
|
301
|
+
this.eventEmitter.emit("chainChanged", this._chainId);
|
|
211
302
|
}
|
|
212
303
|
async getChainId() {
|
|
213
304
|
const chainId = await this.phantom.ethereum.getChainId();
|
|
@@ -217,12 +308,56 @@ var InjectedEthereumChain = class {
|
|
|
217
308
|
return await this.phantom.ethereum.getAccounts();
|
|
218
309
|
}
|
|
219
310
|
isConnected() {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
311
|
+
return this._connected && this.callbacks.isConnected();
|
|
312
|
+
}
|
|
313
|
+
setupEventListeners() {
|
|
314
|
+
this.phantom.ethereum.addEventListener("connect", (accounts) => {
|
|
315
|
+
this.updateConnectionState(true, accounts);
|
|
316
|
+
this.eventEmitter.emit("connect", { chainId: this._chainId });
|
|
317
|
+
this.eventEmitter.emit("accountsChanged", accounts);
|
|
318
|
+
});
|
|
319
|
+
this.phantom.ethereum.addEventListener("disconnect", () => {
|
|
320
|
+
this.updateConnectionState(false, []);
|
|
321
|
+
this.eventEmitter.emit("disconnect", { code: 4900, message: "Provider disconnected" });
|
|
322
|
+
this.eventEmitter.emit("accountsChanged", []);
|
|
323
|
+
});
|
|
324
|
+
this.phantom.ethereum.addEventListener("accountsChanged", (accounts) => {
|
|
325
|
+
this._accounts = accounts;
|
|
326
|
+
this.eventEmitter.emit("accountsChanged", accounts);
|
|
327
|
+
});
|
|
328
|
+
this.phantom.ethereum.addEventListener("chainChanged", (chainId) => {
|
|
329
|
+
this._chainId = chainId;
|
|
330
|
+
this.eventEmitter.emit("chainChanged", chainId);
|
|
331
|
+
});
|
|
332
|
+
this.callbacks.on("connect", (data) => {
|
|
333
|
+
const ethAddresses = data.addresses?.filter((addr) => addr.addressType === import_client2.AddressType.ethereum)?.map((addr) => addr.address) || [];
|
|
334
|
+
if (ethAddresses.length > 0) {
|
|
335
|
+
this.updateConnectionState(true, ethAddresses);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
this.callbacks.on("disconnect", () => {
|
|
339
|
+
this.updateConnectionState(false, []);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
syncInitialState() {
|
|
343
|
+
if (this.callbacks.isConnected()) {
|
|
344
|
+
const ethAddresses = this.callbacks.getAddresses().filter((addr) => addr.addressType === import_client2.AddressType.ethereum).map((addr) => addr.address);
|
|
345
|
+
if (ethAddresses.length > 0) {
|
|
346
|
+
this.updateConnectionState(true, ethAddresses);
|
|
347
|
+
}
|
|
224
348
|
}
|
|
225
349
|
}
|
|
350
|
+
updateConnectionState(connected, accounts) {
|
|
351
|
+
this._connected = connected;
|
|
352
|
+
this._accounts = accounts;
|
|
353
|
+
}
|
|
354
|
+
// Event methods for interface compliance
|
|
355
|
+
on(event, listener) {
|
|
356
|
+
this.eventEmitter.on(event, listener);
|
|
357
|
+
}
|
|
358
|
+
off(event, listener) {
|
|
359
|
+
this.eventEmitter.off(event, listener);
|
|
360
|
+
}
|
|
226
361
|
};
|
|
227
362
|
|
|
228
363
|
// src/providers/injected/index.ts
|
|
@@ -238,11 +373,11 @@ var InjectedProvider = class {
|
|
|
238
373
|
this.addressTypes = config.addressTypes;
|
|
239
374
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Address types configured", { addressTypes: this.addressTypes });
|
|
240
375
|
const plugins = [(0, import_browser_injected_sdk.createExtensionPlugin)()];
|
|
241
|
-
if (this.addressTypes.includes(
|
|
376
|
+
if (this.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
242
377
|
plugins.push((0, import_solana.createSolanaPlugin)());
|
|
243
378
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana plugin added");
|
|
244
379
|
}
|
|
245
|
-
if (this.addressTypes.includes(
|
|
380
|
+
if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
246
381
|
plugins.push((0, import_ethereum.createEthereumPlugin)());
|
|
247
382
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
|
|
248
383
|
}
|
|
@@ -252,17 +387,24 @@ var InjectedProvider = class {
|
|
|
252
387
|
pluginCount: plugins.length
|
|
253
388
|
});
|
|
254
389
|
this.phantom = (0, import_browser_injected_sdk.createPhantom)({ plugins });
|
|
390
|
+
const callbacks = this.createCallbacks();
|
|
391
|
+
if (this.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
392
|
+
this._solanaChain = new InjectedSolanaChain(this.phantom, callbacks);
|
|
393
|
+
}
|
|
394
|
+
if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
395
|
+
this._ethereumChain = new InjectedEthereumChain(this.phantom, callbacks);
|
|
396
|
+
}
|
|
255
397
|
debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
|
|
256
398
|
}
|
|
257
399
|
/**
|
|
258
400
|
* Access to Solana chain operations
|
|
259
401
|
*/
|
|
260
402
|
get solana() {
|
|
261
|
-
if (!this.addressTypes.includes(
|
|
403
|
+
if (!this.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
262
404
|
throw new Error("Solana not enabled for this provider");
|
|
263
405
|
}
|
|
264
406
|
if (!this._solanaChain) {
|
|
265
|
-
|
|
407
|
+
throw new Error("Solana chain not initialized");
|
|
266
408
|
}
|
|
267
409
|
return this._solanaChain;
|
|
268
410
|
}
|
|
@@ -270,11 +412,11 @@ var InjectedProvider = class {
|
|
|
270
412
|
* Access to Ethereum chain operations
|
|
271
413
|
*/
|
|
272
414
|
get ethereum() {
|
|
273
|
-
if (!this.addressTypes.includes(
|
|
415
|
+
if (!this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
274
416
|
throw new Error("Ethereum not enabled for this provider");
|
|
275
417
|
}
|
|
276
418
|
if (!this._ethereumChain) {
|
|
277
|
-
|
|
419
|
+
throw new Error("Ethereum chain not initialized");
|
|
278
420
|
}
|
|
279
421
|
return this._ethereumChain;
|
|
280
422
|
}
|
|
@@ -300,28 +442,28 @@ var InjectedProvider = class {
|
|
|
300
442
|
}
|
|
301
443
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Phantom extension detected");
|
|
302
444
|
const connectedAddresses = [];
|
|
303
|
-
if (this.addressTypes.includes(
|
|
445
|
+
if (this.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
304
446
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
|
|
305
447
|
try {
|
|
306
|
-
const
|
|
307
|
-
if (
|
|
448
|
+
const publicKey = await this.phantom.solana.connect();
|
|
449
|
+
if (publicKey) {
|
|
308
450
|
connectedAddresses.push({
|
|
309
|
-
addressType:
|
|
310
|
-
address:
|
|
451
|
+
addressType: import_client3.AddressType.solana,
|
|
452
|
+
address: publicKey
|
|
311
453
|
});
|
|
312
|
-
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address:
|
|
454
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
|
|
313
455
|
}
|
|
314
456
|
} catch (err) {
|
|
315
457
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
|
|
316
458
|
}
|
|
317
459
|
}
|
|
318
|
-
if (this.addressTypes.includes(
|
|
460
|
+
if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
319
461
|
try {
|
|
320
|
-
const accounts = await this.ethereum.
|
|
462
|
+
const accounts = await this.phantom.ethereum.connect();
|
|
321
463
|
if (accounts && accounts.length > 0) {
|
|
322
464
|
connectedAddresses.push(
|
|
323
465
|
...accounts.map((address) => ({
|
|
324
|
-
addressType:
|
|
466
|
+
addressType: import_client3.AddressType.ethereum,
|
|
325
467
|
address
|
|
326
468
|
}))
|
|
327
469
|
);
|
|
@@ -363,19 +505,17 @@ var InjectedProvider = class {
|
|
|
363
505
|
}
|
|
364
506
|
async disconnect() {
|
|
365
507
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
|
|
366
|
-
if (this.addressTypes.includes(
|
|
508
|
+
if (this.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
367
509
|
try {
|
|
368
|
-
await this.solana.disconnect();
|
|
510
|
+
await this.phantom.solana.disconnect();
|
|
369
511
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
|
|
370
512
|
} catch (err) {
|
|
371
513
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
|
|
372
514
|
}
|
|
373
515
|
}
|
|
374
|
-
if (this.addressTypes.includes(
|
|
516
|
+
if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
375
517
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected (no-op)");
|
|
376
518
|
}
|
|
377
|
-
this._solanaChain = void 0;
|
|
378
|
-
this._ethereumChain = void 0;
|
|
379
519
|
this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
|
|
380
520
|
this.browserInjectedCleanupFunctions = [];
|
|
381
521
|
this.connected = false;
|
|
@@ -448,10 +588,10 @@ var InjectedProvider = class {
|
|
|
448
588
|
}
|
|
449
589
|
setupBrowserInjectedEvents() {
|
|
450
590
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
|
|
451
|
-
if (this.addressTypes.includes(
|
|
591
|
+
if (this.addressTypes.includes(import_client3.AddressType.solana)) {
|
|
452
592
|
this.setupSolanaEvents();
|
|
453
593
|
}
|
|
454
|
-
if (this.addressTypes.includes(
|
|
594
|
+
if (this.addressTypes.includes(import_client3.AddressType.ethereum)) {
|
|
455
595
|
this.setupEthereumEvents();
|
|
456
596
|
}
|
|
457
597
|
}
|
|
@@ -459,8 +599,8 @@ var InjectedProvider = class {
|
|
|
459
599
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
|
|
460
600
|
const handleSolanaConnect = (publicKey) => {
|
|
461
601
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
|
|
462
|
-
const solanaAddress = { addressType:
|
|
463
|
-
if (!this.addresses.find((addr) => addr.addressType ===
|
|
602
|
+
const solanaAddress = { addressType: import_client3.AddressType.solana, address: publicKey };
|
|
603
|
+
if (!this.addresses.find((addr) => addr.addressType === import_client3.AddressType.solana)) {
|
|
464
604
|
this.addresses.push(solanaAddress);
|
|
465
605
|
}
|
|
466
606
|
this.connected = true;
|
|
@@ -471,7 +611,7 @@ var InjectedProvider = class {
|
|
|
471
611
|
};
|
|
472
612
|
const handleSolanaDisconnect = () => {
|
|
473
613
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received");
|
|
474
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
614
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.solana);
|
|
475
615
|
this.connected = this.addresses.length > 0;
|
|
476
616
|
this.emit("disconnect", {
|
|
477
617
|
source: "injected-extension"
|
|
@@ -479,11 +619,11 @@ var InjectedProvider = class {
|
|
|
479
619
|
};
|
|
480
620
|
const handleSolanaAccountChanged = (publicKey) => {
|
|
481
621
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
|
|
482
|
-
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType ===
|
|
622
|
+
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType === import_client3.AddressType.solana);
|
|
483
623
|
if (solanaIndex >= 0) {
|
|
484
|
-
this.addresses[solanaIndex] = { addressType:
|
|
624
|
+
this.addresses[solanaIndex] = { addressType: import_client3.AddressType.solana, address: publicKey };
|
|
485
625
|
} else {
|
|
486
|
-
this.addresses.push({ addressType:
|
|
626
|
+
this.addresses.push({ addressType: import_client3.AddressType.solana, address: publicKey });
|
|
487
627
|
}
|
|
488
628
|
this.emit("connect", {
|
|
489
629
|
addresses: this.addresses,
|
|
@@ -492,23 +632,24 @@ var InjectedProvider = class {
|
|
|
492
632
|
};
|
|
493
633
|
const cleanupConnect = this.phantom.solana.addEventListener("connect", handleSolanaConnect);
|
|
494
634
|
const cleanupDisconnect = this.phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
|
|
495
|
-
const cleanupAccountChanged = this.phantom.solana.addEventListener(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
cleanupDisconnect,
|
|
499
|
-
cleanupAccountChanged
|
|
635
|
+
const cleanupAccountChanged = this.phantom.solana.addEventListener(
|
|
636
|
+
"accountChanged",
|
|
637
|
+
handleSolanaAccountChanged
|
|
500
638
|
);
|
|
639
|
+
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountChanged);
|
|
501
640
|
}
|
|
502
641
|
setupEthereumEvents() {
|
|
503
642
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
|
|
504
643
|
const handleEthereumConnect = (accounts) => {
|
|
505
644
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
|
|
506
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
645
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
507
646
|
if (accounts && accounts.length > 0) {
|
|
508
|
-
this.addresses.push(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
647
|
+
this.addresses.push(
|
|
648
|
+
...accounts.map((address) => ({
|
|
649
|
+
addressType: import_client3.AddressType.ethereum,
|
|
650
|
+
address
|
|
651
|
+
}))
|
|
652
|
+
);
|
|
512
653
|
}
|
|
513
654
|
this.connected = this.addresses.length > 0;
|
|
514
655
|
this.emit("connect", {
|
|
@@ -518,7 +659,7 @@ var InjectedProvider = class {
|
|
|
518
659
|
};
|
|
519
660
|
const handleEthereumDisconnect = () => {
|
|
520
661
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
|
|
521
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
662
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
522
663
|
this.connected = this.addresses.length > 0;
|
|
523
664
|
this.emit("disconnect", {
|
|
524
665
|
source: "injected-extension"
|
|
@@ -526,12 +667,14 @@ var InjectedProvider = class {
|
|
|
526
667
|
};
|
|
527
668
|
const handleEthereumAccountsChanged = (accounts) => {
|
|
528
669
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
|
|
529
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
670
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== import_client3.AddressType.ethereum);
|
|
530
671
|
if (accounts && accounts.length > 0) {
|
|
531
|
-
this.addresses.push(
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
672
|
+
this.addresses.push(
|
|
673
|
+
...accounts.map((address) => ({
|
|
674
|
+
addressType: import_client3.AddressType.ethereum,
|
|
675
|
+
address
|
|
676
|
+
}))
|
|
677
|
+
);
|
|
535
678
|
}
|
|
536
679
|
this.emit("connect", {
|
|
537
680
|
addresses: this.addresses,
|
|
@@ -540,12 +683,34 @@ var InjectedProvider = class {
|
|
|
540
683
|
};
|
|
541
684
|
const cleanupConnect = this.phantom.ethereum.addEventListener("connect", handleEthereumConnect);
|
|
542
685
|
const cleanupDisconnect = this.phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
|
|
543
|
-
const cleanupAccountsChanged = this.phantom.ethereum.addEventListener(
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
cleanupDisconnect,
|
|
547
|
-
cleanupAccountsChanged
|
|
686
|
+
const cleanupAccountsChanged = this.phantom.ethereum.addEventListener(
|
|
687
|
+
"accountsChanged",
|
|
688
|
+
handleEthereumAccountsChanged
|
|
548
689
|
);
|
|
690
|
+
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountsChanged);
|
|
691
|
+
}
|
|
692
|
+
createCallbacks() {
|
|
693
|
+
return {
|
|
694
|
+
connect: async () => {
|
|
695
|
+
const result = await this.connect();
|
|
696
|
+
return result.addresses;
|
|
697
|
+
},
|
|
698
|
+
disconnect: async () => {
|
|
699
|
+
await this.disconnect();
|
|
700
|
+
},
|
|
701
|
+
isConnected: () => {
|
|
702
|
+
return this.isConnected();
|
|
703
|
+
},
|
|
704
|
+
getAddresses: () => {
|
|
705
|
+
return this.getAddresses();
|
|
706
|
+
},
|
|
707
|
+
on: (event, callback) => {
|
|
708
|
+
this.on(event, callback);
|
|
709
|
+
},
|
|
710
|
+
off: (event, callback) => {
|
|
711
|
+
this.off(event, callback);
|
|
712
|
+
}
|
|
713
|
+
};
|
|
549
714
|
}
|
|
550
715
|
};
|
|
551
716
|
|
|
@@ -661,6 +826,7 @@ var BrowserAuthProvider = class {
|
|
|
661
826
|
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Starting Phantom Connect authentication", {
|
|
662
827
|
organizationId: phantomOptions.organizationId,
|
|
663
828
|
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
829
|
+
appId: phantomOptions.appId,
|
|
664
830
|
provider: phantomOptions.provider,
|
|
665
831
|
authUrl: phantomOptions.authUrl,
|
|
666
832
|
hasCustomData: !!phantomOptions.customAuthData
|
|
@@ -670,13 +836,10 @@ var BrowserAuthProvider = class {
|
|
|
670
836
|
const params = new URLSearchParams({
|
|
671
837
|
organization_id: phantomOptions.organizationId,
|
|
672
838
|
parent_organization_id: phantomOptions.parentOrganizationId,
|
|
839
|
+
app_id: phantomOptions.appId,
|
|
673
840
|
redirect_uri: phantomOptions.redirectUrl || (typeof window !== "undefined" ? window.location.href : ""),
|
|
674
841
|
session_id: phantomOptions.sessionId,
|
|
675
|
-
clear_previous_session: true.toString()
|
|
676
|
-
app_name: phantomOptions.appName || "",
|
|
677
|
-
// Optional app name
|
|
678
|
-
app_logo: phantomOptions.appLogo || ""
|
|
679
|
-
// Optional app logo URL
|
|
842
|
+
clear_previous_session: true.toString()
|
|
680
843
|
});
|
|
681
844
|
if (phantomOptions.provider) {
|
|
682
845
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
|
|
@@ -694,6 +857,7 @@ var BrowserAuthProvider = class {
|
|
|
694
857
|
const authContext = {
|
|
695
858
|
organizationId: phantomOptions.organizationId,
|
|
696
859
|
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
860
|
+
appId: phantomOptions.appId,
|
|
697
861
|
provider: phantomOptions.provider,
|
|
698
862
|
sessionId: phantomOptions.sessionId
|
|
699
863
|
};
|
|
@@ -1091,7 +1255,13 @@ var ProviderManager = class {
|
|
|
1091
1255
|
return;
|
|
1092
1256
|
}
|
|
1093
1257
|
debug.log(DebugCategory.PROVIDER_MANAGER, "Setting up event forwarding from current provider");
|
|
1094
|
-
const eventsToForward = [
|
|
1258
|
+
const eventsToForward = [
|
|
1259
|
+
"connect_start",
|
|
1260
|
+
"connect",
|
|
1261
|
+
"connect_error",
|
|
1262
|
+
"disconnect",
|
|
1263
|
+
"error"
|
|
1264
|
+
];
|
|
1095
1265
|
for (const event of eventsToForward) {
|
|
1096
1266
|
const forwardingCallback = (data) => {
|
|
1097
1267
|
debug.log(DebugCategory.PROVIDER_MANAGER, "Forwarding event from provider", { event, data });
|
|
@@ -1125,19 +1295,17 @@ var ProviderManager = class {
|
|
|
1125
1295
|
addressTypes: this.config.addressTypes
|
|
1126
1296
|
});
|
|
1127
1297
|
} else {
|
|
1128
|
-
if (!this.config.apiBaseUrl || !this.config.
|
|
1129
|
-
throw new Error("apiBaseUrl and
|
|
1298
|
+
if (!this.config.apiBaseUrl || !this.config.appId) {
|
|
1299
|
+
throw new Error("apiBaseUrl and appId are required for embedded provider");
|
|
1130
1300
|
}
|
|
1131
1301
|
provider = new EmbeddedProvider({
|
|
1132
1302
|
apiBaseUrl: this.config.apiBaseUrl,
|
|
1133
|
-
organizationId: this.config.
|
|
1303
|
+
organizationId: this.config.appId,
|
|
1304
|
+
appId: this.config.appId,
|
|
1134
1305
|
authOptions: this.config.authOptions,
|
|
1135
1306
|
embeddedWalletType: embeddedWalletType || "app-wallet",
|
|
1136
1307
|
addressTypes: this.config.addressTypes,
|
|
1137
|
-
solanaProvider: this.config.solanaProvider || "web3js"
|
|
1138
|
-
appLogo: this.config.appLogo,
|
|
1139
|
-
// Optional app logo URL
|
|
1140
|
-
appName: this.config.appName
|
|
1308
|
+
solanaProvider: this.config.solanaProvider || "web3js"
|
|
1141
1309
|
});
|
|
1142
1310
|
}
|
|
1143
1311
|
this.providers.set(key, provider);
|
|
@@ -1184,8 +1352,32 @@ var ProviderManager = class {
|
|
|
1184
1352
|
}*/
|
|
1185
1353
|
};
|
|
1186
1354
|
|
|
1187
|
-
// src/
|
|
1355
|
+
// src/waitForPhantomExtension.ts
|
|
1188
1356
|
var import_browser_injected_sdk2 = require("@phantom/browser-injected-sdk");
|
|
1357
|
+
async function waitForPhantomExtension(timeoutMs = 3e3) {
|
|
1358
|
+
return new Promise((resolve) => {
|
|
1359
|
+
const startTime = Date.now();
|
|
1360
|
+
const checkInterval = 100;
|
|
1361
|
+
const checkForExtension = () => {
|
|
1362
|
+
try {
|
|
1363
|
+
if ((0, import_browser_injected_sdk2.isPhantomExtensionInstalled)()) {
|
|
1364
|
+
resolve(true);
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
} catch (error) {
|
|
1368
|
+
}
|
|
1369
|
+
const elapsed = Date.now() - startTime;
|
|
1370
|
+
if (elapsed >= timeoutMs) {
|
|
1371
|
+
resolve(false);
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1374
|
+
setTimeout(checkForExtension, checkInterval);
|
|
1375
|
+
};
|
|
1376
|
+
checkForExtension();
|
|
1377
|
+
});
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// src/BrowserSDK.ts
|
|
1189
1381
|
var BrowserSDK = class {
|
|
1190
1382
|
constructor(config) {
|
|
1191
1383
|
debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
|
|
@@ -1306,8 +1498,8 @@ var BrowserSDK = class {
|
|
|
1306
1498
|
/**
|
|
1307
1499
|
* Check if Phantom extension is installed
|
|
1308
1500
|
*/
|
|
1309
|
-
static isPhantomInstalled() {
|
|
1310
|
-
return (
|
|
1501
|
+
static async isPhantomInstalled(timeoutMs) {
|
|
1502
|
+
return waitForPhantomExtension(timeoutMs);
|
|
1311
1503
|
}
|
|
1312
1504
|
/**
|
|
1313
1505
|
* Add event listener for provider events (connect, connect_start, connect_error, disconnect, error)
|
|
@@ -1474,15 +1666,17 @@ var BrowserSDK = class {
|
|
|
1474
1666
|
debug.info(DebugCategory.BROWSER_SDK, "Got supported auto-confirm chains", { result });
|
|
1475
1667
|
return result;
|
|
1476
1668
|
} catch (error) {
|
|
1477
|
-
debug.error(DebugCategory.BROWSER_SDK, "Failed to get supported auto-confirm chains", {
|
|
1669
|
+
debug.error(DebugCategory.BROWSER_SDK, "Failed to get supported auto-confirm chains", {
|
|
1670
|
+
error: error.message
|
|
1671
|
+
});
|
|
1478
1672
|
throw error;
|
|
1479
1673
|
}
|
|
1480
1674
|
}
|
|
1481
1675
|
};
|
|
1482
1676
|
|
|
1483
1677
|
// src/types.ts
|
|
1484
|
-
var
|
|
1678
|
+
var import_client4 = require("@phantom/client");
|
|
1485
1679
|
|
|
1486
1680
|
// src/index.ts
|
|
1487
|
-
var
|
|
1488
|
-
var
|
|
1681
|
+
var import_constants2 = require("@phantom/constants");
|
|
1682
|
+
var import_client5 = require("@phantom/client");
|