@phantom/embedded-provider-core 0.1.2 → 0.1.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/dist/index.d.mts CHANGED
@@ -62,12 +62,16 @@ interface PhantomConnectOptions {
62
62
  customAuthData?: Record<string, any>;
63
63
  authUrl?: string;
64
64
  sessionId: string;
65
+ appName?: string;
66
+ appLogo?: string;
65
67
  }
66
68
  interface JWTAuthOptions {
67
69
  organizationId: string;
68
70
  parentOrganizationId: string;
69
71
  jwtToken: string;
70
72
  customAuthData?: Record<string, any>;
73
+ appName?: string;
74
+ appLogo?: string;
71
75
  }
72
76
  interface AuthProvider {
73
77
  authenticate(options: PhantomConnectOptions | JWTAuthOptions): Promise<void | AuthResult>;
@@ -121,9 +125,11 @@ interface EmbeddedProviderConfig {
121
125
  authUrl?: string;
122
126
  redirectUrl?: string;
123
127
  };
124
- embeddedWalletType: "app-wallet" | "user-wallet";
128
+ embeddedWalletType: "app-wallet" | "user-wallet" | (string & Record<never, never>);
125
129
  addressTypes: AddressType[];
126
- solanaProvider: "web3js" | "kit";
130
+ solanaProvider: "web3js" | "kit" | (string & Record<never, never>);
131
+ appName?: string;
132
+ appLogo?: string;
127
133
  }
128
134
 
129
135
  declare class EmbeddedProvider {
package/dist/index.d.ts CHANGED
@@ -62,12 +62,16 @@ interface PhantomConnectOptions {
62
62
  customAuthData?: Record<string, any>;
63
63
  authUrl?: string;
64
64
  sessionId: string;
65
+ appName?: string;
66
+ appLogo?: string;
65
67
  }
66
68
  interface JWTAuthOptions {
67
69
  organizationId: string;
68
70
  parentOrganizationId: string;
69
71
  jwtToken: string;
70
72
  customAuthData?: Record<string, any>;
73
+ appName?: string;
74
+ appLogo?: string;
71
75
  }
72
76
  interface AuthProvider {
73
77
  authenticate(options: PhantomConnectOptions | JWTAuthOptions): Promise<void | AuthResult>;
@@ -121,9 +125,11 @@ interface EmbeddedProviderConfig {
121
125
  authUrl?: string;
122
126
  redirectUrl?: string;
123
127
  };
124
- embeddedWalletType: "app-wallet" | "user-wallet";
128
+ embeddedWalletType: "app-wallet" | "user-wallet" | (string & Record<never, never>);
125
129
  addressTypes: AddressType[];
126
- solanaProvider: "web3js" | "kit";
130
+ solanaProvider: "web3js" | "kit" | (string & Record<never, never>);
131
+ appName?: string;
132
+ appLogo?: string;
127
133
  }
128
134
 
129
135
  declare class EmbeddedProvider {
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -29,6 +39,8 @@ module.exports = __toCommonJS(src_exports);
29
39
 
30
40
  // src/embedded-provider.ts
31
41
  var import_client = require("@phantom/client");
42
+ var import_base64url = require("@phantom/base64url");
43
+ var import_bs58 = __toESM(require("bs58"));
32
44
  var import_parsers = require("@phantom/parsers");
33
45
 
34
46
  // src/auth/jwt-auth.ts
@@ -240,7 +252,11 @@ var EmbeddedProvider = class {
240
252
  async createOrganizationAndStamper() {
241
253
  this.logger.log("EMBEDDED_PROVIDER", "Initializing stamper");
242
254
  const stamperInfo = await this.stamper.init();
243
- this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized", { publicKey: stamperInfo.publicKey, keyId: stamperInfo.keyId, algorithm: this.stamper.algorithm });
255
+ this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized", {
256
+ publicKey: stamperInfo.publicKey,
257
+ keyId: stamperInfo.keyId,
258
+ algorithm: this.stamper.algorithm
259
+ });
244
260
  this.logger.log("EMBEDDED_PROVIDER", "Creating temporary PhantomClient");
245
261
  const tempClient = new import_client.PhantomClient(
246
262
  {
@@ -248,18 +264,29 @@ var EmbeddedProvider = class {
248
264
  },
249
265
  this.stamper
250
266
  );
251
- const uid = Date.now();
252
- const organizationName = `${this.config.organizationId}-${uid}`;
253
267
  const platformName = this.platform.name || "unknown";
254
268
  const shortPubKey = stamperInfo.publicKey.slice(0, 8);
255
- const authenticatorName = `${platformName}-${shortPubKey}-${uid}`;
269
+ const organizationName = `${this.config.organizationId}-${platformName}-${shortPubKey}`;
256
270
  this.logger.log("EMBEDDED_PROVIDER", "Creating organization", {
257
271
  organizationName,
258
- authenticatorName,
272
+ publicKey: stamperInfo.publicKey,
259
273
  platform: platformName
260
274
  });
261
- const { organizationId } = await tempClient.createOrganization(organizationName, stamperInfo.publicKey, authenticatorName);
262
- this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId, authenticatorName });
275
+ const base64urlPublicKey = (0, import_base64url.base64urlEncode)(import_bs58.default.decode(stamperInfo.publicKey));
276
+ const { organizationId } = await tempClient.createOrganization(
277
+ organizationName,
278
+ [{
279
+ username: `user-${shortPubKey}`,
280
+ role: "admin",
281
+ authenticators: [{
282
+ authenticatorName: `auth-${shortPubKey}`,
283
+ authenticatorKind: "keypair",
284
+ publicKey: base64urlPublicKey,
285
+ algorithm: "Ed25519"
286
+ }]
287
+ }]
288
+ );
289
+ this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId });
263
290
  return { organizationId, stamperInfo };
264
291
  }
265
292
  async connect(authOptions) {
@@ -344,29 +371,52 @@ var EmbeddedProvider = class {
344
371
  this.client = null;
345
372
  this.walletId = null;
346
373
  this.addresses = [];
374
+ this.logger.info("EMBEDDED_PROVIDER", "Disconnected from embedded wallet");
347
375
  }
348
376
  async signMessage(params) {
349
377
  if (!this.client || !this.walletId) {
350
378
  throw new Error("Not connected");
351
379
  }
380
+ this.logger.info("EMBEDDED_PROVIDER", "Signing message", {
381
+ walletId: this.walletId,
382
+ message: params.message
383
+ });
352
384
  const parsedMessage = (0, import_parsers.parseMessage)(params.message);
353
385
  const rawResponse = await this.client.signMessage({
354
386
  walletId: this.walletId,
355
387
  message: parsedMessage.base64url,
356
388
  networkId: params.networkId
357
389
  });
390
+ this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
391
+ walletId: this.walletId,
392
+ message: params.message
393
+ });
358
394
  return (0, import_parsers.parseSignMessageResponse)(rawResponse, params.networkId);
359
395
  }
360
396
  async signAndSendTransaction(params) {
361
397
  if (!this.client || !this.walletId) {
362
398
  throw new Error("Not connected");
363
399
  }
400
+ this.logger.info("EMBEDDED_PROVIDER", "Signing and sending transaction", {
401
+ walletId: this.walletId,
402
+ networkId: params.networkId
403
+ });
364
404
  const parsedTransaction = await (0, import_parsers.parseTransaction)(params.transaction, params.networkId);
405
+ this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
406
+ walletId: this.walletId,
407
+ transaction: parsedTransaction
408
+ });
365
409
  const rawResponse = await this.client.signAndSendTransaction({
366
410
  walletId: this.walletId,
367
411
  transaction: parsedTransaction.base64url,
368
412
  networkId: params.networkId
369
413
  });
414
+ this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
415
+ walletId: this.walletId,
416
+ networkId: params.networkId,
417
+ hash: rawResponse.hash,
418
+ rawTransaction: rawResponse.rawTransaction
419
+ });
370
420
  return await (0, import_parsers.parseTransactionResponse)(rawResponse.rawTransaction, params.networkId, rawResponse.hash);
371
421
  }
372
422
  getAddresses() {
@@ -396,6 +446,9 @@ var EmbeddedProvider = class {
396
446
  return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);
397
447
  }
398
448
  } else {
449
+ this.logger.info("EMBEDDED_PROVIDER", "Creating app-wallet", {
450
+ organizationId
451
+ });
399
452
  const tempClient = new import_client.PhantomClient(
400
453
  {
401
454
  apiBaseUrl: this.config.apiBaseUrl,
@@ -418,6 +471,7 @@ var EmbeddedProvider = class {
418
471
  lastUsed: now
419
472
  };
420
473
  await this.storage.saveSession(session);
474
+ this.logger.info("EMBEDDED_PROVIDER", "App-wallet created successfully", { walletId, organizationId });
421
475
  return session;
422
476
  }
423
477
  }
@@ -500,7 +554,9 @@ var EmbeddedProvider = class {
500
554
  redirectUrl: this.config.authOptions?.redirectUrl,
501
555
  customAuthData: authOptions?.customAuthData,
502
556
  authUrl: this.config.authOptions?.authUrl,
503
- sessionId
557
+ sessionId,
558
+ appName: this.config.appName,
559
+ appLogo: this.config.appLogo
504
560
  });
