@phantom/browser-sdk 0.2.1 → 0.2.3
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 +60 -1
- package/dist/index.d.ts +66 -23
- package/dist/index.js +349 -118
- package/dist/index.mjs +347 -116
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -3,26 +3,118 @@ import { AddressType } from "@phantom/client";
|
|
|
3
3
|
import { createPhantom, createExtensionPlugin } from "@phantom/browser-injected-sdk";
|
|
4
4
|
import { createSolanaPlugin } from "@phantom/browser-injected-sdk/solana";
|
|
5
5
|
import { createEthereumPlugin } from "@phantom/browser-injected-sdk/ethereum";
|
|
6
|
+
|
|
7
|
+
// src/debug.ts
|
|
8
|
+
var DebugLevel = /* @__PURE__ */ ((DebugLevel2) => {
|
|
9
|
+
DebugLevel2[DebugLevel2["ERROR"] = 0] = "ERROR";
|
|
10
|
+
DebugLevel2[DebugLevel2["WARN"] = 1] = "WARN";
|
|
11
|
+
DebugLevel2[DebugLevel2["INFO"] = 2] = "INFO";
|
|
12
|
+
DebugLevel2[DebugLevel2["DEBUG"] = 3] = "DEBUG";
|
|
13
|
+
return DebugLevel2;
|
|
14
|
+
})(DebugLevel || {});
|
|
15
|
+
var Debug = class {
|
|
16
|
+
constructor() {
|
|
17
|
+
this.level = 0 /* ERROR */;
|
|
18
|
+
this.enabled = false;
|
|
19
|
+
}
|
|
20
|
+
static getInstance() {
|
|
21
|
+
if (!Debug.instance) {
|
|
22
|
+
Debug.instance = new Debug();
|
|
23
|
+
}
|
|
24
|
+
return Debug.instance;
|
|
25
|
+
}
|
|
26
|
+
setCallback(callback) {
|
|
27
|
+
this.callback = callback;
|
|
28
|
+
}
|
|
29
|
+
setLevel(level) {
|
|
30
|
+
this.level = level;
|
|
31
|
+
}
|
|
32
|
+
enable() {
|
|
33
|
+
this.enabled = true;
|
|
34
|
+
}
|
|
35
|
+
disable() {
|
|
36
|
+
this.enabled = false;
|
|
37
|
+
}
|
|
38
|
+
writeLog(level, category, message, data) {
|
|
39
|
+
if (!this.enabled || level > this.level) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const debugMessage = {
|
|
43
|
+
timestamp: Date.now(),
|
|
44
|
+
level,
|
|
45
|
+
category,
|
|
46
|
+
message,
|
|
47
|
+
data
|
|
48
|
+
};
|
|
49
|
+
if (this.callback) {
|
|
50
|
+
this.callback(debugMessage);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
error(category, message, data) {
|
|
54
|
+
this.writeLog(0 /* ERROR */, category, message, data);
|
|
55
|
+
}
|
|
56
|
+
warn(category, message, data) {
|
|
57
|
+
this.writeLog(1 /* WARN */, category, message, data);
|
|
58
|
+
}
|
|
59
|
+
info(category, message, data) {
|
|
60
|
+
this.writeLog(2 /* INFO */, category, message, data);
|
|
61
|
+
}
|
|
62
|
+
debug(category, message, data) {
|
|
63
|
+
this.writeLog(3 /* DEBUG */, category, message, data);
|
|
64
|
+
}
|
|
65
|
+
log(category, message, data) {
|
|
66
|
+
this.writeLog(3 /* DEBUG */, category, message, data);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var debug = Debug.getInstance();
|
|
70
|
+
var DebugCategory = {
|
|
71
|
+
BROWSER_SDK: "BrowserSDK",
|
|
72
|
+
PROVIDER_MANAGER: "ProviderManager",
|
|
73
|
+
EMBEDDED_PROVIDER: "EmbeddedProvider",
|
|
74
|
+
INJECTED_PROVIDER: "InjectedProvider",
|
|
75
|
+
PHANTOM_CONNECT_AUTH: "PhantomConnectAuth",
|
|
76
|
+
JWT_AUTH: "JWTAuth",
|
|
77
|
+
STORAGE: "Storage",
|
|
78
|
+
SESSION: "Session"
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// src/providers/injected/index.ts
|
|
6
82
|
var InjectedProvider = class {
|
|
7
83
|
constructor(config) {
|
|
8
84
|
this.connected = false;
|
|
9
85
|
this.addresses = [];
|
|
86
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Initializing InjectedProvider", { config });
|
|
10
87
|
this.addressTypes = config.addressTypes || [AddressType.solana, AddressType.ethereum];
|
|
88
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Address types configured", { addressTypes: this.addressTypes });
|
|
11
89
|
const plugins = [createExtensionPlugin()];
|
|
12
90
|
if (this.addressTypes.includes(AddressType.solana)) {
|
|
13
91
|
plugins.push(createSolanaPlugin());
|
|
92
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Solana plugin added");
|
|
14
93
|
}
|
|
15
94
|
if (this.addressTypes.includes(AddressType.ethereum)) {
|
|
16
95
|
plugins.push(createEthereumPlugin());
|
|
96
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Ethereum plugin added");
|
|
17
97
|
}
|
|
98
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Creating Phantom instance with plugins", {
|
|
99
|
+
pluginCount: plugins.length
|
|
100
|
+
});
|
|
18
101
|
this.phantom = createPhantom({ plugins });
|
|
102
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "InjectedProvider initialized");
|
|
19
103
|
}
|
|
20
|
-
async connect() {
|
|
104
|
+
async connect(authOptions) {
|
|
105
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Starting injected provider connect", {
|
|
106
|
+
addressTypes: this.addressTypes,
|
|
107
|
+
authOptionsIgnored: !!authOptions
|
|
108
|
+
// Note: authOptions are ignored for injected provider
|
|
109
|
+
});
|
|
21
110
|
if (!this.phantom.extension.isInstalled()) {
|
|
111
|
+
debug.error(DebugCategory.INJECTED_PROVIDER, "Phantom wallet extension not found");
|
|
22
112
|
throw new Error("Phantom wallet not found");
|
|
23
113
|
}
|
|
114
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Phantom extension detected");
|
|
24
115
|
const connectedAddresses = [];
|
|
25
116
|
if (this.addressTypes.includes(AddressType.solana)) {
|
|
117
|
+
debug.log(DebugCategory.INJECTED_PROVIDER, "Attempting Solana connection");
|
|
26
118
|
try {
|
|
27
119
|
const publicKey = await this.phantom.solana.connect();
|
|
28
120
|
if (publicKey) {
|
|
@@ -30,9 +122,10 @@ var InjectedProvider = class {
|
|
|
30
122
|
addressType: AddressType.solana,
|
|
31
123
|
address: publicKey
|
|
32
124
|
});
|
|
125
|
+
debug.info(DebugCategory.INJECTED_PROVIDER, "Solana connected successfully", { address: publicKey });
|
|
33
126
|
}
|
|
34
127
|
} catch (err) {
|
|
35
|
-
|
|
128
|
+
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Solana", { error: err });
|
|
36
129
|
}
|
|
37
130
|
}
|
|
38
131
|
if (this.addressTypes.includes(AddressType.ethereum)) {
|
|
@@ -47,7 +140,7 @@ var InjectedProvider = class {
|
|
|
47
140
|
);
|
|
48
141
|
}
|
|
49
142
|
} catch (err) {
|
|
50
|
-
|
|
143
|
+
debug.warn(DebugCategory.INJECTED_PROVIDER, "Failed to connect Ethereum", { error: err });
|
|
51
144
|
}
|
|
52
145
|
}
|
|
53
146
|
if (connectedAddresses.length === 0) {
|
|
@@ -56,7 +149,8 @@ var InjectedProvider = class {
|
|
|
56
149
|
this.addresses = connectedAddresses;
|
|
57
150
|
this.connected = true;
|
|
58
151
|
return {
|
|
59
|
-
addresses: this.addresses
|
|
152
|
+
addresses: this.addresses,
|
|
153
|
+
status: "completed"
|
|
60
154
|
// walletId is not applicable for injected providers
|
|
61
155
|
};
|
|
62
156
|
}
|
|
@@ -142,11 +236,10 @@ var InjectedProvider = class {
|
|
|
142
236
|
};
|
|
143
237
|
|
|
144
238
|
// src/providers/embedded/index.ts
|
|
145
|
-
import {
|
|
146
|
-
import { ApiKeyStamper } from "@phantom/api-key-stamper";
|
|
239
|
+
import { EmbeddedProvider as CoreEmbeddedProvider } from "@phantom/embedded-provider-core";
|
|
147
240
|
|
|
148
|
-
// src/providers/embedded/storage.ts
|
|
149
|
-
var
|
|
241
|
+
// src/providers/embedded/adapters/storage.ts
|
|
242
|
+
var BrowserStorage = class {
|
|
150
243
|
constructor() {
|
|
151
244
|
this.dbName = "phantom-browser-sdk";
|
|
152
245
|
this.storeName = "sessions";
|
|
@@ -166,149 +259,222 @@ var IndexedDBStorage = class {
|
|
|
166
259
|
});
|
|
167
260
|
}
|
|
168
261
|
async getSession() {
|
|
262
|
+
debug.log(DebugCategory.STORAGE, "Getting session from IndexedDB");
|
|
169
263
|
const db = await this.getDB();
|
|
170
264
|
return new Promise((resolve, reject) => {
|
|
171
265
|
const transaction = db.transaction([this.storeName], "readonly");
|
|
172
266
|
const store = transaction.objectStore(this.storeName);
|
|
173
267
|
const request = store.get("currentSession");
|
|
174
|
-
request.onsuccess = () =>
|
|
175
|
-
|
|
268
|
+
request.onsuccess = () => {
|
|
269
|
+
const session = request.result || null;
|
|
270
|
+
debug.log(DebugCategory.STORAGE, "Retrieved session from IndexedDB", {
|
|
271
|
+
hasSession: !!session,
|
|
272
|
+
sessionId: session?.sessionId
|
|
273
|
+
});
|
|
274
|
+
resolve(session);
|
|
275
|
+
};
|
|
276
|
+
request.onerror = () => {
|
|
277
|
+
debug.error(DebugCategory.STORAGE, "Failed to get session from IndexedDB", { error: request.error });
|
|
278
|
+
reject(request.error);
|
|
279
|
+
};
|
|
176
280
|
});
|
|
177
281
|
}
|
|
178
282
|
async saveSession(session) {
|
|
283
|
+
debug.log(DebugCategory.STORAGE, "Saving session to IndexedDB", {
|
|
284
|
+
sessionId: session.sessionId,
|
|
285
|
+
walletId: session.walletId,
|
|
286
|
+
status: session.status
|
|
287
|
+
});
|
|
179
288
|
const db = await this.getDB();
|
|
180
289
|
return new Promise((resolve, reject) => {
|
|
181
290
|
const transaction = db.transaction([this.storeName], "readwrite");
|
|
182
291
|
const store = transaction.objectStore(this.storeName);
|
|
183
292
|
const request = store.put(session, "currentSession");
|
|
184
|
-
request.onsuccess = () =>
|
|
185
|
-
|
|
293
|
+
request.onsuccess = () => {
|
|
294
|
+
debug.log(DebugCategory.STORAGE, "Successfully saved session to IndexedDB");
|
|
295
|
+
resolve();
|
|
296
|
+
};
|
|
297
|
+
request.onerror = () => {
|
|
298
|
+
debug.error(DebugCategory.STORAGE, "Failed to save session to IndexedDB", { error: request.error });
|
|
299
|
+
reject(request.error);
|
|
300
|
+
};
|
|
186
301
|
});
|
|
187
302
|
}
|
|
188
303
|
async clearSession() {
|
|
304
|
+
debug.log(DebugCategory.STORAGE, "Clearing session from IndexedDB");
|
|
189
305
|
const db = await this.getDB();
|
|
190
306
|
return new Promise((resolve, reject) => {
|
|
191
307
|
const transaction = db.transaction([this.storeName], "readwrite");
|
|
192
308
|
const store = transaction.objectStore(this.storeName);
|
|
193
309
|
const request = store.delete("currentSession");
|
|
194
|
-
request.onsuccess = () =>
|
|
195
|
-
|
|
310
|
+
request.onsuccess = () => {
|
|
311
|
+
debug.log(DebugCategory.STORAGE, "Successfully cleared session from IndexedDB");
|
|
312
|
+
resolve();
|
|
313
|
+
};
|
|
314
|
+
request.onerror = () => {
|
|
315
|
+
debug.error(DebugCategory.STORAGE, "Failed to clear session from IndexedDB", { error: request.error });
|
|
316
|
+
reject(request.error);
|
|
317
|
+
};
|
|
196
318
|
});
|
|
197
319
|
}
|
|
198
320
|
};
|
|
199
321
|
|
|
200
|
-
// src/providers/embedded/
|
|
201
|
-
var
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return
|
|
205
|
-
walletId: `wallet-${Date.now()}`
|
|
206
|
-
};
|
|
322
|
+
// src/providers/embedded/adapters/url-params.ts
|
|
323
|
+
var BrowserURLParamsAccessor = class {
|
|
324
|
+
getParam(key) {
|
|
325
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
326
|
+
return urlParams.get(key);
|
|
207
327
|
}
|
|
208
328
|
};
|
|
329
|
+
var browserUrlParamsAccessor = new BrowserURLParamsAccessor();
|
|
209
330
|
|
|
210
|
-
// src/
|
|
211
|
-
|
|
212
|
-
var
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
this.
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
331
|
+
// src/constants.ts
|
|
332
|
+
var DEFAULT_AUTH_URL = "https://connect.phantom.app";
|
|
333
|
+
var DEFAULT_WALLET_API_URL = "https://api.phantom.app/v1/wallets";
|
|
334
|
+
|
|
335
|
+
// src/providers/embedded/adapters/auth.ts
|
|
336
|
+
var BrowserAuthProvider = class {
|
|
337
|
+
constructor(urlParamsAccessor) {
|
|
338
|
+
this.urlParamsAccessor = urlParamsAccessor;
|
|
339
|
+
}
|
|
340
|
+
authenticate(options) {
|
|
341
|
+
return new Promise((resolve) => {
|
|
342
|
+
if ("jwtToken" in options) {
|
|
343
|
+
throw new Error("JWT authentication should be handled by the core JWTAuth class");
|
|
344
|
+
}
|
|
345
|
+
const phantomOptions = options;
|
|
346
|
+
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Starting Phantom Connect authentication", {
|
|
347
|
+
organizationId: phantomOptions.organizationId,
|
|
348
|
+
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
349
|
+
provider: phantomOptions.provider,
|
|
350
|
+
authUrl: phantomOptions.authUrl,
|
|
351
|
+
hasCustomData: !!phantomOptions.customAuthData
|
|
227
352
|
});
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const authResult = await auth.authenticate({
|
|
241
|
-
iframeUrl: this.config.authUrl || "https://auth-flow.phantom.app",
|
|
242
|
-
organizationId,
|
|
243
|
-
parentOrganizationId: this.config.organizationId,
|
|
244
|
-
embeddedWalletType: this.config.embeddedWalletType
|
|
353
|
+
const baseUrl = phantomOptions.authUrl || DEFAULT_AUTH_URL;
|
|
354
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Using auth URL", { baseUrl });
|
|
355
|
+
const params = new URLSearchParams({
|
|
356
|
+
organization_id: phantomOptions.organizationId,
|
|
357
|
+
parent_organization_id: phantomOptions.parentOrganizationId,
|
|
358
|
+
redirect_uri: phantomOptions.redirectUrl || (typeof window !== "undefined" ? window.location.href : ""),
|
|
359
|
+
session_id: phantomOptions.sessionId,
|
|
360
|
+
clear_previous_session: true.toString()
|
|
361
|
+
});
|
|
362
|
+
if (phantomOptions.provider) {
|
|
363
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Provider specified, will skip selection", {
|
|
364
|
+
provider: phantomOptions.provider
|
|
245
365
|
});
|
|
246
|
-
|
|
366
|
+
params.append("provider", phantomOptions.provider);
|
|
247
367
|
} else {
|
|
248
|
-
|
|
249
|
-
|
|
368
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "No provider specified, defaulting to Google");
|
|
369
|
+
params.append("provider", "google");
|
|
370
|
+
}
|
|
371
|
+
if (phantomOptions.customAuthData) {
|
|
372
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Adding custom auth data");
|
|
373
|
+
params.append("authData", JSON.stringify(phantomOptions.customAuthData));
|
|
250
374
|
}
|
|
251
|
-
|
|
375
|
+
const authContext = {
|
|
376
|
+
organizationId: phantomOptions.organizationId,
|
|
377
|
+
parentOrganizationId: phantomOptions.parentOrganizationId,
|
|
378
|
+
provider: phantomOptions.provider,
|
|
379
|
+
sessionId: phantomOptions.sessionId
|
|
380
|
+
};
|
|
381
|
+
sessionStorage.setItem("phantom-auth-context", JSON.stringify(authContext));
|
|
382
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Stored auth context in session storage", { authContext });
|
|
383
|
+
const authUrl = `${baseUrl}?${params.toString()}`;
|
|
384
|
+
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Redirecting to Phantom Connect", { authUrl });
|
|
385
|
+
window.location.href = authUrl;
|
|
386
|
+
resolve();
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
resumeAuthFromRedirect() {
|
|
390
|
+
try {
|
|
391
|
+
const walletId = this.urlParamsAccessor.getParam("wallet_id");
|
|
392
|
+
const sessionId = this.urlParamsAccessor.getParam("session_id");
|
|
393
|
+
const error = this.urlParamsAccessor.getParam("error");
|
|
394
|
+
const errorDescription = this.urlParamsAccessor.getParam("error_description");
|
|
395
|
+
if (error) {
|
|
396
|
+
const errorMsg = errorDescription || error;
|
|
397
|
+
switch (error) {
|
|
398
|
+
case "access_denied":
|
|
399
|
+
throw new Error(`Authentication cancelled: ${errorMsg}`);
|
|
400
|
+
case "invalid_request":
|
|
401
|
+
throw new Error(`Invalid authentication request: ${errorMsg}`);
|
|
402
|
+
case "server_error":
|
|
403
|
+
throw new Error(`Authentication server error: ${errorMsg}`);
|
|
404
|
+
case "temporarily_unavailable":
|
|
405
|
+
throw new Error(`Authentication service temporarily unavailable: ${errorMsg}`);
|
|
406
|
+
default:
|
|
407
|
+
throw new Error(`Authentication failed: ${errorMsg}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (!walletId || !sessionId) {
|
|
411
|
+
debug.log(DebugCategory.PHANTOM_CONNECT_AUTH, "Missing auth parameters in URL", {
|
|
412
|
+
hasWalletId: !!walletId,
|
|
413
|
+
hasSessionId: !!sessionId
|
|
414
|
+
});
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
const contextStr = sessionStorage.getItem("phantom-auth-context");
|
|
418
|
+
let context = {};
|
|
419
|
+
if (contextStr) {
|
|
420
|
+
try {
|
|
421
|
+
context = JSON.parse(contextStr);
|
|
422
|
+
} catch (parseError) {
|
|
423
|
+
debug.warn(DebugCategory.PHANTOM_CONNECT_AUTH, "Failed to parse stored auth context", { error: parseError });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (context.sessionId && sessionId !== context.sessionId) {
|
|
427
|
+
debug.error(DebugCategory.PHANTOM_CONNECT_AUTH, "Session ID mismatch", {
|
|
428
|
+
urlSessionId: sessionId,
|
|
429
|
+
storedSessionId: context.sessionId
|
|
430
|
+
});
|
|
431
|
+
throw new Error("Session ID mismatch - possible session corruption or replay attack");
|
|
432
|
+
}
|
|
433
|
+
sessionStorage.removeItem("phantom-auth-context");
|
|
434
|
+
debug.info(DebugCategory.PHANTOM_CONNECT_AUTH, "Successfully resumed auth from redirect", {
|
|
252
435
|
walletId,
|
|
253
|
-
|
|
254
|
-
|
|
436
|
+
sessionId
|
|
437
|
+
});
|
|
438
|
+
return {
|
|
439
|
+
walletId,
|
|
440
|
+
userInfo: context
|
|
255
441
|
};
|
|
256
|
-
|
|
442
|
+
} catch (error) {
|
|
443
|
+
sessionStorage.removeItem("phantom-auth-context");
|
|
444
|
+
throw error;
|
|
257
445
|
}
|
|
258
|
-
const stamper = new ApiKeyStamper({
|
|
259
|
-
apiSecretKey: session.keypair.secretKey
|
|
260
|
-
});
|
|
261
|
-
this.client = new PhantomClient(
|
|
262
|
-
{
|
|
263
|
-
apiBaseUrl: this.config.apiBaseUrl,
|
|
264
|
-
organizationId: session.organizationId
|
|
265
|
-
},
|
|
266
|
-
stamper
|
|
267
|
-
);
|
|
268
|
-
this.walletId = session.walletId;
|
|
269
|
-
const addresses = await this.client.getWalletAddresses(session.walletId);
|
|
270
|
-
this.addresses = addresses.filter((addr) => this.config.addressTypes.some((type) => type === addr.addressType)).map((addr) => ({
|
|
271
|
-
addressType: addr.addressType,
|
|
272
|
-
address: addr.address
|
|
273
|
-
}));
|
|
274
|
-
return {
|
|
275
|
-
walletId: this.walletId,
|
|
276
|
-
addresses: this.addresses
|
|
277
|
-
};
|
|
278
446
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
// src/providers/embedded/adapters/logger.ts
|
|
450
|
+
var BrowserLogger = class {
|
|
451
|
+
info(category, message, data) {
|
|
452
|
+
debug.info(category, message, data);
|
|
284
453
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
throw new Error("Not connected");
|
|
288
|
-
}
|
|
289
|
-
const parsedMessage = parseMessage(params.message);
|
|
290
|
-
return await this.client.signMessage({
|
|
291
|
-
walletId: this.walletId,
|
|
292
|
-
message: parsedMessage.base64url,
|
|
293
|
-
networkId: params.networkId
|
|
294
|
-
});
|
|
454
|
+
warn(category, message, data) {
|
|
455
|
+
debug.warn(category, message, data);
|
|
295
456
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
throw new Error("Not connected");
|
|
299
|
-
}
|
|
300
|
-
const parsedTransaction = await parseTransaction(params.transaction, params.networkId);
|
|
301
|
-
return await this.client.signAndSendTransaction({
|
|
302
|
-
walletId: this.walletId,
|
|
303
|
-
transaction: parsedTransaction.base64url,
|
|
304
|
-
networkId: params.networkId
|
|
305
|
-
});
|
|
457
|
+
error(category, message, data) {
|
|
458
|
+
debug.error(category, message, data);
|
|
306
459
|
}
|
|
307
|
-
|
|
308
|
-
|
|
460
|
+
log(category, message, data) {
|
|
461
|
+
debug.log(category, message, data);
|
|
309
462
|
}
|
|
310
|
-
|
|
311
|
-
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
// src/providers/embedded/index.ts
|
|
466
|
+
var EmbeddedProvider = class extends CoreEmbeddedProvider {
|
|
467
|
+
constructor(config) {
|
|
468
|
+
debug.log(DebugCategory.EMBEDDED_PROVIDER, "Initializing Browser EmbeddedProvider", { config });
|
|
469
|
+
const urlParamsAccessor = new BrowserURLParamsAccessor();
|
|
470
|
+
const platform = {
|
|
471
|
+
storage: new BrowserStorage(),
|
|
472
|
+
authProvider: new BrowserAuthProvider(urlParamsAccessor),
|
|
473
|
+
urlParamsAccessor
|
|
474
|
+
};
|
|
475
|
+
const logger = new BrowserLogger();
|
|
476
|
+
super(config, platform, logger);
|
|
477
|
+
debug.info(DebugCategory.EMBEDDED_PROVIDER, "Browser EmbeddedProvider initialized");
|
|
312
478
|
}
|
|
313
479
|
};
|
|
314
480
|
|
|
@@ -319,8 +485,13 @@ var ProviderManager = class {
|
|
|
319
485
|
this.currentProvider = null;
|
|
320
486
|
this.currentProviderKey = null;
|
|
321
487
|
this.walletId = null;
|
|
488
|
+
debug.log(DebugCategory.PROVIDER_MANAGER, "Initializing ProviderManager", { config });
|
|
322
489
|
this.config = config;
|
|
490
|
+
debug.log(DebugCategory.PROVIDER_MANAGER, "Setting default provider");
|
|
323
491
|
this.setDefaultProvider();
|
|
492
|
+
debug.info(DebugCategory.PROVIDER_MANAGER, "ProviderManager initialized", {
|
|
493
|
+
currentProviderKey: this.currentProviderKey
|
|
494
|
+
});
|
|
324
495
|
}
|
|
325
496
|
/**
|
|
326
497
|
* Switch to a different provider type
|
|
@@ -361,13 +532,27 @@ var ProviderManager = class {
|
|
|
361
532
|
/**
|
|
362
533
|
* Connect using the current provider
|
|
363
534
|
*/
|
|
364
|
-
async connect() {
|
|
535
|
+
async connect(authOptions) {
|
|
536
|
+
debug.info(DebugCategory.PROVIDER_MANAGER, "Starting connection", {
|
|
537
|
+
currentProviderKey: this.currentProviderKey,
|
|
538
|
+
authOptions: authOptions ? { provider: authOptions.provider, hasJwtToken: !!authOptions.jwtToken } : void 0
|
|
539
|
+
});
|
|
365
540
|
if (!this.currentProvider) {
|
|
541
|
+
debug.error(DebugCategory.PROVIDER_MANAGER, "No provider selected");
|
|
366
542
|
throw new Error("No provider selected");
|
|
367
543
|
}
|
|
368
|
-
|
|
544
|
+
debug.log(DebugCategory.PROVIDER_MANAGER, "Delegating to provider connect method");
|
|
545
|
+
const result = await this.currentProvider.connect(authOptions);
|
|
369
546
|
this.walletId = result.walletId || null;
|
|
547
|
+
debug.log(DebugCategory.PROVIDER_MANAGER, "Connection successful, saving preferences", {
|
|
548
|
+
walletId: this.walletId,
|
|
549
|
+
addressCount: result.addresses?.length || 0
|
|
550
|
+
});
|
|
370
551
|
this.saveProviderPreference();
|
|
552
|
+
debug.info(DebugCategory.PROVIDER_MANAGER, "Connect completed", {
|
|
553
|
+
walletId: this.walletId,
|
|
554
|
+
addresses: result.addresses
|
|
555
|
+
});
|
|
371
556
|
return result;
|
|
372
557
|
}
|
|
373
558
|
/**
|
|
@@ -447,7 +632,7 @@ var ProviderManager = class {
|
|
|
447
632
|
provider = new EmbeddedProvider({
|
|
448
633
|
apiBaseUrl: this.config.apiBaseUrl,
|
|
449
634
|
organizationId: this.config.organizationId,
|
|
450
|
-
|
|
635
|
+
authOptions: this.config.authOptions,
|
|
451
636
|
embeddedWalletType: embeddedWalletType || "app-wallet",
|
|
452
637
|
addressTypes: this.config.addressTypes || [],
|
|
453
638
|
solanaProvider: this.config.solanaProvider || "web3js"
|
|
@@ -501,37 +686,78 @@ var ProviderManager = class {
|
|
|
501
686
|
import { isPhantomExtensionInstalled } from "@phantom/browser-injected-sdk";
|
|
502
687
|
var BrowserSDK = class {
|
|
503
688
|
constructor(config) {
|
|
689
|
+
if (config.debug?.enabled) {
|
|
690
|
+
debug.enable();
|
|
691
|
+
if (config.debug.level !== void 0) {
|
|
692
|
+
debug.setLevel(config.debug.level);
|
|
693
|
+
}
|
|
694
|
+
if (config.debug.callback) {
|
|
695
|
+
debug.setCallback(config.debug.callback);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
debug.info(DebugCategory.BROWSER_SDK, "Initializing BrowserSDK", {
|
|
699
|
+
providerType: config.providerType,
|
|
700
|
+
embeddedWalletType: config.embeddedWalletType,
|
|
701
|
+
addressTypes: config.addressTypes,
|
|
702
|
+
debugEnabled: config.debug?.enabled
|
|
703
|
+
});
|
|
504
704
|
if (!["injected", "embedded"].includes(config.providerType)) {
|
|
705
|
+
debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType", { providerType: config.providerType });
|
|
505
706
|
throw new Error(`Invalid providerType: ${config.providerType}. Must be "injected" or "embedded".`);
|
|
506
707
|
}
|
|
507
708
|
const embeddedWalletType = config.embeddedWalletType || "app-wallet";
|
|
508
709
|
if (config.providerType === "embedded" && !["app-wallet", "user-wallet"].includes(embeddedWalletType)) {
|
|
710
|
+
debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType", {
|
|
711
|
+
embeddedWalletType: config.embeddedWalletType
|
|
712
|
+
});
|
|
509
713
|
throw new Error(
|
|
510
714
|
`Invalid embeddedWalletType: ${config.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
|
|
511
715
|
);
|
|
512
716
|
}
|
|
513
717
|
config.embeddedWalletType = embeddedWalletType;
|
|
514
718
|
this.config = config;
|
|
719
|
+
debug.log(DebugCategory.BROWSER_SDK, "Creating ProviderManager", { config });
|
|
515
720
|
this.providerManager = new ProviderManager(config);
|
|
721
|
+
debug.info(DebugCategory.BROWSER_SDK, "BrowserSDK initialized successfully");
|
|
516
722
|
}
|
|
517
723
|
/**
|
|
518
724
|
* Connect to the wallet with optional provider switching
|
|
519
725
|
*/
|
|
520
726
|
async connect(options) {
|
|
727
|
+
debug.info(DebugCategory.BROWSER_SDK, "Starting connect process", { options });
|
|
521
728
|
if (options?.providerType) {
|
|
729
|
+
debug.log(DebugCategory.BROWSER_SDK, "Provider switch requested", {
|
|
730
|
+
providerType: options.providerType,
|
|
731
|
+
embeddedWalletType: options.embeddedWalletType
|
|
732
|
+
});
|
|
522
733
|
if (!["injected", "embedded"].includes(options.providerType)) {
|
|
734
|
+
debug.error(DebugCategory.BROWSER_SDK, "Invalid providerType in connect options", {
|
|
735
|
+
providerType: options.providerType
|
|
736
|
+
});
|
|
523
737
|
throw new Error(`Invalid providerType: ${options.providerType}. Must be "injected" or "embedded".`);
|
|
524
738
|
}
|
|
525
739
|
if (options.embeddedWalletType && !["app-wallet", "user-wallet"].includes(options.embeddedWalletType)) {
|
|
740
|
+
debug.error(DebugCategory.BROWSER_SDK, "Invalid embeddedWalletType in connect options", {
|
|
741
|
+
embeddedWalletType: options.embeddedWalletType
|
|
742
|
+
});
|
|
526
743
|
throw new Error(
|
|
527
744
|
`Invalid embeddedWalletType: ${options.embeddedWalletType}. Must be "app-wallet" or "user-wallet".`
|
|
528
745
|
);
|
|
529
746
|
}
|
|
747
|
+
debug.log(DebugCategory.BROWSER_SDK, "Switching provider", {
|
|
748
|
+
providerType: options.providerType,
|
|
749
|
+
embeddedWalletType: options.embeddedWalletType
|
|
750
|
+
});
|
|
530
751
|
await this.providerManager.switchProvider(options.providerType, {
|
|
531
752
|
embeddedWalletType: options.embeddedWalletType
|
|
532
753
|
});
|
|
533
754
|
}
|
|
534
|
-
|
|
755
|
+
debug.log(DebugCategory.BROWSER_SDK, "Delegating to ProviderManager.connect", {
|
|
756
|
+
authOptions: options?.authOptions
|
|
757
|
+
});
|
|
758
|
+
const result = await this.providerManager.connect(options?.authOptions);
|
|
759
|
+
debug.info(DebugCategory.BROWSER_SDK, "Connect completed successfully", result);
|
|
760
|
+
return result;
|
|
535
761
|
}
|
|
536
762
|
/**
|
|
537
763
|
* Switch to a different provider type
|
|
@@ -643,5 +869,10 @@ import { NetworkId, AddressType as AddressType2 } from "@phantom/client";
|
|
|
643
869
|
export {
|
|
644
870
|
AddressType2 as AddressType,
|
|
645
871
|
BrowserSDK,
|
|
646
|
-
|
|
872
|
+
DEFAULT_AUTH_URL,
|
|
873
|
+
DEFAULT_WALLET_API_URL,
|
|
874
|
+
DebugCategory,
|
|
875
|
+
DebugLevel,
|
|
876
|
+
NetworkId,
|
|
877
|
+
debug
|
|
647
878
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@phantom/browser-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Browser SDK for Phantom Wallet with unified interface",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -30,8 +30,9 @@
|
|
|
30
30
|
"@phantom/api-key-stamper": "^0.1.1",
|
|
31
31
|
"@phantom/base64url": "^0.1.0",
|
|
32
32
|
"@phantom/browser-injected-sdk": "^0.0.9",
|
|
33
|
-
"@phantom/client": "^0.1.
|
|
34
|
-
"@phantom/
|
|
33
|
+
"@phantom/client": "^0.1.3",
|
|
34
|
+
"@phantom/embedded-provider-core": "^0.1.1",
|
|
35
|
+
"@phantom/parsers": "^0.0.4",
|
|
35
36
|
"axios": "^1.10.0",
|
|
36
37
|
"bs58": "^6.0.0",
|
|
37
38
|
"buffer": "^6.0.3",
|