@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.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
// src/providers/injected/index.ts
|
|
2
|
-
import { AddressType } from "@phantom/client";
|
|
3
|
-
import {
|
|
4
|
-
createPhantom,
|
|
5
|
-
createExtensionPlugin
|
|
6
|
-
} from "@phantom/browser-injected-sdk";
|
|
2
|
+
import { AddressType as AddressType3 } from "@phantom/client";
|
|
3
|
+
import { createPhantom, createExtensionPlugin } from "@phantom/browser-injected-sdk";
|
|
7
4
|
import { createSolanaPlugin } from "@phantom/browser-injected-sdk/solana";
|
|
8
5
|
import { createEthereumPlugin } from "@phantom/browser-injected-sdk/ethereum";
|
|
9
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
createAutoConfirmPlugin
|
|
8
|
+
} from "@phantom/browser-injected-sdk/auto-confirm";
|
|
10
9
|
|
|
11
10
|
// src/debug.ts
|
|
12
11
|
var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
|
|
@@ -83,97 +82,187 @@ var DebugCategory = {
|
|
|
83
82
|
};
|
|
84
83
|
|
|
85
84
|
// src/providers/injected/chains/SolanaChain.ts
|
|
86
|
-
import {
|
|
85
|
+
import { EventEmitter } from "eventemitter3";
|
|
86
|
+
import { AddressType } from "@phantom/client";
|
|
87
87
|
import { Buffer } from "buffer";
|
|
88
88
|
var InjectedSolanaChain = class {
|
|
89
|
-
constructor(phantom) {
|
|
89
|
+
constructor(phantom, callbacks) {
|
|
90
|
+
this._connected = false;
|
|
91
|
+
this._publicKey = null;
|
|
92
|
+
this.eventEmitter = new EventEmitter();
|
|
90
93
|
this.phantom = phantom;
|
|
94
|
+
this.callbacks = callbacks;
|
|
95
|
+
this.setupEventListeners();
|
|
96
|
+
this.syncInitialState();
|
|
97
|
+
}
|
|
98
|
+
// Wallet adapter compliant properties
|
|
99
|
+
get connected() {
|
|
100
|
+
return this._connected;
|
|
101
|
+
}
|
|
102
|
+
get publicKey() {
|
|
103
|
+
return this._publicKey;
|
|
104
|
+
}
|
|
105
|
+
// Connection methods - delegate to provider
|
|
106
|
+
connect(_options) {
|
|
107
|
+
if (!this.callbacks.isConnected()) {
|
|
108
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
109
|
+
}
|
|
110
|
+
const addresses = this.callbacks.getAddresses();
|
|
111
|
+
const solanaAddress = addresses.find((addr) => addr.addressType === AddressType.solana);
|
|
112
|
+
if (!solanaAddress) {
|
|
113
|
+
return Promise.reject(new Error("Solana not enabled for this provider"));
|
|
114
|
+
}
|
|
115
|
+
this.updateConnectionState(true, solanaAddress.address);
|
|
116
|
+
return Promise.resolve({ publicKey: solanaAddress.address });
|
|
117
|
+
}
|
|
118
|
+
async disconnect() {
|
|
119
|
+
await this.callbacks.disconnect();
|
|
91
120
|
}
|
|
121
|
+
// Standard wallet adapter methods
|
|
92
122
|
async signMessage(message) {
|
|
93
123
|
const messageBytes = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
94
124
|
const result = await this.phantom.solana.signMessage(messageBytes);
|
|
95
|
-
const signature = result.signature instanceof Uint8Array ? Buffer.from(result.signature).toString("base64") : result.signature;
|
|
96
125
|
return {
|
|
97
|
-
signature,
|
|
98
|
-
|
|
126
|
+
signature: result.signature instanceof Uint8Array ? result.signature : new Uint8Array(Buffer.from(result.signature, "base64")),
|
|
127
|
+
publicKey: this._publicKey || ""
|
|
99
128
|
};
|
|
100
129
|
}
|
|
101
|
-
signTransaction(
|
|
102
|
-
|
|
130
|
+
async signTransaction(transaction) {
|
|
131
|
+
if (!this.callbacks.isConnected()) {
|
|
132
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
const result = await this.phantom.solana.signTransaction(transaction);
|
|
136
|
+
return result;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
return Promise.reject(error);
|
|
139
|
+
}
|
|
103
140
|
}
|
|
104
141
|
async signAndSendTransaction(transaction) {
|
|
105
142
|
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
|
-
};
|
|
143
|
+
return { signature: result.signature };
|
|
111
144
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (!address) {
|
|
115
|
-
throw new Error("Failed to connect to Solana wallet");
|
|
116
|
-
}
|
|
117
|
-
return { publicKey: address };
|
|
145
|
+
signAllTransactions(_transactions) {
|
|
146
|
+
return Promise.reject(new Error("Sign-only transactions not supported by injected provider"));
|
|
118
147
|
}
|
|
119
|
-
|
|
120
|
-
return
|
|
148
|
+
switchNetwork(_network) {
|
|
149
|
+
return Promise.resolve();
|
|
121
150
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
try {
|
|
126
|
-
const address = await this.phantom.solana.getAccount();
|
|
127
|
-
return address || null;
|
|
128
|
-
} catch {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
151
|
+
// Legacy methods
|
|
152
|
+
getPublicKey() {
|
|
153
|
+
return Promise.resolve(this._publicKey);
|
|
131
154
|
}
|
|
132
155
|
isConnected() {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
return this._connected && this.callbacks.isConnected();
|
|
157
|
+
}
|
|
158
|
+
setupEventListeners() {
|
|
159
|
+
this.phantom.solana.addEventListener("connect", (publicKey) => {
|
|
160
|
+
this.updateConnectionState(true, publicKey);
|
|
161
|
+
this.eventEmitter.emit("connect", publicKey);
|
|
162
|
+
});
|
|
163
|
+
this.phantom.solana.addEventListener("disconnect", () => {
|
|
164
|
+
this.updateConnectionState(false, null);
|
|
165
|
+
this.eventEmitter.emit("disconnect");
|
|
166
|
+
});
|
|
167
|
+
this.phantom.solana.addEventListener("accountChanged", (publicKey) => {
|
|
168
|
+
this._publicKey = publicKey;
|
|
169
|
+
this.eventEmitter.emit("accountChanged", publicKey);
|
|
170
|
+
});
|
|
171
|
+
this.callbacks.on("connect", (data) => {
|
|
172
|
+
const solanaAddress = data.addresses?.find((addr) => addr.addressType === AddressType.solana);
|
|
173
|
+
if (solanaAddress) {
|
|
174
|
+
this.updateConnectionState(true, solanaAddress.address);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
this.callbacks.on("disconnect", () => {
|
|
178
|
+
this.updateConnectionState(false, null);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
syncInitialState() {
|
|
182
|
+
if (this.callbacks.isConnected()) {
|
|
183
|
+
const solanaAddress = this.callbacks.getAddresses().find((addr) => addr.addressType === AddressType.solana);
|
|
184
|
+
if (solanaAddress) {
|
|
185
|
+
this.updateConnectionState(true, solanaAddress.address);
|
|
186
|
+
}
|
|
137
187
|
}
|
|
138
188
|
}
|
|
189
|
+
updateConnectionState(connected, publicKey) {
|
|
190
|
+
this._connected = connected;
|
|
191
|
+
this._publicKey = publicKey;
|
|
192
|
+
}
|
|
193
|
+
// Event methods for interface compliance
|
|
194
|
+
on(event, listener) {
|
|
195
|
+
this.eventEmitter.on(event, listener);
|
|
196
|
+
}
|
|
197
|
+
off(event, listener) {
|
|
198
|
+
this.eventEmitter.off(event, listener);
|
|
199
|
+
}
|
|
139
200
|
};
|
|
140
201
|
|
|
141
202
|
// src/providers/injected/chains/EthereumChain.ts
|
|
142
|
-
import {
|
|
203
|
+
import { EventEmitter as EventEmitter2 } from "eventemitter3";
|
|
204
|
+
import { AddressType as AddressType2 } from "@phantom/client";
|
|
143
205
|
var InjectedEthereumChain = class {
|
|
144
|
-
constructor(phantom) {
|
|
206
|
+
constructor(phantom, callbacks) {
|
|
207
|
+
this._connected = false;
|
|
208
|
+
this._chainId = "0x1";
|
|
209
|
+
this._accounts = [];
|
|
210
|
+
this.eventEmitter = new EventEmitter2();
|
|
145
211
|
this.phantom = phantom;
|
|
212
|
+
this.callbacks = callbacks;
|
|
213
|
+
this.setupEventListeners();
|
|
214
|
+
this.syncInitialState();
|
|
215
|
+
}
|
|
216
|
+
// EIP-1193 compliant properties
|
|
217
|
+
get connected() {
|
|
218
|
+
return this._connected;
|
|
146
219
|
}
|
|
220
|
+
get chainId() {
|
|
221
|
+
return this._chainId;
|
|
222
|
+
}
|
|
223
|
+
get accounts() {
|
|
224
|
+
return this._accounts;
|
|
225
|
+
}
|
|
226
|
+
// EIP-1193 core method with eth_signTransaction support
|
|
147
227
|
async request(args) {
|
|
228
|
+
if (args.method === "eth_signTransaction") {
|
|
229
|
+
const [transaction] = args.params;
|
|
230
|
+
const result = await this.signTransaction(transaction);
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
148
233
|
const provider = await this.phantom.ethereum.getProvider();
|
|
149
234
|
return await provider.request(args);
|
|
150
235
|
}
|
|
236
|
+
// Connection methods - delegate to provider
|
|
237
|
+
connect() {
|
|
238
|
+
if (!this.callbacks.isConnected()) {
|
|
239
|
+
return Promise.reject(new Error("Provider not connected. Call provider connect first."));
|
|
240
|
+
}
|
|
241
|
+
const addresses = this.callbacks.getAddresses();
|
|
242
|
+
const ethAddresses = addresses.filter((addr) => addr.addressType === AddressType2.ethereum).map((addr) => addr.address);
|
|
243
|
+
this.updateConnectionState(true, ethAddresses);
|
|
244
|
+
return Promise.resolve(ethAddresses);
|
|
245
|
+
}
|
|
246
|
+
async disconnect() {
|
|
247
|
+
await this.callbacks.disconnect();
|
|
248
|
+
}
|
|
249
|
+
// Standard compliant methods (return raw values, not wrapped objects)
|
|
151
250
|
async signPersonalMessage(message, address) {
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
signature,
|
|
155
|
-
rawSignature: signature
|
|
156
|
-
};
|
|
251
|
+
return await this.phantom.ethereum.signPersonalMessage(message, address);
|
|
157
252
|
}
|
|
158
253
|
async signTypedData(typedData, address) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
};
|
|
254
|
+
return await this.phantom.ethereum.signTypedData(typedData, address);
|
|
255
|
+
}
|
|
256
|
+
async signTransaction(transaction) {
|
|
257
|
+
return await this.phantom.ethereum.signTransaction(transaction);
|
|
164
258
|
}
|
|
165
259
|
async sendTransaction(transaction) {
|
|
166
|
-
|
|
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
|
-
};
|
|
260
|
+
return await this.phantom.ethereum.sendTransaction(transaction);
|
|
174
261
|
}
|
|
175
262
|
async switchChain(chainId) {
|
|
176
|
-
|
|
263
|
+
await this.phantom.ethereum.switchChain(`0x${chainId.toString(16)}`);
|
|
264
|
+
this._chainId = `0x${chainId.toString(16)}`;
|
|
265
|
+
this.eventEmitter.emit("chainChanged", this._chainId);
|
|
177
266
|
}
|
|
178
267
|
async getChainId() {
|
|
179
268
|
const chainId = await this.phantom.ethereum.getChainId();
|
|
@@ -183,12 +272,56 @@ var InjectedEthereumChain = class {
|
|
|
183
272
|
return await this.phantom.ethereum.getAccounts();
|
|
184
273
|
}
|
|
185
274
|
isConnected() {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
275
|
+
return this._connected && this.callbacks.isConnected();
|
|
276
|
+
}
|
|
277
|
+
setupEventListeners() {
|
|
278
|
+
this.phantom.ethereum.addEventListener("connect", (accounts) => {
|
|
279
|
+
this.updateConnectionState(true, accounts);
|
|
280
|
+
this.eventEmitter.emit("connect", { chainId: this._chainId });
|
|
281
|
+
this.eventEmitter.emit("accountsChanged", accounts);
|
|
282
|
+
});
|
|
283
|
+
this.phantom.ethereum.addEventListener("disconnect", () => {
|
|
284
|
+
this.updateConnectionState(false, []);
|
|
285
|
+
this.eventEmitter.emit("disconnect", { code: 4900, message: "Provider disconnected" });
|
|
286
|
+
this.eventEmitter.emit("accountsChanged", []);
|
|
287
|
+
});
|
|
288
|
+
this.phantom.ethereum.addEventListener("accountsChanged", (accounts) => {
|
|
289
|
+
this._accounts = accounts;
|
|
290
|
+
this.eventEmitter.emit("accountsChanged", accounts);
|
|
291
|
+
});
|
|
292
|
+
this.phantom.ethereum.addEventListener("chainChanged", (chainId) => {
|
|
293
|
+
this._chainId = chainId;
|
|
294
|
+
this.eventEmitter.emit("chainChanged", chainId);
|
|
295
|
+
});
|
|
296
|
+
this.callbacks.on("connect", (data) => {
|
|
297
|
+
const ethAddresses = data.addresses?.filter((addr) => addr.addressType === AddressType2.ethereum)?.map((addr) => addr.address) || [];
|
|
298
|
+
if (ethAddresses.length > 0) {
|
|
299
|
+
this.updateConnectionState(true, ethAddresses);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
this.callbacks.on("disconnect", () => {
|
|
303
|
+
this.updateConnectionState(false, []);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
syncInitialState() {
|
|
307
|
+
if (this.callbacks.isConnected()) {
|
|
308
|
+
const ethAddresses = this.callbacks.getAddresses().filter((addr) => addr.addressType === AddressType2.ethereum).map((addr) => addr.address);
|
|
309
|
+
if (ethAddresses.length > 0) {
|
|
310
|
+
this.updateConnectionState(true, ethAddresses);
|
|
311
|
+
}
|
|
190
312
|
}
|
|
191
313
|
}
|
|
314
|
+
updateConnectionState(connected, accounts) {
|
|
315
|
+
this._connected = connected;
|
|
316
|
+
this._accounts = accounts;
|
|
317
|
+
}
|
|
318
|
+
// Event methods for interface compliance
|
|
319
|
+
on(event, listener) {
|
|
320
|
+
this.eventEmitter.on(event, listener);
|
|
321
|
+
}
|
|
322
|
+
off(event, listener) {
|
|
323
|
+
this.eventEmitter.off(event, listener);
|
|
324
|
+
}
|
|
192
325
|
};
|
|
193
326
|
|
|
194
327
|
// src/providers/injected/index.ts
|
|
@@ -204,11 +337,11 @@ var InjectedProvider = class {
|
|
|
204
337
|
this.addressTypes = config.addressTypes;
|
|
205
338
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Address types configured", { addressTypes: this.addressTypes });
|
|
206
339
|
const plugins = [createExtensionPlugin()];
|
|
207
|
-
if (this.addressTypes.includes(
|
|
340
|
+
if (this.addressTypes.includes(AddressType3.solana)) {
|
|
208
341
|
plugins.push(createSolanaPlugin());
|
|
209
342
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana plugin added");
|
|
210
343
|
}
|
|
211
|
-
if (this.addressTypes.includes(
|
|
344
|
+
if (this.addressTypes.includes(AddressType3.ethereum)) {
|
|
212
345
|
plugins.push(createEthereumPlugin());
|
|
213
346
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
|
|
214
347
|
}
|
|
@@ -218,17 +351,24 @@ var InjectedProvider = class {
|
|
|
218
351
|
pluginCount: plugins.length
|
|
219
352
|
});
|
|
220
353
|
this.phantom = createPhantom({ plugins });
|
|
354
|
+
const callbacks = this.createCallbacks();
|
|
355
|
+
if (this.addressTypes.includes(AddressType3.solana)) {
|
|
356
|
+
this._solanaChain = new InjectedSolanaChain(this.phantom, callbacks);
|
|
357
|
+
}
|
|
358
|
+
if (this.addressTypes.includes(AddressType3.ethereum)) {
|
|
359
|
+
this._ethereumChain = new InjectedEthereumChain(this.phantom, callbacks);
|
|
360
|
+
}
|
|
221
361
|
debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
|
|
222
362
|
}
|
|
223
363
|
/**
|
|
224
364
|
* Access to Solana chain operations
|
|
225
365
|
*/
|
|
226
366
|
get solana() {
|
|
227
|
-
if (!this.addressTypes.includes(
|
|
367
|
+
if (!this.addressTypes.includes(AddressType3.solana)) {
|
|
228
368
|
throw new Error("Solana not enabled for this provider");
|
|
229
369
|
}
|
|
230
370
|
if (!this._solanaChain) {
|
|
231
|
-
|
|
371
|
+
throw new Error("Solana chain not initialized");
|
|
232
372
|
}
|
|
233
373
|
return this._solanaChain;
|
|
234
374
|
}
|
|
@@ -236,11 +376,11 @@ var InjectedProvider = class {
|
|
|
236
376
|
* Access to Ethereum chain operations
|
|
237
377
|
*/
|
|
238
378
|
get ethereum() {
|
|
239
|
-
if (!this.addressTypes.includes(
|
|
379
|
+
if (!this.addressTypes.includes(AddressType3.ethereum)) {
|
|
240
380
|
throw new Error("Ethereum not enabled for this provider");
|
|
241
381
|
}
|
|
242
382
|
if (!this._ethereumChain) {
|
|
243
|
-
|
|
383
|
+
throw new Error("Ethereum chain not initialized");
|
|
244
384
|
}
|
|
245
385
|
return this._ethereumChain;
|
|
246
386
|
}
|
|
@@ -266,28 +406,28 @@ var InjectedProvider = class {
|
|
|
266
406
|
}
|
|
267
407
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Phantom extension detected");
|
|
268
408
|
const connectedAddresses = [];
|
|
269
|
-
if (this.addressTypes.includes(
|
|
409
|
+
if (this.addressTypes.includes(AddressType3.solana)) {
|
|
270
410
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
|
|
271
411
|
try {
|
|
272
|
-
const
|
|
273
|
-
if (
|
|
412
|
+
const publicKey = await this.phantom.solana.connect();
|
|
413
|
+
if (publicKey) {
|
|
274
414
|
connectedAddresses.push({
|
|
275
|
-
addressType:
|
|
276
|
-
address:
|
|
415
|
+
addressType: AddressType3.solana,
|
|
416
|
+
address: publicKey
|
|
277
417
|
});
|
|
278
|
-
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address:
|
|
418
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
|
|
279
419
|
}
|
|
280
420
|
} catch (err) {
|
|
281
421
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
|
|
282
422
|
}
|
|
283
423
|
}
|
|
284
|
-
if (this.addressTypes.includes(
|
|
424
|
+
if (this.addressTypes.includes(AddressType3.ethereum)) {
|
|
285
425
|
try {
|
|
286
|
-
const accounts = await this.ethereum.
|
|
426
|
+
const accounts = await this.phantom.ethereum.connect();
|
|
287
427
|
if (accounts && accounts.length > 0) {
|
|
288
428
|
connectedAddresses.push(
|
|
289
429
|
...accounts.map((address) => ({
|
|
290
|
-
addressType:
|
|
430
|
+
addressType: AddressType3.ethereum,
|
|
291
431
|
address
|
|
292
432
|
}))
|
|
293
433
|
);
|
|
@@ -329,19 +469,17 @@ var InjectedProvider = class {
|
|
|
329
469
|
}
|
|
330
470
|
async disconnect() {
|
|
331
471
|
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider disconnect");
|
|
332
|
-
if (this.addressTypes.includes(
|
|
472
|
+
if (this.addressTypes.includes(AddressType3.solana)) {
|
|
333
473
|
try {
|
|
334
|
-
await this.solana.disconnect();
|
|
474
|
+
await this.phantom.solana.disconnect();
|
|
335
475
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnected successfully");
|
|
336
476
|
} catch (err) {
|
|
337
477
|
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to disconnect Solana", { error: err });
|
|
338
478
|
}
|
|
339
479
|
}
|
|
340
|
-
if (this.addressTypes.includes(
|
|
480
|
+
if (this.addressTypes.includes(AddressType3.ethereum)) {
|
|
341
481
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnected (no-op)");
|
|
342
482
|
}
|
|
343
|
-
this._solanaChain = void 0;
|
|
344
|
-
this._ethereumChain = void 0;
|
|
345
483
|
this.browserInjectedCleanupFunctions.forEach((cleanup) => cleanup());
|
|
346
484
|
this.browserInjectedCleanupFunctions = [];
|
|
347
485
|
this.connected = false;
|
|
@@ -414,10 +552,10 @@ var InjectedProvider = class {
|
|
|
414
552
|
}
|
|
415
553
|
setupBrowserInjectedEvents() {
|
|
416
554
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up browser-injected-sdk event listeners");
|
|
417
|
-
if (this.addressTypes.includes(
|
|
555
|
+
if (this.addressTypes.includes(AddressType3.solana)) {
|
|
418
556
|
this.setupSolanaEvents();
|
|
419
557
|
}
|
|
420
|
-
if (this.addressTypes.includes(
|
|
558
|
+
if (this.addressTypes.includes(AddressType3.ethereum)) {
|
|
421
559
|
this.setupEthereumEvents();
|
|
422
560
|
}
|
|
423
561
|
}
|
|
@@ -425,8 +563,8 @@ var InjectedProvider = class {
|
|
|
425
563
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Solana event listeners");
|
|
426
564
|
const handleSolanaConnect = (publicKey) => {
|
|
427
565
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana connect event received", { publicKey });
|
|
428
|
-
const solanaAddress = { addressType:
|
|
429
|
-
if (!this.addresses.find((addr) => addr.addressType ===
|
|
566
|
+
const solanaAddress = { addressType: AddressType3.solana, address: publicKey };
|
|
567
|
+
if (!this.addresses.find((addr) => addr.addressType === AddressType3.solana)) {
|
|
430
568
|
this.addresses.push(solanaAddress);
|
|
431
569
|
}
|
|
432
570
|
this.connected = true;
|
|
@@ -437,7 +575,7 @@ var InjectedProvider = class {
|
|
|
437
575
|
};
|
|
438
576
|
const handleSolanaDisconnect = () => {
|
|
439
577
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana disconnect event received");
|
|
440
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
578
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType3.solana);
|
|
441
579
|
this.connected = this.addresses.length > 0;
|
|
442
580
|
this.emit("disconnect", {
|
|
443
581
|
source: "injected-extension"
|
|
@@ -445,11 +583,11 @@ var InjectedProvider = class {
|
|
|
445
583
|
};
|
|
446
584
|
const handleSolanaAccountChanged = (publicKey) => {
|
|
447
585
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana account changed event received", { publicKey });
|
|
448
|
-
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType ===
|
|
586
|
+
const solanaIndex = this.addresses.findIndex((addr) => addr.addressType === AddressType3.solana);
|
|
449
587
|
if (solanaIndex >= 0) {
|
|
450
|
-
this.addresses[solanaIndex] = { addressType:
|
|
588
|
+
this.addresses[solanaIndex] = { addressType: AddressType3.solana, address: publicKey };
|
|
451
589
|
} else {
|
|
452
|
-
this.addresses.push({ addressType:
|
|
590
|
+
this.addresses.push({ addressType: AddressType3.solana, address: publicKey });
|
|
453
591
|
}
|
|
454
592
|
this.emit("connect", {
|
|
455
593
|
addresses: this.addresses,
|
|
@@ -458,23 +596,24 @@ var InjectedProvider = class {
|
|
|
458
596
|
};
|
|
459
597
|
const cleanupConnect = this.phantom.solana.addEventListener("connect", handleSolanaConnect);
|
|
460
598
|
const cleanupDisconnect = this.phantom.solana.addEventListener("disconnect", handleSolanaDisconnect);
|
|
461
|
-
const cleanupAccountChanged = this.phantom.solana.addEventListener(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
cleanupDisconnect,
|
|
465
|
-
cleanupAccountChanged
|
|
599
|
+
const cleanupAccountChanged = this.phantom.solana.addEventListener(
|
|
600
|
+
"accountChanged",
|
|
601
|
+
handleSolanaAccountChanged
|
|
466
602
|
);
|
|
603
|
+
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountChanged);
|
|
467
604
|
}
|
|
468
605
|
setupEthereumEvents() {
|
|
469
606
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Setting up Ethereum event listeners");
|
|
470
607
|
const handleEthereumConnect = (accounts) => {
|
|
471
608
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum connect event received", { accounts });
|
|
472
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
609
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType3.ethereum);
|
|
473
610
|
if (accounts && accounts.length > 0) {
|
|
474
|
-
this.addresses.push(
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
611
|
+
this.addresses.push(
|
|
612
|
+
...accounts.map((address) => ({
|
|
613
|
+
addressType: AddressType3.ethereum,
|
|
614
|
+
address
|
|
615
|
+
}))
|
|
616
|
+
);
|
|
478
617
|
}
|
|
479
618
|
this.connected = this.addresses.length > 0;
|
|
480
619
|
this.emit("connect", {
|
|
@@ -484,7 +623,7 @@ var InjectedProvider = class {
|
|
|
484
623
|
};
|
|
485
624
|
const handleEthereumDisconnect = () => {
|
|
486
625
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum disconnect event received");
|
|
487
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
626
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType3.ethereum);
|
|
488
627
|
this.connected = this.addresses.length > 0;
|
|
489
628
|
this.emit("disconnect", {
|
|
490
629
|
source: "injected-extension"
|
|
@@ -492,12 +631,14 @@ var InjectedProvider = class {
|
|
|
492
631
|
};
|
|
493
632
|
const handleEthereumAccountsChanged = (accounts) => {
|
|
494
633
|
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum accounts changed event received", { accounts });
|
|
495
|
-
this.addresses = this.addresses.filter((addr) => addr.addressType !==
|
|
634
|
+
this.addresses = this.addresses.filter((addr) => addr.addressType !== AddressType3.ethereum);
|
|
496
635
|
if (accounts && accounts.length > 0) {
|
|
497
|
-
this.addresses.push(
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
636
|
+
this.addresses.push(
|
|
637
|
+
...accounts.map((address) => ({
|
|
638
|
+
addressType: AddressType3.ethereum,
|
|
639
|
+
address
|
|
640
|
+
}))
|
|
641
|
+
);
|
|
501
642
|
}
|
|
502
643
|
this.emit("connect", {
|
|
503
644
|
addresses: this.addresses,
|
|
@@ -506,12 +647,34 @@ var InjectedProvider = class {
|
|
|
506
647
|
};
|
|
507
648
|
const cleanupConnect = this.phantom.ethereum.addEventListener("connect", handleEthereumConnect);
|
|
508
649
|
const cleanupDisconnect = this.phantom.ethereum.addEventListener("disconnect", handleEthereumDisconnect);
|
|
509
|
-
const cleanupAccountsChanged = this.phantom.ethereum.addEventListener(
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
cleanupDisconnect,
|
|
513
|
-
cleanupAccountsChanged
|
|
650
|
+
const cleanupAccountsChanged = this.phantom.ethereum.addEventListener(
|
|
651
|
+
"accountsChanged",
|
|
652
|
+
handleEthereumAccountsChanged
|
|
514
653
|
);
|
|
654
|
+
this.browserInjectedCleanupFunctions.push(cleanupConnect, cleanupDisconnect, cleanupAccountsChanged);
|
|
655
|
+
}
|
|
656
|
+
createCallbacks() {
|
|
657
|
+
return {
|
|
658
|
+
connect: async () => {
|
|
659
|
+
const result = await this.connect();
|
|
660
|
+
return result.addresses;
|
|
661
|
+
},
|
|
662
|
+
disconnect: async () => {
|
|
663
|
+
await this.disconnect();
|
|
664
|
+
},
|
|
665
|
+
isConnected: () => {
|
|
666
|
+
return this.isConnected();
|
|
667
|
+
},
|
|
668
|
+
getAddresses: () => {
|
|
669
|
+
return this.getAddresses();
|
|
670
|
+
},
|
|
671
|
+
on: (event, callback) => {
|
|
672
|
+
this.on(event, callback);
|
|
673
|
+
},
|
|
674
|
+
off: (event, callback) => {
|
|
675
|
+
this.off(event, callback);
|
|
676
|
+
}
|
|
677
|
+
};
|
|
515
678
|
}
|
|
516
679
|
};
|
|
517
680
|
|
|
@@ -627,6 +790,7 @@ var BrowserAuthProvider = class {
|
|
|
627
790
|
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Starting Phantom Connect authentication", {
|
|
628
791
|
organizationId: phantomOptions.organizationId,
|
|
629
792
|
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
793
|
+
appId: phantomOptions.appId,
|
|
630
794
|
provider: phantomOptions.provider,
|
|
631
795
|
authUrl: phantomOptions.authUrl,
|
|
632
796
|
hasCustomData: !!phantomOptions.customAuthData
|
|
@@ -636,13 +800,10 @@ var BrowserAuthProvider = class {
|
|
|
636
800
|
const params = new URLSearchParams({
|
|
637
801
|
organization_id: phantomOptions.organizationId,
|
|
638
802
|
parent_organization_id: phantomOptions.parentOrganizationId,
|
|
803
|
+
app_id: phantomOptions.appId,
|
|
639
804
|
redirect_uri: phantomOptions.redirectUrl || (typeof window !== "undefined" ? window.location.href : ""),
|
|
640
805
|
session_id: phantomOptions.sessionId,
|
|
641
|
-
clear_previous_session: true.toString()
|
|
642
|
-
app_name: phantomOptions.appName || "",
|
|
643
|
-
// Optional app name
|
|
644
|
-
app_logo: phantomOptions.appLogo || ""
|
|
645
|
-
// Optional app logo URL
|
|
806
|
+
clear_previous_session: true.toString()
|
|
646
807
|
});
|
|
647
808
|
if (phantomOptions.provider) {
|
|
648
809
|
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
|
|
@@ -660,6 +821,7 @@ var BrowserAuthProvider = class {
|
|
|
660
821
|
const authContext = {
|
|
661
822
|
organizationId: phantomOptions.organizationId,
|
|
662
823
|
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
824
|
+
appId: phantomOptions.appId,
|
|
663
825
|
provider: phantomOptions.provider,
|
|
664
826
|
sessionId: phantomOptions.sessionId
|
|
665
827
|
};
|
|
@@ -1057,7 +1219,13 @@ var ProviderManager = class {
|
|
|
1057
1219
|
return;
|
|
1058
1220
|
}
|
|
1059
1221
|
debug.log(DebugCategory.PROVIDER_MANAGER, "Setting up event forwarding from current provider");
|
|
1060
|
-
const eventsToForward = [
|
|
1222
|
+
const eventsToForward = [
|
|
1223
|
+
"connect_start",
|
|
1224
|
+
"connect",
|
|
1225
|
+
"connect_error",
|
|
1226
|
+
"disconnect",
|
|
1227
|
+
"error"
|
|
1228
|
+
];
|
|
1061
1229
|
for (const event of eventsToForward) {
|
|
1062
1230
|
const forwardingCallback = (data) => {
|
|
1063
1231
|
debug.log(DebugCategory.PROVIDER_MANAGER, "Forwarding event from provider", { event, data });
|
|
@@ -1091,19 +1259,17 @@ var ProviderManager = class {
|
|
|
1091
1259
|
addressTypes: this.config.addressTypes
|
|
1092
1260
|
});
|
|
1093
1261
|
} else {
|
|
1094
|
-
if (!this.config.apiBaseUrl || !this.config.
|
|
1095
|
-
throw new Error("apiBaseUrl and
|
|
1262
|
+
if (!this.config.apiBaseUrl || !this.config.appId) {
|
|
1263
|
+
throw new Error("apiBaseUrl and appId are required for embedded provider");
|
|
1096
1264
|
}
|
|
1097
1265
|
provider = new EmbeddedProvider({
|
|
1098
1266
|
apiBaseUrl: this.config.apiBaseUrl,
|
|
1099
|
-
organizationId: this.config.
|
|
1267
|
+
organizationId: this.config.appId,
|
|
1268
|
+
appId: this.config.appId,
|
|
1100
1269
|
authOptions: this.config.authOptions,
|
|
1101
1270
|
embeddedWalletType: embeddedWalletType || "app-wallet",
|
|
1102
1271
|
addressTypes: this.config.addressTypes,
|
|
1103
|
-
solanaProvider: this.config.solanaProvider || "web3js"
|
|
1104
|
-
appLogo: this.config.appLogo,
|
|
1105
|
-
// Optional app logo URL
|
|
1106
|
-
appName: this.config.appName
|
|
1272
|
+
solanaProvider: this.config.solanaProvider || "web3js"
|
|
1107
1273
|
});
|
|
1108
1274
|
}
|
|
1109
1275
|
this.providers.set(key, provider);
|
|
@@ -1150,8 +1316,32 @@ var ProviderManager = class {
|
|
|
1150
1316
|
}*/
|
|
1151
1317
|
};
|
|
1152
1318
|
|
|
1153
|
-
// src/
|
|
1319
|
+
// src/waitForPhantomExtension.ts
|
|
1154
1320
|
import { isPhantomExtensionInstalled } from "@phantom/browser-injected-sdk";
|
|
1321
|
+
async function waitForPhantomExtension(timeoutMs = 3e3) {
|
|
1322
|
+
return new Promise((resolve) => {
|
|
1323
|
+
const startTime = Date.now();
|
|
1324
|
+
const checkInterval = 100;
|
|
1325
|
+
const checkForExtension = () => {
|
|
1326
|
+
try {
|
|
1327
|
+
if (isPhantomExtensionInstalled()) {
|
|
1328
|
+
resolve(true);
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
} catch (error) {
|
|
1332
|
+
}
|
|
1333
|
+
const elapsed = Date.now() - startTime;
|
|
1334
|
+
if (elapsed >= timeoutMs) {
|
|
1335
|
+
resolve(false);
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
setTimeout(checkForExtension, checkInterval);
|
|
1339
|
+
};
|
|
1340
|
+
checkForExtension();
|
|
1341
|
+
});
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// src/BrowserSDK.ts
|
|
1155
1345
|
var BrowserSDK = class {
|
|
1156
1346
|
constructor(config) {
|
|
1157
1347
|
debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
|
|
@@ -1272,8 +1462,8 @@ var BrowserSDK = class {
|
|
|
1272
1462
|
/**
|
|
1273
1463
|
* Check if Phantom extension is installed
|
|
1274
1464
|
*/
|
|
1275
|
-
static isPhantomInstalled() {
|
|
1276
|
-
return
|
|
1465
|
+
static async isPhantomInstalled(timeoutMs) {
|
|
1466
|
+
return waitForPhantomExtension(timeoutMs);
|
|
1277
1467
|
}
|
|
1278
1468
|
/**
|
|
1279
1469
|
* Add event listener for provider events (connect, connect_start, connect_error, disconnect, error)
|
|
@@ -1440,29 +1630,32 @@ var BrowserSDK = class {
|
|
|
1440
1630
|
debug.info(DebugCategory.BROWSER_SDK, "Got supported auto-confirm chains", { result });
|
|
1441
1631
|
return result;
|
|
1442
1632
|
} catch (error) {
|
|
1443
|
-
debug.error(DebugCategory.BROWSER_SDK, "Failed to get supported auto-confirm chains", {
|
|
1633
|
+
debug.error(DebugCategory.BROWSER_SDK, "Failed to get supported auto-confirm chains", {
|
|
1634
|
+
error: error.message
|
|
1635
|
+
});
|
|
1444
1636
|
throw error;
|
|
1445
1637
|
}
|
|
1446
1638
|
}
|
|
1447
1639
|
};
|
|
1448
1640
|
|
|
1449
1641
|
// src/types.ts
|
|
1450
|
-
import { AddressType as
|
|
1642
|
+
import { AddressType as AddressType4 } from "@phantom/client";
|
|
1451
1643
|
|
|
1452
1644
|
// src/index.ts
|
|
1453
|
-
import { NetworkId
|
|
1454
|
-
import { AddressType as
|
|
1645
|
+
import { NetworkId } from "@phantom/constants";
|
|
1646
|
+
import { AddressType as AddressType5 } from "@phantom/client";
|
|
1455
1647
|
export {
|
|
1456
|
-
|
|
1648
|
+
AddressType5 as AddressType,
|
|
1457
1649
|
BrowserSDK,
|
|
1458
1650
|
DEFAULT_AUTH_URL,
|
|
1459
1651
|
DEFAULT_WALLET_API_URL,
|
|
1460
1652
|
DebugCategory,
|
|
1461
1653
|
DebugLevel,
|
|
1462
|
-
|
|
1654
|
+
NetworkId,
|
|
1463
1655
|
debug,
|
|
1464
1656
|
detectBrowser,
|
|
1465
1657
|
getBrowserDisplayName,
|
|
1466
1658
|
getPlatformName,
|
|
1467
|
-
parseBrowserFromUserAgent
|
|
1659
|
+
parseBrowserFromUserAgent,
|
|
1660
|
+
waitForPhantomExtension
|
|
1468
1661
|
};
|