505
561
  if (authResult && "walletId" in authResult) {
506
562
  this.logger.info("EMBEDDED_PROVIDER", "Authentication completed after redirect", {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/embedded-provider.ts","../src/auth/jwt-auth.ts","../src/utils/session.ts","../src/utils/retry.ts"],"sourcesContent":["export * from \"./interfaces\";\nexport * from \"./types\";\nexport * from \"./embedded-provider\";\nexport * from \"./auth/jwt-auth\";\nexport * from \"./utils/session\";\nexport * from \"./utils/retry\";\n","import { PhantomClient } from \"@phantom/client\";\nimport type { AddressType } from \"@phantom/client\";\nimport { parseMessage, parseTransaction, parseSignMessageResponse, parseTransactionResponse,type ParsedTransactionResult, type ParsedSignatureResult } from \"@phantom/parsers\";\n\nimport type {\n PlatformAdapter,\n Session,\n AuthResult,\n DebugLogger,\n EmbeddedStorage,\n AuthProvider,\n URLParamsAccessor,\n StamperInfo,\n} from \"./interfaces\";\nimport type {\n EmbeddedProviderConfig,\n ConnectResult,\n SignMessageParams,\n SignAndSendTransactionParams,\n WalletAddress,\n AuthOptions,\n} from \"./types\";\nimport { JWTAuth } from \"./auth/jwt-auth\";\nimport { generateSessionId } from \"./utils/session\";\nimport { retryWithBackoff } from \"./utils/retry\";\nimport type { StamperWithKeyManagement } from \"@phantom/sdk-types\";\nexport class EmbeddedProvider {\n private config: EmbeddedProviderConfig;\n private platform: PlatformAdapter;\n private storage: EmbeddedStorage;\n private authProvider: AuthProvider;\n private urlParamsAccessor: URLParamsAccessor;\n private stamper: StamperWithKeyManagement;\n private logger: DebugLogger;\n private client: PhantomClient | null = null;\n private walletId: string | null = null;\n private addresses: WalletAddress[] = [];\n private jwtAuth: JWTAuth;\n\n constructor(config: EmbeddedProviderConfig, platform: PlatformAdapter, logger: DebugLogger) {\n this.logger = logger;\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing EmbeddedProvider\", { config });\n\n this.config = config;\n this.platform = platform;\n this.storage = platform.storage;\n this.authProvider = platform.authProvider;\n this.urlParamsAccessor = platform.urlParamsAccessor;\n this.stamper = platform.stamper;\n this.jwtAuth = new JWTAuth();\n\n // Store solana provider config (unused for now)\n config.solanaProvider;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n }\n\n private async getAndFilterWalletAddresses(walletId: string): Promise<WalletAddress[]> {\n // Get wallet addresses with retry and auto-disconnect on failure\n const addresses = await retryWithBackoff(\n () => this.client!.getWalletAddresses(walletId),\n \"getWalletAddresses\",\n this.logger,\n ).catch(async error => {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"getWalletAddresses failed after retries, disconnecting\", {\n walletId,\n error: error.message,\n });\n // Clear the session if getWalletAddresses fails after retries\n await this.storage.clearSession();\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n throw error;\n });\n\n // Filter by enabled address types and return formatted addresses\n return addresses\n .filter(addr => this.config.addressTypes.some(type => type === addr.addressType))\n .map(addr => ({\n addressType: addr.addressType as AddressType,\n address: addr.address,\n }));\n }\n\n /*\n * We use this method to make sure the session is not invalid, or there's a different session id in the url.\n * If there's a different one, we delete the current session and start from scratch.\n * This prevents issues where users have stale sessions or URL mismatches after redirects.\n */\n private async validateAndCleanSession(session: Session | null): Promise<Session | null> {\n if (!session) return null;\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Found existing session, validating\", {\n sessionId: session.sessionId,\n status: session.status,\n walletId: session.walletId,\n });\n\n // If session is not completed, check if we're in the right context\n if (session.status !== \"completed\") {\n const urlSessionId = this.urlParamsAccessor.getParam(\"session_id\");\n\n // If we have a pending session but no sessionId in URL, this is a mismatch\n if (session.status === \"pending\" && !urlSessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session mismatch detected - pending session without redirect context\", {\n sessionId: session.sessionId,\n status: session.status,\n });\n // Clear the invalid session and start fresh\n await this.storage.clearSession();\n return null;\n }\n // If sessionId in URL doesn't match stored session, clear invalid session\n else if (urlSessionId && urlSessionId !== session.sessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session ID mismatch detected\", {\n storedSessionId: session.sessionId,\n urlSessionId: urlSessionId,\n });\n await this.storage.clearSession();\n return null;\n }\n }\n\n return session;\n }\n\n /*\n * We use this method to validate authentication options before processing them.\n * This ensures only supported auth providers are used and required tokens are present.\n */\n private validateAuthOptions(authOptions?: AuthOptions): void {\n if (!authOptions) return;\n\n if (authOptions.provider && ![\"google\", \"apple\", \"jwt\"].includes(authOptions.provider)) {\n throw new Error(`Invalid auth provider: ${authOptions.provider}. Must be \"google\", \"apple\", or \"jwt\"`);\n }\n\n if (authOptions.provider === \"jwt\" && !authOptions.jwtToken) {\n throw new Error(\"JWT token is required when using JWT authentication\");\n }\n }\n\n /*\n * We use this method to initialize the stamper and create an organization for new sessions.\n * This is the first step when no existing session is found and we need to set up a new wallet.\n */\n private async createOrganizationAndStamper(): Promise<{ organizationId: string; stamperInfo: StamperInfo }> {\n // Initialize stamper (generates keypair in IndexedDB)\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing stamper\");\n const stamperInfo = await this.stamper.init();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Stamper initialized\", { publicKey: stamperInfo.publicKey, keyId: stamperInfo.keyId, algorithm: this.stamper.algorithm });\n\n // Create a temporary client with the stamper\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating temporary PhantomClient\");\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n },\n this.stamper,\n );\n\n // Create an organization\n // organization name is a combination of this organizationId and this userId, which will be a unique identifier\n const uid = Date.now(); // for now\n const organizationName = `${this.config.organizationId}-${uid}`;\n \n // Create authenticator name with platform info and public key for identification\n const platformName = this.platform.name || \"unknown\";\n const shortPubKey = stamperInfo.publicKey.slice(0, 8); // First 8 chars of public key\n const authenticatorName = `${platformName}-${shortPubKey}-${uid}`;\n \n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating organization\", { \n organizationName, \n authenticatorName, \n platform: platformName \n });\n \n const { organizationId } = await tempClient.createOrganization(organizationName, stamperInfo.publicKey, authenticatorName);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId, authenticatorName });\n\n return { organizationId, stamperInfo };\n }\n\n async connect(authOptions?: AuthOptions): Promise<ConnectResult> {\n try {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting embedded provider connect\", {\n authOptions: authOptions\n ? {\n provider: authOptions.provider,\n hasJwtToken: !!authOptions.jwtToken,\n }\n : undefined,\n });\n\n // Get and validate existing session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Getting existing session\");\n let session = await this.storage.getSession();\n session = await this.validateAndCleanSession(session);\n\n // First, check if we're resuming from a redirect\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking for redirect resume\");\n if (this.authProvider.resumeAuthFromRedirect) {\n const authResult = this.authProvider.resumeAuthFromRedirect();\n if (authResult) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Resuming from redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n return this.completeAuthConnection(authResult);\n }\n }\n\n // Validate auth options\n this.validateAuthOptions(authOptions);\n\n // If no session exists, create new one\n if (!session) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing session, creating new one\");\n const { organizationId, stamperInfo } = await this.createOrganizationAndStamper();\n session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions);\n }\n\n // If session is null here, it means we're doing a redirect\n if (!session) {\n // This should not return anything as redirect is happening\n return {\n addresses: [],\n status: \"pending\",\n } as ConnectResult;\n }\n\n // Update session last used timestamp (only for non-redirect flows)\n // For redirect flows, timestamp is updated before redirect to prevent race condition\n if (!authOptions || authOptions.provider === \"jwt\" || this.config.embeddedWalletType === \"app-wallet\") {\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n }\n\n // Initialize client and get addresses\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n } catch (error) {\n // Log the full error details for debugging\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Connect failed with error\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n\n // Enhanced error handling with specific error types\n if (error instanceof Error) {\n // Check for specific error types and provide better error messages\n if (error.message.includes(\"IndexedDB\") || error.message.includes(\"storage\")) {\n throw new Error(\n \"Storage error: Unable to access browser storage. Please ensure storage is available and try again.\",\n );\n }\n\n if (error.message.includes(\"network\") || error.message.includes(\"fetch\")) {\n throw new Error(\n \"Network error: Unable to connect to authentication server. Please check your internet connection and try again.\",\n );\n }\n\n if (error.message.includes(\"JWT\") || error.message.includes(\"jwt\")) {\n throw new Error(`JWT Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"Authentication\") || error.message.includes(\"auth\")) {\n throw new Error(`Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"organization\") || error.message.includes(\"wallet\")) {\n throw new Error(`Wallet creation error: ${error.message}`);\n }\n\n // Re-throw the original error if it's already well-formatted\n throw error;\n }\n\n // Handle unknown error types\n throw new Error(`Embedded wallet connection failed: ${String(error)}`);\n }\n }\n\n async disconnect(): Promise<void> {\n await this.storage.clearSession();\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Parse message to base64url format for client\n const parsedMessage = parseMessage(params.message);\n\n // Get raw response from client\n const rawResponse = await this.client.signMessage({\n walletId: this.walletId,\n message: parsedMessage.base64url,\n networkId: params.networkId,\n });\n\n // Parse the response to get human-readable signature and explorer URL\n return parseSignMessageResponse(rawResponse, params.networkId);\n }\n\n async signAndSendTransaction(params: SignAndSendTransactionParams): Promise<ParsedTransactionResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Parse transaction to base64url format for client based on network\n const parsedTransaction = await parseTransaction(params.transaction, params.networkId);\n\n // Get raw response from client\n const rawResponse = await this.client.signAndSendTransaction({\n walletId: this.walletId,\n transaction: parsedTransaction.base64url,\n networkId: params.networkId,\n });\n\n // Parse the response to get transaction hash and explorer URL\n return await parseTransactionResponse(rawResponse.rawTransaction, params.networkId, rawResponse.hash);\n }\n\n getAddresses(): WalletAddress[] {\n return this.addresses;\n }\n\n isConnected(): boolean {\n return this.client !== null && this.walletId !== null;\n }\n\n /*\n * We use this method to route between different authentication flows based on wallet type and auth options.\n * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.\n * Returns null for redirect flows since they don't complete synchronously.\n */\n private async handleAuthFlow(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions?: AuthOptions,\n ): Promise<Session | null> {\n if (this.config.embeddedWalletType === \"user-wallet\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Creating user-wallet, routing authentication\", {\n authProvider: authOptions?.provider || \"phantom-connect\",\n });\n\n // Route to appropriate authentication flow based on authOptions\n if (authOptions?.provider === \"jwt\") {\n return await this.handleJWTAuth(organizationId, stamperInfo, authOptions);\n } else {\n // This will redirect in browser, so we don't return a session\n // In react-native this will return an auth result\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting redirect-based authentication flow\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n });\n return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);\n \n }\n } else {\n // Create app-wallet directly\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: organizationId,\n },\n this.stamper,\n );\n\n const wallet = await tempClient.createWallet(`Wallet ${Date.now()}`);\n const walletId = wallet.walletId;\n\n // Save session with app-wallet info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"app-wallet\",\n userInfo: { embeddedWalletType: this.config.embeddedWalletType },\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n await this.storage.saveSession(session);\n return session;\n }\n }\n\n /*\n * We use this method to handle JWT-based authentication for user-wallets.\n * It authenticates using the provided JWT token and creates a completed session.\n */\n private async handleJWTAuth(organizationId: string, stamperInfo: StamperInfo, authOptions: AuthOptions): Promise<Session> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using JWT authentication flow\");\n\n // Use JWT authentication flow\n if (!authOptions.jwtToken) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"JWT token missing for JWT authentication\");\n throw new Error(\"JWT token is required for JWT authentication\");\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting JWT authentication\");\n const authResult = await this.jwtAuth.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n jwtToken: authOptions.jwtToken,\n customAuthData: authOptions.customAuthData,\n });\n const walletId = authResult.walletId;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"JWT authentication completed\", { walletId });\n\n // Save session with auth info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: authResult.provider,\n userInfo: authResult.userInfo,\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving JWT session\");\n await this.storage.saveSession(session);\n return session;\n }\n\n /*\n * We use this method to handle redirect-based authentication (Google/Apple OAuth).\n * It saves a temporary session before redirecting to prevent losing state during the redirect flow.\n * Session timestamp is updated before redirect to prevent race conditions.\n */\n private async handleRedirectAuth(organizationId: string, stamperInfo: StamperInfo, authOptions?: AuthOptions): Promise<Session | null> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using Phantom Connect authentication flow (redirect-based)\", {\n provider: authOptions?.provider,\n hasRedirectUrl: !!this.config.authOptions?.redirectUrl,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Use Phantom Connect authentication flow (redirect-based)\n // Store session before redirect so we can restore it after redirect\n const now = Date.now();\n const sessionId = generateSessionId();\n const tempSession: Session = {\n sessionId: sessionId,\n walletId: `temp-${now}`, // Temporary ID, will be updated after redirect\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"phantom-connect\",\n userInfo: { provider: authOptions?.provider },\n status: \"pending\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving temporary session before redirect\", {\n sessionId: tempSession.sessionId,\n tempWalletId: tempSession.walletId,\n });\n\n // Update session timestamp before redirect (prevents race condition)\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting Phantom Connect redirect\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Start the authentication flow (this will redirect the user in the browser, or handle it in React Native)\n const authResult = await this.authProvider.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider as \"google\" | \"apple\" | undefined,\n redirectUrl: this.config.authOptions?.redirectUrl,\n customAuthData: authOptions?.customAuthData,\n authUrl: this.config.authOptions?.authUrl,\n sessionId: sessionId,\n });\n\n if (authResult && \"walletId\" in authResult) {\n // If we got an auth result, we need to update the session with actual wallet ID\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authentication completed after redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n\n // Update the temporary session with actual wallet ID and auth info\n tempSession.walletId = authResult.walletId;\n tempSession.authProvider = authResult.provider || tempSession.authProvider;\n tempSession.status = \"completed\";\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n return tempSession; // Return the auth result for further processing\n }\n // If we don't have an auth result, it means we're in a redirect flow\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Redirect authentication initiated, waiting for redirect completion\");\n // In this case, we don't return anything as the redirect will handle the rest\n return null;\n }\n\n private async completeAuthConnection(authResult: AuthResult): Promise<ConnectResult> {\n // Check if we have an existing session\n const session = await this.storage.getSession();\n\n if (!session) {\n throw new Error(\"No session found after redirect - session may have expired\");\n }\n\n // Update session with actual wallet ID and auth info from redirect\n session.walletId = authResult.walletId;\n session.authProvider = authResult.provider || session.authProvider;\n session.status = \"completed\";\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * We use this method to initialize the PhantomClient and fetch wallet addresses from a completed session.\n * This is the final step that sets up the provider's client state and retrieves available addresses.\n */\n private async initializeClientFromSession(session: Session): Promise<void> {\n // Create client from session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing PhantomClient from session\", {\n organizationId: session.organizationId,\n walletId: session.walletId,\n });\n\n // Ensure stamper is initialized with existing keys\n if (!this.stamper.getKeyInfo()) {\n await this.stamper.init();\n }\n\n this.client = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: session.organizationId,\n },\n this.stamper,\n );\n\n this.walletId = session.walletId;\n\n // Get wallet addresses and filter by enabled address types with retry\n this.addresses = await this.getAndFilterWalletAddresses(session.walletId);\n }\n}\n","import type { AuthResult, JWTAuthOptions } from \"../interfaces\";\n\nexport class JWTAuth {\n async authenticate(options: JWTAuthOptions): Promise<AuthResult> {\n // Validate JWT token format\n if (!options.jwtToken || typeof options.jwtToken !== \"string\") {\n throw new Error(\"Invalid JWT token: token must be a non-empty string\");\n }\n\n // Basic JWT format validation (3 parts separated by dots)\n const jwtParts = options.jwtToken.split(\".\");\n if (jwtParts.length !== 3) {\n throw new Error(\"Invalid JWT token format: token must have 3 parts separated by dots\");\n }\n\n // JWT authentication flow - direct API call to create wallet with JWT\n try {\n // This would typically make an API call to your backend\n // which would validate the JWT and create/retrieve the wallet\n const response = await fetch(\"/api/auth/jwt\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${options.jwtToken}`,\n },\n body: JSON.stringify({\n organizationId: options.organizationId,\n parentOrganizationId: options.parentOrganizationId,\n customAuthData: options.customAuthData,\n }),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.error || errorMessage;\n } catch {\n errorMessage = response.statusText || errorMessage;\n }\n\n switch (response.status) {\n case 400:\n throw new Error(`Invalid JWT authentication request: ${errorMessage}`);\n case 401:\n throw new Error(`JWT token is invalid or expired: ${errorMessage}`);\n case 403:\n throw new Error(`JWT authentication forbidden: ${errorMessage}`);\n case 404:\n throw new Error(`JWT authentication endpoint not found: ${errorMessage}`);\n case 429:\n throw new Error(`Too many JWT authentication requests: ${errorMessage}`);\n case 500:\n case 502:\n case 503:\n case 504:\n throw new Error(`JWT authentication server error: ${errorMessage}`);\n default:\n throw new Error(`JWT authentication failed: ${errorMessage}`);\n }\n }\n\n let result;\n try {\n result = await response.json();\n } catch (parseError) {\n throw new Error(\"Invalid response from JWT authentication server: response is not valid JSON\");\n }\n\n if (!result.walletId) {\n throw new Error(\"Invalid JWT authentication response: missing walletId\");\n }\n\n return {\n walletId: result.walletId,\n provider: \"jwt\",\n userInfo: result.userInfo || {},\n };\n } catch (error) {\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n throw new Error(\"JWT authentication failed: network error or invalid endpoint\");\n }\n\n if (error instanceof Error) {\n throw error; // Re-throw known errors\n }\n\n throw new Error(`JWT authentication error: ${String(error)}`);\n }\n }\n}\n","export function generateSessionId(): string {\n return (\n \"session_\" +\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15) +\n \"_\" +\n Date.now()\n );\n}\n","import type { DebugLogger } from \"../interfaces\";\n\nexport async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n operationName: string,\n logger: DebugLogger,\n maxRetries: number = 3,\n baseDelay: number = 1000,\n): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n logger.log(\"EMBEDDED_PROVIDER\", `Attempting ${operationName}`, {\n attempt,\n maxRetries,\n });\n return await operation();\n } catch (error) {\n lastError = error as Error;\n logger.warn(\"EMBEDDED_PROVIDER\", `${operationName} failed`, {\n attempt,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n if (attempt === maxRetries) {\n logger.error(\"EMBEDDED_PROVIDER\", `${operationName} failed after ${maxRetries} attempts`, {\n finalError: error instanceof Error ? error.message : String(error),\n });\n break;\n }\n\n // Exponential backoff: 1s, 2s, 4s\n const delay = baseDelay * Math.pow(2, attempt - 1);\n logger.log(\"EMBEDDED_PROVIDER\", `Retrying ${operationName} in ${delay}ms`, {\n attempt: attempt + 1,\n delay,\n });\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError!;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/embedded-provider.ts","../src/auth/jwt-auth.ts","../src/utils/session.ts","../src/utils/retry.ts"],"sourcesContent":["export * from \"./interfaces\";\nexport * from \"./types\";\nexport * from \"./embedded-provider\";\nexport * from \"./auth/jwt-auth\";\nexport * from \"./utils/session\";\nexport * from \"./utils/retry\";\n","import { PhantomClient } from \"@phantom/client\";\nimport type { AddressType } from \"@phantom/client\";\nimport { base64urlEncode } from \"@phantom/base64url\";\nimport bs58 from \"bs58\";\nimport {\n parseMessage,\n parseTransaction,\n parseSignMessageResponse,\n parseTransactionResponse,\n type ParsedTransactionResult,\n type ParsedSignatureResult,\n} from \"@phantom/parsers\";\n\nimport type {\n PlatformAdapter,\n Session,\n AuthResult,\n DebugLogger,\n EmbeddedStorage,\n AuthProvider,\n URLParamsAccessor,\n StamperInfo,\n} from \"./interfaces\";\nimport type {\n EmbeddedProviderConfig,\n ConnectResult,\n SignMessageParams,\n SignAndSendTransactionParams,\n WalletAddress,\n AuthOptions,\n} from \"./types\";\nimport { JWTAuth } from \"./auth/jwt-auth\";\nimport { generateSessionId } from \"./utils/session\";\nimport { retryWithBackoff } from \"./utils/retry\";\nimport type { StamperWithKeyManagement } from \"@phantom/sdk-types\";\nexport class EmbeddedProvider {\n private config: EmbeddedProviderConfig;\n private platform: PlatformAdapter;\n private storage: EmbeddedStorage;\n private authProvider: AuthProvider;\n private urlParamsAccessor: URLParamsAccessor;\n private stamper: StamperWithKeyManagement;\n private logger: DebugLogger;\n private client: PhantomClient | null = null;\n private walletId: string | null = null;\n private addresses: WalletAddress[] = [];\n private jwtAuth: JWTAuth;\n\n constructor(config: EmbeddedProviderConfig, platform: PlatformAdapter, logger: DebugLogger) {\n this.logger = logger;\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing EmbeddedProvider\", { config });\n\n this.config = config;\n this.platform = platform;\n this.storage = platform.storage;\n this.authProvider = platform.authProvider;\n this.urlParamsAccessor = platform.urlParamsAccessor;\n this.stamper = platform.stamper;\n this.jwtAuth = new JWTAuth();\n\n // Store solana provider config (unused for now)\n config.solanaProvider;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n }\n\n private async getAndFilterWalletAddresses(walletId: string): Promise<WalletAddress[]> {\n // Get wallet addresses with retry and auto-disconnect on failure\n const addresses = await retryWithBackoff(\n () => this.client!.getWalletAddresses(walletId),\n \"getWalletAddresses\",\n this.logger,\n ).catch(async error => {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"getWalletAddresses failed after retries, disconnecting\", {\n walletId,\n error: error.message,\n });\n // Clear the session if getWalletAddresses fails after retries\n await this.storage.clearSession();\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n throw error;\n });\n\n // Filter by enabled address types and return formatted addresses\n return addresses\n .filter(addr => this.config.addressTypes.some(type => type === addr.addressType))\n .map(addr => ({\n addressType: addr.addressType as AddressType,\n address: addr.address,\n }));\n }\n\n /*\n * We use this method to make sure the session is not invalid, or there's a different session id in the url.\n * If there's a different one, we delete the current session and start from scratch.\n * This prevents issues where users have stale sessions or URL mismatches after redirects.\n */\n private async validateAndCleanSession(session: Session | null): Promise<Session | null> {\n if (!session) return null;\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Found existing session, validating\", {\n sessionId: session.sessionId,\n status: session.status,\n walletId: session.walletId,\n });\n\n // If session is not completed, check if we're in the right context\n if (session.status !== \"completed\") {\n const urlSessionId = this.urlParamsAccessor.getParam(\"session_id\");\n\n // If we have a pending session but no sessionId in URL, this is a mismatch\n if (session.status === \"pending\" && !urlSessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session mismatch detected - pending session without redirect context\", {\n sessionId: session.sessionId,\n status: session.status,\n });\n // Clear the invalid session and start fresh\n await this.storage.clearSession();\n return null;\n }\n // If sessionId in URL doesn't match stored session, clear invalid session\n else if (urlSessionId && urlSessionId !== session.sessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session ID mismatch detected\", {\n storedSessionId: session.sessionId,\n urlSessionId: urlSessionId,\n });\n await this.storage.clearSession();\n return null;\n }\n }\n\n return session;\n }\n\n /*\n * We use this method to validate authentication options before processing them.\n * This ensures only supported auth providers are used and required tokens are present.\n */\n private validateAuthOptions(authOptions?: AuthOptions): void {\n if (!authOptions) return;\n\n if (authOptions.provider && ![\"google\", \"apple\", \"jwt\"].includes(authOptions.provider)) {\n throw new Error(`Invalid auth provider: ${authOptions.provider}. Must be \"google\", \"apple\", or \"jwt\"`);\n }\n\n if (authOptions.provider === \"jwt\" && !authOptions.jwtToken) {\n throw new Error(\"JWT token is required when using JWT authentication\");\n }\n }\n\n /*\n * We use this method to initialize the stamper and create an organization for new sessions.\n * This is the first step when no existing session is found and we need to set up a new wallet.\n */\n private async createOrganizationAndStamper(): Promise<{ organizationId: string; stamperInfo: StamperInfo }> {\n // Initialize stamper (generates keypair in IndexedDB)\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing stamper\");\n const stamperInfo = await this.stamper.init();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Stamper initialized\", {\n publicKey: stamperInfo.publicKey,\n keyId: stamperInfo.keyId,\n algorithm: this.stamper.algorithm,\n });\n\n // Create a temporary client with the stamper\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating temporary PhantomClient\");\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n },\n this.stamper,\n );\n\n // Create an organization\n // organization name is a combination of this organizationId and this userId, which will be a unique identifier\n const platformName = this.platform.name || \"unknown\";\n const shortPubKey = stamperInfo.publicKey.slice(0, 8);\n const organizationName = `${this.config.organizationId}-${platformName}-${shortPubKey}`;\n\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating organization\", {\n organizationName,\n publicKey: stamperInfo.publicKey,\n platform: platformName,\n });\n\n // Convert base58 public key to base64url format as required by the API\n const base64urlPublicKey = base64urlEncode(bs58.decode(stamperInfo.publicKey));\n \n const { organizationId } = await tempClient.createOrganization(\n organizationName,\n [{\n username: `user-${shortPubKey}`,\n role: 'admin',\n authenticators: [{\n authenticatorName: `auth-${shortPubKey}`,\n authenticatorKind: 'keypair',\n publicKey: base64urlPublicKey,\n algorithm: 'Ed25519',\n }]\n }]\n );\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId });\n\n return { organizationId, stamperInfo };\n }\n\n async connect(authOptions?: AuthOptions): Promise<ConnectResult> {\n try {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting embedded provider connect\", {\n authOptions: authOptions\n ? {\n provider: authOptions.provider,\n hasJwtToken: !!authOptions.jwtToken,\n }\n : undefined,\n });\n\n // Get and validate existing session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Getting existing session\");\n let session = await this.storage.getSession();\n session = await this.validateAndCleanSession(session);\n\n // First, check if we're resuming from a redirect\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking for redirect resume\");\n if (this.authProvider.resumeAuthFromRedirect) {\n const authResult = this.authProvider.resumeAuthFromRedirect();\n if (authResult) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Resuming from redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n return this.completeAuthConnection(authResult);\n }\n }\n\n // Validate auth options\n this.validateAuthOptions(authOptions);\n\n // If no session exists, create new one\n if (!session) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing session, creating new one\");\n const { organizationId, stamperInfo } = await this.createOrganizationAndStamper();\n session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions);\n }\n\n // If session is null here, it means we're doing a redirect\n if (!session) {\n // This should not return anything as redirect is happening\n return {\n addresses: [],\n status: \"pending\",\n } as ConnectResult;\n }\n\n // Update session last used timestamp (only for non-redirect flows)\n // For redirect flows, timestamp is updated before redirect to prevent race condition\n if (!authOptions || authOptions.provider === \"jwt\" || this.config.embeddedWalletType === \"app-wallet\") {\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n }\n\n // Initialize client and get addresses\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n } catch (error) {\n // Log the full error details for debugging\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Connect failed with error\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n\n // Enhanced error handling with specific error types\n if (error instanceof Error) {\n // Check for specific error types and provide better error messages\n if (error.message.includes(\"IndexedDB\") || error.message.includes(\"storage\")) {\n throw new Error(\n \"Storage error: Unable to access browser storage. Please ensure storage is available and try again.\",\n );\n }\n\n if (error.message.includes(\"network\") || error.message.includes(\"fetch\")) {\n throw new Error(\n \"Network error: Unable to connect to authentication server. Please check your internet connection and try again.\",\n );\n }\n\n if (error.message.includes(\"JWT\") || error.message.includes(\"jwt\")) {\n throw new Error(`JWT Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"Authentication\") || error.message.includes(\"auth\")) {\n throw new Error(`Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"organization\") || error.message.includes(\"wallet\")) {\n throw new Error(`Wallet creation error: ${error.message}`);\n }\n\n // Re-throw the original error if it's already well-formatted\n throw error;\n }\n\n // Handle unknown error types\n throw new Error(`Embedded wallet connection failed: ${String(error)}`);\n }\n }\n\n async disconnect(): Promise<void> {\n await this.storage.clearSession();\n\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Disconnected from embedded wallet\");\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Signing message\", {\n walletId: this.walletId,\n message: params.message,\n });\n\n // Parse message to base64url format for client\n const parsedMessage = parseMessage(params.message);\n\n // Get raw response from client\n const rawResponse = await this.client.signMessage({\n walletId: this.walletId,\n message: parsedMessage.base64url,\n networkId: params.networkId,\n });\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Message signed successfully\", {\n walletId: this.walletId,\n message: params.message,\n });\n\n // Parse the response to get human-readable signature and explorer URL\n return parseSignMessageResponse(rawResponse, params.networkId);\n }\n\n async signAndSendTransaction(params: SignAndSendTransactionParams): Promise<ParsedTransactionResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Signing and sending transaction\", {\n walletId: this.walletId,\n networkId: params.networkId,\n });\n\n // Parse transaction to base64url format for client based on network\n const parsedTransaction = await parseTransaction(params.transaction, params.networkId);\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Parsed transaction for signing\", {\n walletId: this.walletId,\n transaction: parsedTransaction,\n });\n\n // Get raw response from client\n const rawResponse = await this.client.signAndSendTransaction({\n walletId: this.walletId,\n transaction: parsedTransaction.base64url,\n networkId: params.networkId,\n });\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Transaction signed and sent successfully\", {\n walletId: this.walletId,\n networkId: params.networkId,\n hash: rawResponse.hash,\n rawTransaction: rawResponse.rawTransaction,\n });\n\n // Parse the response to get transaction hash and explorer URL\n return await parseTransactionResponse(rawResponse.rawTransaction, params.networkId, rawResponse.hash);\n }\n\n getAddresses(): WalletAddress[] {\n return this.addresses;\n }\n\n isConnected(): boolean {\n return this.client !== null && this.walletId !== null;\n }\n\n /*\n * We use this method to route between different authentication flows based on wallet type and auth options.\n * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.\n * Returns null for redirect flows since they don't complete synchronously.\n */\n private async handleAuthFlow(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions?: AuthOptions,\n ): Promise<Session | null> {\n if (this.config.embeddedWalletType === \"user-wallet\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Creating user-wallet, routing authentication\", {\n authProvider: authOptions?.provider || \"phantom-connect\",\n });\n\n // Route to appropriate authentication flow based on authOptions\n if (authOptions?.provider === \"jwt\") {\n return await this.handleJWTAuth(organizationId, stamperInfo, authOptions);\n } else {\n // This will redirect in browser, so we don't return a session\n // In react-native this will return an auth result\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting redirect-based authentication flow\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n });\n return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);\n }\n } else {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Creating app-wallet\", {\n organizationId,\n });\n // Create app-wallet directly\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: organizationId,\n },\n this.stamper,\n );\n\n const wallet = await tempClient.createWallet(`Wallet ${Date.now()}`);\n const walletId = wallet.walletId;\n\n // Save session with app-wallet info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"app-wallet\",\n userInfo: { embeddedWalletType: this.config.embeddedWalletType },\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"App-wallet created successfully\", { walletId, organizationId });\n return session;\n }\n }\n\n /*\n * We use this method to handle JWT-based authentication for user-wallets.\n * It authenticates using the provided JWT token and creates a completed session.\n */\n private async handleJWTAuth(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions: AuthOptions,\n ): Promise<Session> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using JWT authentication flow\");\n\n // Use JWT authentication flow\n if (!authOptions.jwtToken) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"JWT token missing for JWT authentication\");\n throw new Error(\"JWT token is required for JWT authentication\");\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting JWT authentication\");\n const authResult = await this.jwtAuth.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n jwtToken: authOptions.jwtToken,\n customAuthData: authOptions.customAuthData,\n });\n const walletId = authResult.walletId;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"JWT authentication completed\", { walletId });\n\n // Save session with auth info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: authResult.provider,\n userInfo: authResult.userInfo,\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving JWT session\");\n await this.storage.saveSession(session);\n return session;\n }\n\n /*\n * We use this method to handle redirect-based authentication (Google/Apple OAuth).\n * It saves a temporary session before redirecting to prevent losing state during the redirect flow.\n * Session timestamp is updated before redirect to prevent race conditions.\n */\n private async handleRedirectAuth(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions?: AuthOptions,\n ): Promise<Session | null> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using Phantom Connect authentication flow (redirect-based)\", {\n provider: authOptions?.provider,\n hasRedirectUrl: !!this.config.authOptions?.redirectUrl,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Use Phantom Connect authentication flow (redirect-based)\n // Store session before redirect so we can restore it after redirect\n const now = Date.now();\n const sessionId = generateSessionId();\n const tempSession: Session = {\n sessionId: sessionId,\n walletId: `temp-${now}`, // Temporary ID, will be updated after redirect\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"phantom-connect\",\n userInfo: { provider: authOptions?.provider },\n status: \"pending\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving temporary session before redirect\", {\n sessionId: tempSession.sessionId,\n tempWalletId: tempSession.walletId,\n });\n\n // Update session timestamp before redirect (prevents race condition)\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting Phantom Connect redirect\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Start the authentication flow (this will redirect the user in the browser, or handle it in React Native)\n const authResult = await this.authProvider.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider as \"google\" | \"apple\" | undefined,\n redirectUrl: this.config.authOptions?.redirectUrl,\n customAuthData: authOptions?.customAuthData,\n authUrl: this.config.authOptions?.authUrl,\n sessionId: sessionId,\n appName: this.config.appName,\n appLogo: this.config.appLogo,\n });\n\n if (authResult && \"walletId\" in authResult) {\n // If we got an auth result, we need to update the session with actual wallet ID\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authentication completed after redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n\n // Update the temporary session with actual wallet ID and auth info\n tempSession.walletId = authResult.walletId;\n tempSession.authProvider = authResult.provider || tempSession.authProvider;\n tempSession.status = \"completed\";\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n return tempSession; // Return the auth result for further processing\n }\n // If we don't have an auth result, it means we're in a redirect flow\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Redirect authentication initiated, waiting for redirect completion\");\n // In this case, we don't return anything as the redirect will handle the rest\n return null;\n }\n\n private async completeAuthConnection(authResult: AuthResult): Promise<ConnectResult> {\n // Check if we have an existing session\n const session = await this.storage.getSession();\n\n if (!session) {\n throw new Error(\"No session found after redirect - session may have expired\");\n }\n\n // Update session with actual wallet ID and auth info from redirect\n session.walletId = authResult.walletId;\n session.authProvider = authResult.provider || session.authProvider;\n session.status = \"completed\";\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * We use this method to initialize the PhantomClient and fetch wallet addresses from a completed session.\n * This is the final step that sets up the provider's client state and retrieves available addresses.\n */\n private async initializeClientFromSession(session: Session): Promise<void> {\n // Create client from session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing PhantomClient from session\", {\n organizationId: session.organizationId,\n walletId: session.walletId,\n });\n\n // Ensure stamper is initialized with existing keys\n if (!this.stamper.getKeyInfo()) {\n await this.stamper.init();\n }\n\n this.client = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: session.organizationId,\n },\n this.stamper,\n );\n\n this.walletId = session.walletId;\n\n // Get wallet addresses and filter by enabled address types with retry\n this.addresses = await this.getAndFilterWalletAddresses(session.walletId);\n }\n}\n","import type { AuthResult, JWTAuthOptions } from \"../interfaces\";\n\nexport class JWTAuth {\n async authenticate(options: JWTAuthOptions): Promise<AuthResult> {\n // Validate JWT token format\n if (!options.jwtToken || typeof options.jwtToken !== \"string\") {\n throw new Error(\"Invalid JWT token: token must be a non-empty string\");\n }\n\n // Basic JWT format validation (3 parts separated by dots)\n const jwtParts = options.jwtToken.split(\".\");\n if (jwtParts.length !== 3) {\n throw new Error(\"Invalid JWT token format: token must have 3 parts separated by dots\");\n }\n\n // JWT authentication flow - direct API call to create wallet with JWT\n try {\n // This would typically make an API call to your backend\n // which would validate the JWT and create/retrieve the wallet\n const response = await fetch(\"/api/auth/jwt\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${options.jwtToken}`,\n },\n body: JSON.stringify({\n organizationId: options.organizationId,\n parentOrganizationId: options.parentOrganizationId,\n customAuthData: options.customAuthData,\n }),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.error || errorMessage;\n } catch {\n errorMessage = response.statusText || errorMessage;\n }\n\n switch (response.status) {\n case 400:\n throw new Error(`Invalid JWT authentication request: ${errorMessage}`);\n case 401:\n throw new Error(`JWT token is invalid or expired: ${errorMessage}`);\n case 403:\n throw new Error(`JWT authentication forbidden: ${errorMessage}`);\n case 404:\n throw new Error(`JWT authentication endpoint not found: ${errorMessage}`);\n case 429:\n throw new Error(`Too many JWT authentication requests: ${errorMessage}`);\n case 500:\n case 502:\n case 503:\n case 504:\n throw new Error(`JWT authentication server error: ${errorMessage}`);\n default:\n throw new Error(`JWT authentication failed: ${errorMessage}`);\n }\n }\n\n let result;\n try {\n result = await response.json();\n } catch (parseError) {\n throw new Error(\"Invalid response from JWT authentication server: response is not valid JSON\");\n }\n\n if (!result.walletId) {\n throw new Error(\"Invalid JWT authentication response: missing walletId\");\n }\n\n return {\n walletId: result.walletId,\n provider: \"jwt\",\n userInfo: result.userInfo || {},\n };\n } catch (error) {\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n throw new Error(\"JWT authentication failed: network error or invalid endpoint\");\n }\n\n if (error instanceof Error) {\n throw error; // Re-throw known errors\n }\n\n throw new Error(`JWT authentication error: ${String(error)}`);\n }\n }\n}\n","export function generateSessionId(): string {\n return (\n \"session_\" +\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15) +\n \"_\" +\n Date.now()\n );\n}\n","import type { DebugLogger } from \"../interfaces\";\n\nexport async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n operationName: string,\n logger: DebugLogger,\n maxRetries: number = 3,\n baseDelay: number = 1000,\n): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n logger.log(\"EMBEDDED_PROVIDER\", `Attempting ${operationName}`, {\n attempt,\n maxRetries,\n });\n return await operation();\n } catch (error) {\n lastError = error as Error;\n logger.warn(\"EMBEDDED_PROVIDER\", `${operationName} failed`, {\n attempt,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n if (attempt === maxRetries) {\n logger.error(\"EMBEDDED_PROVIDER\", `${operationName} failed after ${maxRetries} attempts`, {\n finalError: error instanceof Error ? error.message : String(error),\n });\n break;\n }\n\n // Exponential backoff: 1s, 2s, 4s\n const delay = baseDelay * Math.pow(2, attempt - 1);\n logger.log(\"EMBEDDED_PROVIDER\", `Retrying ${operationName} in ${delay}ms`, {\n attempt: attempt + 1,\n delay,\n });\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError!;\n}\n"],"mappings":"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","names":["bs58"]}
package/dist/index.mjs CHANGED
@@ -1,6 +1,13 @@
1
1
  // src/embedded-provider.ts
2
2
  import { PhantomClient } from "@phantom/client";
3
- import { parseMessage, parseTransaction, parseSignMessageResponse, parseTransactionResponse } from "@phantom/parsers";
3
+ import { base64urlEncode } from "@phantom/base64url";
4
+ import bs58 from "bs58";
5
+ import {
6
+ parseMessage,
7
+ parseTransaction,
8
+ parseSignMessageResponse,
9
+ parseTransactionResponse
10
+ } from "@phantom/parsers";
4
11
 
5
12
  // src/auth/jwt-auth.ts
6
13
  var JWTAuth = class {
@@ -211,7 +218,11 @@ var EmbeddedProvider = class {
211
218
  async createOrganizationAndStamper() {
212
219
  this.logger.log("EMBEDDED_PROVIDER", "Initializing stamper");
213
220
  const stamperInfo = await this.stamper.init();
214
- this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized", { publicKey: stamperInfo.publicKey, keyId: stamperInfo.keyId, algorithm: this.stamper.algorithm });
221
+ this.logger.log("EMBEDDED_PROVIDER", "Stamper initialized", {
222
+ publicKey: stamperInfo.publicKey,
223
+ keyId: stamperInfo.keyId,
224
+ algorithm: this.stamper.algorithm
225
+ });
215
226
  this.logger.log("EMBEDDED_PROVIDER", "Creating temporary PhantomClient");
216
227
  const tempClient = new PhantomClient(
217
228
  {
@@ -219,18 +230,29 @@ var EmbeddedProvider = class {
219
230
  },
220
231
  this.stamper
221
232
  );
222
- const uid = Date.now();
223
- const organizationName = `${this.config.organizationId}-${uid}`;
224
233
  const platformName = this.platform.name || "unknown";
225
234
  const shortPubKey = stamperInfo.publicKey.slice(0, 8);
226
- const authenticatorName = `${platformName}-${shortPubKey}-${uid}`;
235
+ const organizationName = `${this.config.organizationId}-${platformName}-${shortPubKey}`;
227
236
  this.logger.log("EMBEDDED_PROVIDER", "Creating organization", {
228
237
  organizationName,
229
- authenticatorName,
238
+ publicKey: stamperInfo.publicKey,
230
239
  platform: platformName
231
240
  });
232
- const { organizationId } = await tempClient.createOrganization(organizationName, stamperInfo.publicKey, authenticatorName);
233
- this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId, authenticatorName });
241
+ const base64urlPublicKey = base64urlEncode(bs58.decode(stamperInfo.publicKey));
242
+ const { organizationId } = await tempClient.createOrganization(
243
+ organizationName,
244
+ [{
245
+ username: `user-${shortPubKey}`,
246
+ role: "admin",
247
+ authenticators: [{
248
+ authenticatorName: `auth-${shortPubKey}`,
249
+ authenticatorKind: "keypair",
250
+ publicKey: base64urlPublicKey,
251
+ algorithm: "Ed25519"
252
+ }]
253
+ }]
254
+ );
255
+ this.logger.info("EMBEDDED_PROVIDER", "Organization created", { organizationId });
234
256
  return { organizationId, stamperInfo };
235
257
  }
236
258
  async connect(authOptions) {
@@ -315,29 +337,52 @@ var EmbeddedProvider = class {
315
337
  this.client = null;
316
338
  this.walletId = null;
317
339
  this.addresses = [];
340
+ this.logger.info("EMBEDDED_PROVIDER", "Disconnected from embedded wallet");
318
341
  }
319
342
  async signMessage(params) {
320
343
  if (!this.client || !this.walletId) {
321
344
  throw new Error("Not connected");
322
345
  }
346
+ this.logger.info("EMBEDDED_PROVIDER", "Signing message", {
347
+ walletId: this.walletId,
348
+ message: params.message
349
+ });
323
350
  const parsedMessage = parseMessage(params.message);
324
351
  const rawResponse = await this.client.signMessage({
325
352
  walletId: this.walletId,
326
353
  message: parsedMessage.base64url,
327
354
  networkId: params.networkId
328
355
  });
356
+ this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
357
+ walletId: this.walletId,
358
+ message: params.message
359
+ });
329
360
  return parseSignMessageResponse(rawResponse, params.networkId);
330
361
  }
331
362
  async signAndSendTransaction(params) {
332
363
  if (!this.client || !this.walletId) {
333
364
  throw new Error("Not connected");
334
365
  }
366
+ this.logger.info("EMBEDDED_PROVIDER", "Signing and sending transaction", {
367
+ walletId: this.walletId,
368
+ networkId: params.networkId
369
+ });
335
370
  const parsedTransaction = await parseTransaction(params.transaction, params.networkId);
371
+ this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
372
+ walletId: this.walletId,
373
+ transaction: parsedTransaction
374
+ });
336
375
  const rawResponse = await this.client.signAndSendTransaction({
337
376
  walletId: this.walletId,
338
377
  transaction: parsedTransaction.base64url,
339
378
  networkId: params.networkId
340
379
  });
380
+ this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
381
+ walletId: this.walletId,
382
+ networkId: params.networkId,
383
+ hash: rawResponse.hash,
384
+ rawTransaction: rawResponse.rawTransaction
385
+ });
341
386
  return await parseTransactionResponse(rawResponse.rawTransaction, params.networkId, rawResponse.hash);
342
387
  }
343
388
  getAddresses() {
@@ -367,6 +412,9 @@ var EmbeddedProvider = class {
367
412
  return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);
368
413
  }
369
414
  } else {
415
+ this.logger.info("EMBEDDED_PROVIDER", "Creating app-wallet", {
416
+ organizationId
417
+ });
370
418
  const tempClient = new PhantomClient(
371
419
  {
372
420
  apiBaseUrl: this.config.apiBaseUrl,
@@ -389,6 +437,7 @@ var EmbeddedProvider = class {
389
437
  lastUsed: now
390
438
  };
391
439
  await this.storage.saveSession(session);
440
+ this.logger.info("EMBEDDED_PROVIDER", "App-wallet created successfully", { walletId, organizationId });
392
441
  return session;
393
442
  }
394
443
  }
@@ -471,7 +520,9 @@ var EmbeddedProvider = class {
471
520
  redirectUrl: this.config.authOptions?.redirectUrl,
472
521
  customAuthData: authOptions?.customAuthData,
473
522
  authUrl: this.config.authOptions?.authUrl,
474
- sessionId
523
+ sessionId,
524
+ appName: this.config.appName,
525
+ appLogo: this.config.appLogo
475
526
  });
476
527
  if (authResult && "walletId" in authResult) {
477
528
  this.logger.info("EMBEDDED_PROVIDER", "Authentication completed after redirect", {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/embedded-provider.ts","../src/auth/jwt-auth.ts","../src/utils/session.ts","../src/utils/retry.ts"],"sourcesContent":["import { PhantomClient } from \"@phantom/client\";\nimport type { AddressType } from \"@phantom/client\";\nimport { parseMessage, parseTransaction, parseSignMessageResponse, parseTransactionResponse,type ParsedTransactionResult, type ParsedSignatureResult } from \"@phantom/parsers\";\n\nimport type {\n PlatformAdapter,\n Session,\n AuthResult,\n DebugLogger,\n EmbeddedStorage,\n AuthProvider,\n URLParamsAccessor,\n StamperInfo,\n} from \"./interfaces\";\nimport type {\n EmbeddedProviderConfig,\n ConnectResult,\n SignMessageParams,\n SignAndSendTransactionParams,\n WalletAddress,\n AuthOptions,\n} from \"./types\";\nimport { JWTAuth } from \"./auth/jwt-auth\";\nimport { generateSessionId } from \"./utils/session\";\nimport { retryWithBackoff } from \"./utils/retry\";\nimport type { StamperWithKeyManagement } from \"@phantom/sdk-types\";\nexport class EmbeddedProvider {\n private config: EmbeddedProviderConfig;\n private platform: PlatformAdapter;\n private storage: EmbeddedStorage;\n private authProvider: AuthProvider;\n private urlParamsAccessor: URLParamsAccessor;\n private stamper: StamperWithKeyManagement;\n private logger: DebugLogger;\n private client: PhantomClient | null = null;\n private walletId: string | null = null;\n private addresses: WalletAddress[] = [];\n private jwtAuth: JWTAuth;\n\n constructor(config: EmbeddedProviderConfig, platform: PlatformAdapter, logger: DebugLogger) {\n this.logger = logger;\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing EmbeddedProvider\", { config });\n\n this.config = config;\n this.platform = platform;\n this.storage = platform.storage;\n this.authProvider = platform.authProvider;\n this.urlParamsAccessor = platform.urlParamsAccessor;\n this.stamper = platform.stamper;\n this.jwtAuth = new JWTAuth();\n\n // Store solana provider config (unused for now)\n config.solanaProvider;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n }\n\n private async getAndFilterWalletAddresses(walletId: string): Promise<WalletAddress[]> {\n // Get wallet addresses with retry and auto-disconnect on failure\n const addresses = await retryWithBackoff(\n () => this.client!.getWalletAddresses(walletId),\n \"getWalletAddresses\",\n this.logger,\n ).catch(async error => {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"getWalletAddresses failed after retries, disconnecting\", {\n walletId,\n error: error.message,\n });\n // Clear the session if getWalletAddresses fails after retries\n await this.storage.clearSession();\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n throw error;\n });\n\n // Filter by enabled address types and return formatted addresses\n return addresses\n .filter(addr => this.config.addressTypes.some(type => type === addr.addressType))\n .map(addr => ({\n addressType: addr.addressType as AddressType,\n address: addr.address,\n }));\n }\n\n /*\n * We use this method to make sure the session is not invalid, or there's a different session id in the url.\n * If there's a different one, we delete the current session and start from scratch.\n * This prevents issues where users have stale sessions or URL mismatches after redirects.\n */\n private async validateAndCleanSession(session: Session | null): Promise<Session | null> {\n if (!session) return null;\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Found existing session, validating\", {\n sessionId: session.sessionId,\n status: session.status,\n walletId: session.walletId,\n });\n\n // If session is not completed, check if we're in the right context\n if (session.status !== \"completed\") {\n const urlSessionId = this.urlParamsAccessor.getParam(\"session_id\");\n\n // If we have a pending session but no sessionId in URL, this is a mismatch\n if (session.status === \"pending\" && !urlSessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session mismatch detected - pending session without redirect context\", {\n sessionId: session.sessionId,\n status: session.status,\n });\n // Clear the invalid session and start fresh\n await this.storage.clearSession();\n return null;\n }\n // If sessionId in URL doesn't match stored session, clear invalid session\n else if (urlSessionId && urlSessionId !== session.sessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session ID mismatch detected\", {\n storedSessionId: session.sessionId,\n urlSessionId: urlSessionId,\n });\n await this.storage.clearSession();\n return null;\n }\n }\n\n return session;\n }\n\n /*\n * We use this method to validate authentication options before processing them.\n * This ensures only supported auth providers are used and required tokens are present.\n */\n private validateAuthOptions(authOptions?: AuthOptions): void {\n if (!authOptions) return;\n\n if (authOptions.provider && ![\"google\", \"apple\", \"jwt\"].includes(authOptions.provider)) {\n throw new Error(`Invalid auth provider: ${authOptions.provider}. Must be \"google\", \"apple\", or \"jwt\"`);\n }\n\n if (authOptions.provider === \"jwt\" && !authOptions.jwtToken) {\n throw new Error(\"JWT token is required when using JWT authentication\");\n }\n }\n\n /*\n * We use this method to initialize the stamper and create an organization for new sessions.\n * This is the first step when no existing session is found and we need to set up a new wallet.\n */\n private async createOrganizationAndStamper(): Promise<{ organizationId: string; stamperInfo: StamperInfo }> {\n // Initialize stamper (generates keypair in IndexedDB)\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing stamper\");\n const stamperInfo = await this.stamper.init();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Stamper initialized\", { publicKey: stamperInfo.publicKey, keyId: stamperInfo.keyId, algorithm: this.stamper.algorithm });\n\n // Create a temporary client with the stamper\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating temporary PhantomClient\");\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n },\n this.stamper,\n );\n\n // Create an organization\n // organization name is a combination of this organizationId and this userId, which will be a unique identifier\n const uid = Date.now(); // for now\n const organizationName = `${this.config.organizationId}-${uid}`;\n \n // Create authenticator name with platform info and public key for identification\n const platformName = this.platform.name || \"unknown\";\n const shortPubKey = stamperInfo.publicKey.slice(0, 8); // First 8 chars of public key\n const authenticatorName = `${platformName}-${shortPubKey}-${uid}`;\n \n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating organization\", { \n organizationName, \n authenticatorName, \n platform: platformName \n });\n \n const { organizationId } = await tempClient.createOrganization(organizationName, stamperInfo.publicKey, authenticatorName);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId, authenticatorName });\n\n return { organizationId, stamperInfo };\n }\n\n async connect(authOptions?: AuthOptions): Promise<ConnectResult> {\n try {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting embedded provider connect\", {\n authOptions: authOptions\n ? {\n provider: authOptions.provider,\n hasJwtToken: !!authOptions.jwtToken,\n }\n : undefined,\n });\n\n // Get and validate existing session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Getting existing session\");\n let session = await this.storage.getSession();\n session = await this.validateAndCleanSession(session);\n\n // First, check if we're resuming from a redirect\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking for redirect resume\");\n if (this.authProvider.resumeAuthFromRedirect) {\n const authResult = this.authProvider.resumeAuthFromRedirect();\n if (authResult) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Resuming from redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n return this.completeAuthConnection(authResult);\n }\n }\n\n // Validate auth options\n this.validateAuthOptions(authOptions);\n\n // If no session exists, create new one\n if (!session) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing session, creating new one\");\n const { organizationId, stamperInfo } = await this.createOrganizationAndStamper();\n session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions);\n }\n\n // If session is null here, it means we're doing a redirect\n if (!session) {\n // This should not return anything as redirect is happening\n return {\n addresses: [],\n status: \"pending\",\n } as ConnectResult;\n }\n\n // Update session last used timestamp (only for non-redirect flows)\n // For redirect flows, timestamp is updated before redirect to prevent race condition\n if (!authOptions || authOptions.provider === \"jwt\" || this.config.embeddedWalletType === \"app-wallet\") {\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n }\n\n // Initialize client and get addresses\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n } catch (error) {\n // Log the full error details for debugging\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Connect failed with error\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n\n // Enhanced error handling with specific error types\n if (error instanceof Error) {\n // Check for specific error types and provide better error messages\n if (error.message.includes(\"IndexedDB\") || error.message.includes(\"storage\")) {\n throw new Error(\n \"Storage error: Unable to access browser storage. Please ensure storage is available and try again.\",\n );\n }\n\n if (error.message.includes(\"network\") || error.message.includes(\"fetch\")) {\n throw new Error(\n \"Network error: Unable to connect to authentication server. Please check your internet connection and try again.\",\n );\n }\n\n if (error.message.includes(\"JWT\") || error.message.includes(\"jwt\")) {\n throw new Error(`JWT Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"Authentication\") || error.message.includes(\"auth\")) {\n throw new Error(`Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"organization\") || error.message.includes(\"wallet\")) {\n throw new Error(`Wallet creation error: ${error.message}`);\n }\n\n // Re-throw the original error if it's already well-formatted\n throw error;\n }\n\n // Handle unknown error types\n throw new Error(`Embedded wallet connection failed: ${String(error)}`);\n }\n }\n\n async disconnect(): Promise<void> {\n await this.storage.clearSession();\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Parse message to base64url format for client\n const parsedMessage = parseMessage(params.message);\n\n // Get raw response from client\n const rawResponse = await this.client.signMessage({\n walletId: this.walletId,\n message: parsedMessage.base64url,\n networkId: params.networkId,\n });\n\n // Parse the response to get human-readable signature and explorer URL\n return parseSignMessageResponse(rawResponse, params.networkId);\n }\n\n async signAndSendTransaction(params: SignAndSendTransactionParams): Promise<ParsedTransactionResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Parse transaction to base64url format for client based on network\n const parsedTransaction = await parseTransaction(params.transaction, params.networkId);\n\n // Get raw response from client\n const rawResponse = await this.client.signAndSendTransaction({\n walletId: this.walletId,\n transaction: parsedTransaction.base64url,\n networkId: params.networkId,\n });\n\n // Parse the response to get transaction hash and explorer URL\n return await parseTransactionResponse(rawResponse.rawTransaction, params.networkId, rawResponse.hash);\n }\n\n getAddresses(): WalletAddress[] {\n return this.addresses;\n }\n\n isConnected(): boolean {\n return this.client !== null && this.walletId !== null;\n }\n\n /*\n * We use this method to route between different authentication flows based on wallet type and auth options.\n * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.\n * Returns null for redirect flows since they don't complete synchronously.\n */\n private async handleAuthFlow(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions?: AuthOptions,\n ): Promise<Session | null> {\n if (this.config.embeddedWalletType === \"user-wallet\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Creating user-wallet, routing authentication\", {\n authProvider: authOptions?.provider || \"phantom-connect\",\n });\n\n // Route to appropriate authentication flow based on authOptions\n if (authOptions?.provider === \"jwt\") {\n return await this.handleJWTAuth(organizationId, stamperInfo, authOptions);\n } else {\n // This will redirect in browser, so we don't return a session\n // In react-native this will return an auth result\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting redirect-based authentication flow\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n });\n return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);\n \n }\n } else {\n // Create app-wallet directly\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: organizationId,\n },\n this.stamper,\n );\n\n const wallet = await tempClient.createWallet(`Wallet ${Date.now()}`);\n const walletId = wallet.walletId;\n\n // Save session with app-wallet info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"app-wallet\",\n userInfo: { embeddedWalletType: this.config.embeddedWalletType },\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n await this.storage.saveSession(session);\n return session;\n }\n }\n\n /*\n * We use this method to handle JWT-based authentication for user-wallets.\n * It authenticates using the provided JWT token and creates a completed session.\n */\n private async handleJWTAuth(organizationId: string, stamperInfo: StamperInfo, authOptions: AuthOptions): Promise<Session> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using JWT authentication flow\");\n\n // Use JWT authentication flow\n if (!authOptions.jwtToken) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"JWT token missing for JWT authentication\");\n throw new Error(\"JWT token is required for JWT authentication\");\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting JWT authentication\");\n const authResult = await this.jwtAuth.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n jwtToken: authOptions.jwtToken,\n customAuthData: authOptions.customAuthData,\n });\n const walletId = authResult.walletId;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"JWT authentication completed\", { walletId });\n\n // Save session with auth info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: authResult.provider,\n userInfo: authResult.userInfo,\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving JWT session\");\n await this.storage.saveSession(session);\n return session;\n }\n\n /*\n * We use this method to handle redirect-based authentication (Google/Apple OAuth).\n * It saves a temporary session before redirecting to prevent losing state during the redirect flow.\n * Session timestamp is updated before redirect to prevent race conditions.\n */\n private async handleRedirectAuth(organizationId: string, stamperInfo: StamperInfo, authOptions?: AuthOptions): Promise<Session | null> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using Phantom Connect authentication flow (redirect-based)\", {\n provider: authOptions?.provider,\n hasRedirectUrl: !!this.config.authOptions?.redirectUrl,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Use Phantom Connect authentication flow (redirect-based)\n // Store session before redirect so we can restore it after redirect\n const now = Date.now();\n const sessionId = generateSessionId();\n const tempSession: Session = {\n sessionId: sessionId,\n walletId: `temp-${now}`, // Temporary ID, will be updated after redirect\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"phantom-connect\",\n userInfo: { provider: authOptions?.provider },\n status: \"pending\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving temporary session before redirect\", {\n sessionId: tempSession.sessionId,\n tempWalletId: tempSession.walletId,\n });\n\n // Update session timestamp before redirect (prevents race condition)\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting Phantom Connect redirect\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Start the authentication flow (this will redirect the user in the browser, or handle it in React Native)\n const authResult = await this.authProvider.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider as \"google\" | \"apple\" | undefined,\n redirectUrl: this.config.authOptions?.redirectUrl,\n customAuthData: authOptions?.customAuthData,\n authUrl: this.config.authOptions?.authUrl,\n sessionId: sessionId,\n });\n\n if (authResult && \"walletId\" in authResult) {\n // If we got an auth result, we need to update the session with actual wallet ID\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authentication completed after redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n\n // Update the temporary session with actual wallet ID and auth info\n tempSession.walletId = authResult.walletId;\n tempSession.authProvider = authResult.provider || tempSession.authProvider;\n tempSession.status = \"completed\";\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n return tempSession; // Return the auth result for further processing\n }\n // If we don't have an auth result, it means we're in a redirect flow\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Redirect authentication initiated, waiting for redirect completion\");\n // In this case, we don't return anything as the redirect will handle the rest\n return null;\n }\n\n private async completeAuthConnection(authResult: AuthResult): Promise<ConnectResult> {\n // Check if we have an existing session\n const session = await this.storage.getSession();\n\n if (!session) {\n throw new Error(\"No session found after redirect - session may have expired\");\n }\n\n // Update session with actual wallet ID and auth info from redirect\n session.walletId = authResult.walletId;\n session.authProvider = authResult.provider || session.authProvider;\n session.status = \"completed\";\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * We use this method to initialize the PhantomClient and fetch wallet addresses from a completed session.\n * This is the final step that sets up the provider's client state and retrieves available addresses.\n */\n private async initializeClientFromSession(session: Session): Promise<void> {\n // Create client from session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing PhantomClient from session\", {\n organizationId: session.organizationId,\n walletId: session.walletId,\n });\n\n // Ensure stamper is initialized with existing keys\n if (!this.stamper.getKeyInfo()) {\n await this.stamper.init();\n }\n\n this.client = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: session.organizationId,\n },\n this.stamper,\n );\n\n this.walletId = session.walletId;\n\n // Get wallet addresses and filter by enabled address types with retry\n this.addresses = await this.getAndFilterWalletAddresses(session.walletId);\n }\n}\n","import type { AuthResult, JWTAuthOptions } from \"../interfaces\";\n\nexport class JWTAuth {\n async authenticate(options: JWTAuthOptions): Promise<AuthResult> {\n // Validate JWT token format\n if (!options.jwtToken || typeof options.jwtToken !== \"string\") {\n throw new Error(\"Invalid JWT token: token must be a non-empty string\");\n }\n\n // Basic JWT format validation (3 parts separated by dots)\n const jwtParts = options.jwtToken.split(\".\");\n if (jwtParts.length !== 3) {\n throw new Error(\"Invalid JWT token format: token must have 3 parts separated by dots\");\n }\n\n // JWT authentication flow - direct API call to create wallet with JWT\n try {\n // This would typically make an API call to your backend\n // which would validate the JWT and create/retrieve the wallet\n const response = await fetch(\"/api/auth/jwt\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${options.jwtToken}`,\n },\n body: JSON.stringify({\n organizationId: options.organizationId,\n parentOrganizationId: options.parentOrganizationId,\n customAuthData: options.customAuthData,\n }),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.error || errorMessage;\n } catch {\n errorMessage = response.statusText || errorMessage;\n }\n\n switch (response.status) {\n case 400:\n throw new Error(`Invalid JWT authentication request: ${errorMessage}`);\n case 401:\n throw new Error(`JWT token is invalid or expired: ${errorMessage}`);\n case 403:\n throw new Error(`JWT authentication forbidden: ${errorMessage}`);\n case 404:\n throw new Error(`JWT authentication endpoint not found: ${errorMessage}`);\n case 429:\n throw new Error(`Too many JWT authentication requests: ${errorMessage}`);\n case 500:\n case 502:\n case 503:\n case 504:\n throw new Error(`JWT authentication server error: ${errorMessage}`);\n default:\n throw new Error(`JWT authentication failed: ${errorMessage}`);\n }\n }\n\n let result;\n try {\n result = await response.json();\n } catch (parseError) {\n throw new Error(\"Invalid response from JWT authentication server: response is not valid JSON\");\n }\n\n if (!result.walletId) {\n throw new Error(\"Invalid JWT authentication response: missing walletId\");\n }\n\n return {\n walletId: result.walletId,\n provider: \"jwt\",\n userInfo: result.userInfo || {},\n };\n } catch (error) {\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n throw new Error(\"JWT authentication failed: network error or invalid endpoint\");\n }\n\n if (error instanceof Error) {\n throw error; // Re-throw known errors\n }\n\n throw new Error(`JWT authentication error: ${String(error)}`);\n }\n }\n}\n","export function generateSessionId(): string {\n return (\n \"session_\" +\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15) +\n \"_\" +\n Date.now()\n );\n}\n","import type { DebugLogger } from \"../interfaces\";\n\nexport async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n operationName: string,\n logger: DebugLogger,\n maxRetries: number = 3,\n baseDelay: number = 1000,\n): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n logger.log(\"EMBEDDED_PROVIDER\", `Attempting ${operationName}`, {\n attempt,\n maxRetries,\n });\n return await operation();\n } catch (error) {\n lastError = error as Error;\n logger.warn(\"EMBEDDED_PROVIDER\", `${operationName} failed`, {\n attempt,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n if (attempt === maxRetries) {\n logger.error(\"EMBEDDED_PROVIDER\", `${operationName} failed after ${maxRetries} attempts`, {\n finalError: error instanceof Error ? error.message : String(error),\n });\n break;\n }\n\n // Exponential backoff: 1s, 2s, 4s\n const delay = baseDelay * Math.pow(2, attempt - 1);\n logger.log(\"EMBEDDED_PROVIDER\", `Retrying ${operationName} in ${delay}ms`, {\n attempt: attempt + 1,\n delay,\n });\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError!;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/embedded-provider.ts","../src/auth/jwt-auth.ts","../src/utils/session.ts","../src/utils/retry.ts"],"sourcesContent":["import { PhantomClient } from \"@phantom/client\";\nimport type { AddressType } from \"@phantom/client\";\nimport { base64urlEncode } from \"@phantom/base64url\";\nimport bs58 from \"bs58\";\nimport {\n parseMessage,\n parseTransaction,\n parseSignMessageResponse,\n parseTransactionResponse,\n type ParsedTransactionResult,\n type ParsedSignatureResult,\n} from \"@phantom/parsers\";\n\nimport type {\n PlatformAdapter,\n Session,\n AuthResult,\n DebugLogger,\n EmbeddedStorage,\n AuthProvider,\n URLParamsAccessor,\n StamperInfo,\n} from \"./interfaces\";\nimport type {\n EmbeddedProviderConfig,\n ConnectResult,\n SignMessageParams,\n SignAndSendTransactionParams,\n WalletAddress,\n AuthOptions,\n} from \"./types\";\nimport { JWTAuth } from \"./auth/jwt-auth\";\nimport { generateSessionId } from \"./utils/session\";\nimport { retryWithBackoff } from \"./utils/retry\";\nimport type { StamperWithKeyManagement } from \"@phantom/sdk-types\";\nexport class EmbeddedProvider {\n private config: EmbeddedProviderConfig;\n private platform: PlatformAdapter;\n private storage: EmbeddedStorage;\n private authProvider: AuthProvider;\n private urlParamsAccessor: URLParamsAccessor;\n private stamper: StamperWithKeyManagement;\n private logger: DebugLogger;\n private client: PhantomClient | null = null;\n private walletId: string | null = null;\n private addresses: WalletAddress[] = [];\n private jwtAuth: JWTAuth;\n\n constructor(config: EmbeddedProviderConfig, platform: PlatformAdapter, logger: DebugLogger) {\n this.logger = logger;\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing EmbeddedProvider\", { config });\n\n this.config = config;\n this.platform = platform;\n this.storage = platform.storage;\n this.authProvider = platform.authProvider;\n this.urlParamsAccessor = platform.urlParamsAccessor;\n this.stamper = platform.stamper;\n this.jwtAuth = new JWTAuth();\n\n // Store solana provider config (unused for now)\n config.solanaProvider;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n }\n\n private async getAndFilterWalletAddresses(walletId: string): Promise<WalletAddress[]> {\n // Get wallet addresses with retry and auto-disconnect on failure\n const addresses = await retryWithBackoff(\n () => this.client!.getWalletAddresses(walletId),\n \"getWalletAddresses\",\n this.logger,\n ).catch(async error => {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"getWalletAddresses failed after retries, disconnecting\", {\n walletId,\n error: error.message,\n });\n // Clear the session if getWalletAddresses fails after retries\n await this.storage.clearSession();\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n throw error;\n });\n\n // Filter by enabled address types and return formatted addresses\n return addresses\n .filter(addr => this.config.addressTypes.some(type => type === addr.addressType))\n .map(addr => ({\n addressType: addr.addressType as AddressType,\n address: addr.address,\n }));\n }\n\n /*\n * We use this method to make sure the session is not invalid, or there's a different session id in the url.\n * If there's a different one, we delete the current session and start from scratch.\n * This prevents issues where users have stale sessions or URL mismatches after redirects.\n */\n private async validateAndCleanSession(session: Session | null): Promise<Session | null> {\n if (!session) return null;\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Found existing session, validating\", {\n sessionId: session.sessionId,\n status: session.status,\n walletId: session.walletId,\n });\n\n // If session is not completed, check if we're in the right context\n if (session.status !== \"completed\") {\n const urlSessionId = this.urlParamsAccessor.getParam(\"session_id\");\n\n // If we have a pending session but no sessionId in URL, this is a mismatch\n if (session.status === \"pending\" && !urlSessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session mismatch detected - pending session without redirect context\", {\n sessionId: session.sessionId,\n status: session.status,\n });\n // Clear the invalid session and start fresh\n await this.storage.clearSession();\n return null;\n }\n // If sessionId in URL doesn't match stored session, clear invalid session\n else if (urlSessionId && urlSessionId !== session.sessionId) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session ID mismatch detected\", {\n storedSessionId: session.sessionId,\n urlSessionId: urlSessionId,\n });\n await this.storage.clearSession();\n return null;\n }\n }\n\n return session;\n }\n\n /*\n * We use this method to validate authentication options before processing them.\n * This ensures only supported auth providers are used and required tokens are present.\n */\n private validateAuthOptions(authOptions?: AuthOptions): void {\n if (!authOptions) return;\n\n if (authOptions.provider && ![\"google\", \"apple\", \"jwt\"].includes(authOptions.provider)) {\n throw new Error(`Invalid auth provider: ${authOptions.provider}. Must be \"google\", \"apple\", or \"jwt\"`);\n }\n\n if (authOptions.provider === \"jwt\" && !authOptions.jwtToken) {\n throw new Error(\"JWT token is required when using JWT authentication\");\n }\n }\n\n /*\n * We use this method to initialize the stamper and create an organization for new sessions.\n * This is the first step when no existing session is found and we need to set up a new wallet.\n */\n private async createOrganizationAndStamper(): Promise<{ organizationId: string; stamperInfo: StamperInfo }> {\n // Initialize stamper (generates keypair in IndexedDB)\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing stamper\");\n const stamperInfo = await this.stamper.init();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Stamper initialized\", {\n publicKey: stamperInfo.publicKey,\n keyId: stamperInfo.keyId,\n algorithm: this.stamper.algorithm,\n });\n\n // Create a temporary client with the stamper\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating temporary PhantomClient\");\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n },\n this.stamper,\n );\n\n // Create an organization\n // organization name is a combination of this organizationId and this userId, which will be a unique identifier\n const platformName = this.platform.name || \"unknown\";\n const shortPubKey = stamperInfo.publicKey.slice(0, 8);\n const organizationName = `${this.config.organizationId}-${platformName}-${shortPubKey}`;\n\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Creating organization\", {\n organizationName,\n publicKey: stamperInfo.publicKey,\n platform: platformName,\n });\n\n // Convert base58 public key to base64url format as required by the API\n const base64urlPublicKey = base64urlEncode(bs58.decode(stamperInfo.publicKey));\n \n const { organizationId } = await tempClient.createOrganization(\n organizationName,\n [{\n username: `user-${shortPubKey}`,\n role: 'admin',\n authenticators: [{\n authenticatorName: `auth-${shortPubKey}`,\n authenticatorKind: 'keypair',\n publicKey: base64urlPublicKey,\n algorithm: 'Ed25519',\n }]\n }]\n );\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId });\n\n return { organizationId, stamperInfo };\n }\n\n async connect(authOptions?: AuthOptions): Promise<ConnectResult> {\n try {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting embedded provider connect\", {\n authOptions: authOptions\n ? {\n provider: authOptions.provider,\n hasJwtToken: !!authOptions.jwtToken,\n }\n : undefined,\n });\n\n // Get and validate existing session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Getting existing session\");\n let session = await this.storage.getSession();\n session = await this.validateAndCleanSession(session);\n\n // First, check if we're resuming from a redirect\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking for redirect resume\");\n if (this.authProvider.resumeAuthFromRedirect) {\n const authResult = this.authProvider.resumeAuthFromRedirect();\n if (authResult) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Resuming from redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n return this.completeAuthConnection(authResult);\n }\n }\n\n // Validate auth options\n this.validateAuthOptions(authOptions);\n\n // If no session exists, create new one\n if (!session) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing session, creating new one\");\n const { organizationId, stamperInfo } = await this.createOrganizationAndStamper();\n session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions);\n }\n\n // If session is null here, it means we're doing a redirect\n if (!session) {\n // This should not return anything as redirect is happening\n return {\n addresses: [],\n status: \"pending\",\n } as ConnectResult;\n }\n\n // Update session last used timestamp (only for non-redirect flows)\n // For redirect flows, timestamp is updated before redirect to prevent race condition\n if (!authOptions || authOptions.provider === \"jwt\" || this.config.embeddedWalletType === \"app-wallet\") {\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n }\n\n // Initialize client and get addresses\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n } catch (error) {\n // Log the full error details for debugging\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Connect failed with error\", {\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : error,\n });\n\n // Enhanced error handling with specific error types\n if (error instanceof Error) {\n // Check for specific error types and provide better error messages\n if (error.message.includes(\"IndexedDB\") || error.message.includes(\"storage\")) {\n throw new Error(\n \"Storage error: Unable to access browser storage. Please ensure storage is available and try again.\",\n );\n }\n\n if (error.message.includes(\"network\") || error.message.includes(\"fetch\")) {\n throw new Error(\n \"Network error: Unable to connect to authentication server. Please check your internet connection and try again.\",\n );\n }\n\n if (error.message.includes(\"JWT\") || error.message.includes(\"jwt\")) {\n throw new Error(`JWT Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"Authentication\") || error.message.includes(\"auth\")) {\n throw new Error(`Authentication error: ${error.message}`);\n }\n\n if (error.message.includes(\"organization\") || error.message.includes(\"wallet\")) {\n throw new Error(`Wallet creation error: ${error.message}`);\n }\n\n // Re-throw the original error if it's already well-formatted\n throw error;\n }\n\n // Handle unknown error types\n throw new Error(`Embedded wallet connection failed: ${String(error)}`);\n }\n }\n\n async disconnect(): Promise<void> {\n await this.storage.clearSession();\n\n this.client = null;\n this.walletId = null;\n this.addresses = [];\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Disconnected from embedded wallet\");\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Signing message\", {\n walletId: this.walletId,\n message: params.message,\n });\n\n // Parse message to base64url format for client\n const parsedMessage = parseMessage(params.message);\n\n // Get raw response from client\n const rawResponse = await this.client.signMessage({\n walletId: this.walletId,\n message: parsedMessage.base64url,\n networkId: params.networkId,\n });\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Message signed successfully\", {\n walletId: this.walletId,\n message: params.message,\n });\n\n // Parse the response to get human-readable signature and explorer URL\n return parseSignMessageResponse(rawResponse, params.networkId);\n }\n\n async signAndSendTransaction(params: SignAndSendTransactionParams): Promise<ParsedTransactionResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Signing and sending transaction\", {\n walletId: this.walletId,\n networkId: params.networkId,\n });\n\n // Parse transaction to base64url format for client based on network\n const parsedTransaction = await parseTransaction(params.transaction, params.networkId);\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Parsed transaction for signing\", {\n walletId: this.walletId,\n transaction: parsedTransaction,\n });\n\n // Get raw response from client\n const rawResponse = await this.client.signAndSendTransaction({\n walletId: this.walletId,\n transaction: parsedTransaction.base64url,\n networkId: params.networkId,\n });\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Transaction signed and sent successfully\", {\n walletId: this.walletId,\n networkId: params.networkId,\n hash: rawResponse.hash,\n rawTransaction: rawResponse.rawTransaction,\n });\n\n // Parse the response to get transaction hash and explorer URL\n return await parseTransactionResponse(rawResponse.rawTransaction, params.networkId, rawResponse.hash);\n }\n\n getAddresses(): WalletAddress[] {\n return this.addresses;\n }\n\n isConnected(): boolean {\n return this.client !== null && this.walletId !== null;\n }\n\n /*\n * We use this method to route between different authentication flows based on wallet type and auth options.\n * It handles app-wallet creation directly or routes to JWT/redirect authentication for user-wallets.\n * Returns null for redirect flows since they don't complete synchronously.\n */\n private async handleAuthFlow(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions?: AuthOptions,\n ): Promise<Session | null> {\n if (this.config.embeddedWalletType === \"user-wallet\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Creating user-wallet, routing authentication\", {\n authProvider: authOptions?.provider || \"phantom-connect\",\n });\n\n // Route to appropriate authentication flow based on authOptions\n if (authOptions?.provider === \"jwt\") {\n return await this.handleJWTAuth(organizationId, stamperInfo, authOptions);\n } else {\n // This will redirect in browser, so we don't return a session\n // In react-native this will return an auth result\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting redirect-based authentication flow\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n });\n return await this.handleRedirectAuth(organizationId, stamperInfo, authOptions);\n }\n } else {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Creating app-wallet\", {\n organizationId,\n });\n // Create app-wallet directly\n const tempClient = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: organizationId,\n },\n this.stamper,\n );\n\n const wallet = await tempClient.createWallet(`Wallet ${Date.now()}`);\n const walletId = wallet.walletId;\n\n // Save session with app-wallet info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"app-wallet\",\n userInfo: { embeddedWalletType: this.config.embeddedWalletType },\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"App-wallet created successfully\", { walletId, organizationId });\n return session;\n }\n }\n\n /*\n * We use this method to handle JWT-based authentication for user-wallets.\n * It authenticates using the provided JWT token and creates a completed session.\n */\n private async handleJWTAuth(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions: AuthOptions,\n ): Promise<Session> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using JWT authentication flow\");\n\n // Use JWT authentication flow\n if (!authOptions.jwtToken) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"JWT token missing for JWT authentication\");\n throw new Error(\"JWT token is required for JWT authentication\");\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting JWT authentication\");\n const authResult = await this.jwtAuth.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n jwtToken: authOptions.jwtToken,\n customAuthData: authOptions.customAuthData,\n });\n const walletId = authResult.walletId;\n this.logger.info(\"EMBEDDED_PROVIDER\", \"JWT authentication completed\", { walletId });\n\n // Save session with auth info\n const now = Date.now();\n const session = {\n sessionId: generateSessionId(),\n walletId: walletId,\n organizationId: organizationId,\n stamperInfo,\n authProvider: authResult.provider,\n userInfo: authResult.userInfo,\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving JWT session\");\n await this.storage.saveSession(session);\n return session;\n }\n\n /*\n * We use this method to handle redirect-based authentication (Google/Apple OAuth).\n * It saves a temporary session before redirecting to prevent losing state during the redirect flow.\n * Session timestamp is updated before redirect to prevent race conditions.\n */\n private async handleRedirectAuth(\n organizationId: string,\n stamperInfo: StamperInfo,\n authOptions?: AuthOptions,\n ): Promise<Session | null> {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using Phantom Connect authentication flow (redirect-based)\", {\n provider: authOptions?.provider,\n hasRedirectUrl: !!this.config.authOptions?.redirectUrl,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Use Phantom Connect authentication flow (redirect-based)\n // Store session before redirect so we can restore it after redirect\n const now = Date.now();\n const sessionId = generateSessionId();\n const tempSession: Session = {\n sessionId: sessionId,\n walletId: `temp-${now}`, // Temporary ID, will be updated after redirect\n organizationId: organizationId,\n stamperInfo,\n authProvider: \"phantom-connect\",\n userInfo: { provider: authOptions?.provider },\n status: \"pending\" as const,\n createdAt: now,\n lastUsed: now,\n };\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Saving temporary session before redirect\", {\n sessionId: tempSession.sessionId,\n tempWalletId: tempSession.walletId,\n });\n\n // Update session timestamp before redirect (prevents race condition)\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting Phantom Connect redirect\", {\n organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider,\n authUrl: this.config.authOptions?.authUrl,\n });\n\n // Start the authentication flow (this will redirect the user in the browser, or handle it in React Native)\n const authResult = await this.authProvider.authenticate({\n organizationId: organizationId,\n parentOrganizationId: this.config.organizationId,\n provider: authOptions?.provider as \"google\" | \"apple\" | undefined,\n redirectUrl: this.config.authOptions?.redirectUrl,\n customAuthData: authOptions?.customAuthData,\n authUrl: this.config.authOptions?.authUrl,\n sessionId: sessionId,\n appName: this.config.appName,\n appLogo: this.config.appLogo,\n });\n\n if (authResult && \"walletId\" in authResult) {\n // If we got an auth result, we need to update the session with actual wallet ID\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authentication completed after redirect\", {\n walletId: authResult.walletId,\n provider: authResult.provider,\n });\n\n // Update the temporary session with actual wallet ID and auth info\n tempSession.walletId = authResult.walletId;\n tempSession.authProvider = authResult.provider || tempSession.authProvider;\n tempSession.status = \"completed\";\n tempSession.lastUsed = Date.now();\n await this.storage.saveSession(tempSession);\n\n return tempSession; // Return the auth result for further processing\n }\n // If we don't have an auth result, it means we're in a redirect flow\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Redirect authentication initiated, waiting for redirect completion\");\n // In this case, we don't return anything as the redirect will handle the rest\n return null;\n }\n\n private async completeAuthConnection(authResult: AuthResult): Promise<ConnectResult> {\n // Check if we have an existing session\n const session = await this.storage.getSession();\n\n if (!session) {\n throw new Error(\"No session found after redirect - session may have expired\");\n }\n\n // Update session with actual wallet ID and auth info from redirect\n session.walletId = authResult.walletId;\n session.authProvider = authResult.provider || session.authProvider;\n session.status = \"completed\";\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n await this.initializeClientFromSession(session);\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * We use this method to initialize the PhantomClient and fetch wallet addresses from a completed session.\n * This is the final step that sets up the provider's client state and retrieves available addresses.\n */\n private async initializeClientFromSession(session: Session): Promise<void> {\n // Create client from session\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Initializing PhantomClient from session\", {\n organizationId: session.organizationId,\n walletId: session.walletId,\n });\n\n // Ensure stamper is initialized with existing keys\n if (!this.stamper.getKeyInfo()) {\n await this.stamper.init();\n }\n\n this.client = new PhantomClient(\n {\n apiBaseUrl: this.config.apiBaseUrl,\n organizationId: session.organizationId,\n },\n this.stamper,\n );\n\n this.walletId = session.walletId;\n\n // Get wallet addresses and filter by enabled address types with retry\n this.addresses = await this.getAndFilterWalletAddresses(session.walletId);\n }\n}\n","import type { AuthResult, JWTAuthOptions } from \"../interfaces\";\n\nexport class JWTAuth {\n async authenticate(options: JWTAuthOptions): Promise<AuthResult> {\n // Validate JWT token format\n if (!options.jwtToken || typeof options.jwtToken !== \"string\") {\n throw new Error(\"Invalid JWT token: token must be a non-empty string\");\n }\n\n // Basic JWT format validation (3 parts separated by dots)\n const jwtParts = options.jwtToken.split(\".\");\n if (jwtParts.length !== 3) {\n throw new Error(\"Invalid JWT token format: token must have 3 parts separated by dots\");\n }\n\n // JWT authentication flow - direct API call to create wallet with JWT\n try {\n // This would typically make an API call to your backend\n // which would validate the JWT and create/retrieve the wallet\n const response = await fetch(\"/api/auth/jwt\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${options.jwtToken}`,\n },\n body: JSON.stringify({\n organizationId: options.organizationId,\n parentOrganizationId: options.parentOrganizationId,\n customAuthData: options.customAuthData,\n }),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.error || errorMessage;\n } catch {\n errorMessage = response.statusText || errorMessage;\n }\n\n switch (response.status) {\n case 400:\n throw new Error(`Invalid JWT authentication request: ${errorMessage}`);\n case 401:\n throw new Error(`JWT token is invalid or expired: ${errorMessage}`);\n case 403:\n throw new Error(`JWT authentication forbidden: ${errorMessage}`);\n case 404:\n throw new Error(`JWT authentication endpoint not found: ${errorMessage}`);\n case 429:\n throw new Error(`Too many JWT authentication requests: ${errorMessage}`);\n case 500:\n case 502:\n case 503:\n case 504:\n throw new Error(`JWT authentication server error: ${errorMessage}`);\n default:\n throw new Error(`JWT authentication failed: ${errorMessage}`);\n }\n }\n\n let result;\n try {\n result = await response.json();\n } catch (parseError) {\n throw new Error(\"Invalid response from JWT authentication server: response is not valid JSON\");\n }\n\n if (!result.walletId) {\n throw new Error(\"Invalid JWT authentication response: missing walletId\");\n }\n\n return {\n walletId: result.walletId,\n provider: \"jwt\",\n userInfo: result.userInfo || {},\n };\n } catch (error) {\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n throw new Error(\"JWT authentication failed: network error or invalid endpoint\");\n }\n\n if (error instanceof Error) {\n throw error; // Re-throw known errors\n }\n\n throw new Error(`JWT authentication error: ${String(error)}`);\n }\n }\n}\n","export function generateSessionId(): string {\n return (\n \"session_\" +\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15) +\n \"_\" +\n Date.now()\n );\n}\n","import type { DebugLogger } from \"../interfaces\";\n\nexport async function retryWithBackoff<T>(\n operation: () => Promise<T>,\n operationName: string,\n logger: DebugLogger,\n maxRetries: number = 3,\n baseDelay: number = 1000,\n): Promise<T> {\n let lastError: Error;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n logger.log(\"EMBEDDED_PROVIDER\", `Attempting ${operationName}`, {\n attempt,\n maxRetries,\n });\n return await operation();\n } catch (error) {\n lastError = error as Error;\n logger.warn(\"EMBEDDED_PROVIDER\", `${operationName} failed`, {\n attempt,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n\n if (attempt === maxRetries) {\n logger.error(\"EMBEDDED_PROVIDER\", `${operationName} failed after ${maxRetries} attempts`, {\n finalError: error instanceof Error ? error.message : String(error),\n });\n break;\n }\n\n // Exponential backoff: 1s, 2s, 4s\n const delay = baseDelay * Math.pow(2, attempt - 1);\n logger.log(\"EMBEDDED_PROVIDER\", `Retrying ${operationName} in ${delay}ms`, {\n attempt: attempt + 1,\n delay,\n });\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n\n throw lastError!;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phantom/embedded-provider-core",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Platform-agnostic embedded provider core logic for Phantom Wallet SDK",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -39,11 +39,13 @@
39
39
  "author": "Phantom",
40
40
  "license": "MIT",
41
41
  "dependencies": {
42
- "@phantom/api-key-stamper": "^0.1.2",
43
- "@phantom/client": "^0.1.5",
42
+ "@phantom/api-key-stamper": "^0.1.3",
43
+ "@phantom/base64url": "^0.1.0",
44
+ "@phantom/client": "^0.1.6",
44
45
  "@phantom/constants": "^0.0.2",
45
- "@phantom/parsers": "^0.0.5",
46
- "@phantom/sdk-types": "^0.1.1"
46
+ "@phantom/parsers": "^0.0.6",
47
+ "@phantom/sdk-types": "^0.1.2",
48
+ "bs58": "^6.0.0"
47
49
  },
48
50
  "devDependencies": {
49
51
  "@types/jest": "^29.5.5",