@phantom/embedded-provider-core 0.1.9 → 0.1.10
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 +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +22 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -28,6 +28,7 @@ interface Session {
|
|
|
28
28
|
authenticatorExpiresAt: number;
|
|
29
29
|
lastRenewalAttempt?: number;
|
|
30
30
|
username: string;
|
|
31
|
+
accountDerivationIndex?: number;
|
|
31
32
|
}
|
|
32
33
|
interface EmbeddedStorage {
|
|
33
34
|
getSession(): Promise<Session | null>;
|
|
@@ -59,6 +60,7 @@ interface AuthResult {
|
|
|
59
60
|
walletId: string;
|
|
60
61
|
provider?: string;
|
|
61
62
|
userInfo?: Record<string, any>;
|
|
63
|
+
accountDerivationIndex?: number;
|
|
62
64
|
}
|
|
63
65
|
interface PhantomConnectOptions {
|
|
64
66
|
organizationId: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ interface Session {
|
|
|
28
28
|
authenticatorExpiresAt: number;
|
|
29
29
|
lastRenewalAttempt?: number;
|
|
30
30
|
username: string;
|
|
31
|
+
accountDerivationIndex?: number;
|
|
31
32
|
}
|
|
32
33
|
interface EmbeddedStorage {
|
|
33
34
|
getSession(): Promise<Session | null>;
|
|
@@ -59,6 +60,7 @@ interface AuthResult {
|
|
|
59
60
|
walletId: string;
|
|
60
61
|
provider?: string;
|
|
61
62
|
userInfo?: Record<string, any>;
|
|
63
|
+
accountDerivationIndex?: number;
|
|
62
64
|
}
|
|
63
65
|
interface PhantomConnectOptions {
|
|
64
66
|
organizationId: string;
|
package/dist/index.js
CHANGED
|
@@ -215,14 +215,17 @@ var EmbeddedProvider = class {
|
|
|
215
215
|
}
|
|
216
216
|
}
|
|
217
217
|
async getAndFilterWalletAddresses(walletId) {
|
|
218
|
+
const session = await this.storage.getSession();
|
|
219
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
218
220
|
const addresses = await retryWithBackoff(
|
|
219
|
-
() => this.client.getWalletAddresses(walletId),
|
|
221
|
+
() => this.client.getWalletAddresses(walletId, void 0, derivationIndex),
|
|
220
222
|
"getWalletAddresses",
|
|
221
223
|
this.logger
|
|
222
224
|
).catch(async (error) => {
|
|
223
225
|
this.logger.error("EMBEDDED_PROVIDER", "getWalletAddresses failed after retries, disconnecting", {
|
|
224
226
|
walletId,
|
|
225
|
-
error: error.message
|
|
227
|
+
error: error.message,
|
|
228
|
+
derivationIndex
|
|
226
229
|
});
|
|
227
230
|
await this.storage.clearSession();
|
|
228
231
|
this.client = null;
|
|
@@ -573,10 +576,13 @@ var EmbeddedProvider = class {
|
|
|
573
576
|
message: params.message
|
|
574
577
|
});
|
|
575
578
|
const parsedMessage = (0, import_parsers.parseMessage)(params.message);
|
|
579
|
+
const session = await this.storage.getSession();
|
|
580
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
576
581
|
const rawResponse = await this.client.signMessage({
|
|
577
582
|
walletId: this.walletId,
|
|
578
583
|
message: parsedMessage.base64url,
|
|
579
|
-
networkId: params.networkId
|
|
584
|
+
networkId: params.networkId,
|
|
585
|
+
derivationIndex
|
|
580
586
|
});
|
|
581
587
|
this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
|
|
582
588
|
walletId: this.walletId,
|
|
@@ -594,14 +600,18 @@ var EmbeddedProvider = class {
|
|
|
594
600
|
networkId: params.networkId
|
|
595
601
|
});
|
|
596
602
|
const parsedTransaction = await (0, import_parsers.parseTransaction)(params.transaction, params.networkId);
|
|
603
|
+
const session = await this.storage.getSession();
|
|
604
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
597
605
|
this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
|
|
598
606
|
walletId: this.walletId,
|
|
599
|
-
transaction: parsedTransaction
|
|
607
|
+
transaction: parsedTransaction,
|
|
608
|
+
derivationIndex
|
|
600
609
|
});
|
|
601
610
|
const rawResponse = await this.client.signAndSendTransaction({
|
|
602
611
|
walletId: this.walletId,
|
|
603
612
|
transaction: parsedTransaction.base64url,
|
|
604
|
-
networkId: params.networkId
|
|
613
|
+
networkId: params.networkId,
|
|
614
|
+
derivationIndex
|
|
605
615
|
});
|
|
606
616
|
this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
|
|
607
617
|
walletId: this.walletId,
|
|
@@ -658,6 +668,8 @@ var EmbeddedProvider = class {
|
|
|
658
668
|
stamperInfo,
|
|
659
669
|
authProvider: "app-wallet",
|
|
660
670
|
userInfo: { embeddedWalletType: this.config.embeddedWalletType },
|
|
671
|
+
accountDerivationIndex: 0,
|
|
672
|
+
// App wallets default to index 0
|
|
661
673
|
status: "completed",
|
|
662
674
|
createdAt: now,
|
|
663
675
|
lastUsed: now,
|
|
@@ -698,6 +710,7 @@ var EmbeddedProvider = class {
|
|
|
698
710
|
stamperInfo,
|
|
699
711
|
authProvider: authResult.provider,
|
|
700
712
|
userInfo: authResult.userInfo,
|
|
713
|
+
accountDerivationIndex: authResult.accountDerivationIndex,
|
|
701
714
|
status: "completed",
|
|
702
715
|
createdAt: now,
|
|
703
716
|
lastUsed: now,
|
|
@@ -731,6 +744,8 @@ var EmbeddedProvider = class {
|
|
|
731
744
|
stamperInfo,
|
|
732
745
|
authProvider: "phantom-connect",
|
|
733
746
|
userInfo: { provider: authOptions?.provider },
|
|
747
|
+
accountDerivationIndex: void 0,
|
|
748
|
+
// Will be set when redirect completes
|
|
734
749
|
status: "pending",
|
|
735
750
|
createdAt: now,
|
|
736
751
|
lastUsed: now,
|
|
@@ -769,6 +784,7 @@ var EmbeddedProvider = class {
|
|
|
769
784
|
});
|
|
770
785
|
tempSession.walletId = authResult.walletId;
|
|
771
786
|
tempSession.authProvider = authResult.provider || tempSession.authProvider;
|
|
787
|
+
tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
|
|
772
788
|
tempSession.status = "completed";
|
|
773
789
|
tempSession.lastUsed = Date.now();
|
|
774
790
|
await this.storage.saveSession(tempSession);
|
|
@@ -784,6 +800,7 @@ var EmbeddedProvider = class {
|
|
|
784
800
|
}
|
|
785
801
|
session.walletId = authResult.walletId;
|
|
786
802
|
session.authProvider = authResult.provider || session.authProvider;
|
|
803
|
+
session.accountDerivationIndex = authResult.accountDerivationIndex;
|
|
787
804
|
session.status = "completed";
|
|
788
805
|
session.lastUsed = Date.now();
|
|
789
806
|
await this.storage.saveSession(session);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/embedded-provider.ts","../src/constants.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\";\nexport * from \"./constants\";\n","import { PhantomClient } 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\";\nimport { AUTHENTICATOR_EXPIRATION_TIME_MS, AUTHENTICATOR_RENEWAL_WINDOW_MS } from \"./constants\";\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\";\n\nexport type EmbeddedProviderEvent = 'connect' | 'connect_start' | 'connect_error' | 'disconnect' | 'error';\nexport type EventCallback = (data?: any) => void;\n\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 private eventListeners: Map<EmbeddedProviderEvent, Set<EventCallback>> = new Map();\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 \n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n\n // Auto-connect is now handled manually via autoConnect() method to avoid race conditions\n }\n\n /*\n * Event system methods for listening to provider state changes\n */\n on(event: EmbeddedProviderEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener added\", { event });\n }\n\n off(event: EmbeddedProviderEvent, callback: EventCallback): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n listeners.delete(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener removed\", { event });\n }\n }\n\n private emit(event: EmbeddedProviderEvent, data?: any): void {\n const listeners = this.eventListeners.get(event);\n if (listeners && listeners.size > 0) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Emitting event\", { event, listenerCount: listeners.size, data });\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Event callback error\", { event, error });\n }\n });\n }\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 }\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 // For completed sessions, check if session is valid (only checks authenticator expiration)\n if (session.status === \"completed\" && !this.isSessionValid(session)) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session invalid due to authenticator expiration\", {\n sessionId: session.sessionId,\n authenticatorExpiresAt: session.authenticatorExpiresAt,\n });\n // Clear the invalid session\n await this.storage.clearSession();\n return null;\n }\n\n return session;\n }\n\n /*\n * Shared connection logic for both connect() and autoConnect().\n * Handles redirect resume, existing session validation, and session initialization.\n * Returns ConnectResult if connection succeeds, null if should continue with new auth flow.\n */\n private async tryExistingConnection(): Promise<ConnectResult | null> {\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 // If we have a completed session, use it\n if (session && session.status === \"completed\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using existing completed session\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n });\n\n await this.initializeClientFromSession(session);\n\n // Update session timestamp\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Connection from existing session successful\", {\n walletId: this.walletId,\n addressCount: this.addresses.length,\n });\n\n // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for existing session success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"existing-session\",\n });\n\n return result;\n }\n\n // No existing connection available\n return null;\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 validate if a session is still valid.\n * This checks session status, required fields, and authenticator expiration.\n * Sessions never expire by age - only authenticators expire.\n */\n private isSessionValid(session: Session | null): boolean {\n if (!session) {\n return false;\n }\n\n // Check required fields\n if (!session.walletId || !session.organizationId || !session.stamperInfo) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session missing required fields\", {\n hasWalletId: !!session.walletId,\n hasOrganizationId: !!session.organizationId,\n hasStamperInfo: !!session.stamperInfo,\n });\n return false;\n }\n\n // Check session status\n if (session.status !== \"completed\") {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session not completed\", { status: session.status });\n return false;\n }\n\n // Sessions without authenticator timing are invalid\n if (!session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session invalid - missing authenticator timing\", {\n sessionId: session.sessionId,\n });\n return false;\n }\n\n // Check authenticator expiration - if expired, session is invalid\n if (Date.now() >= session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Authenticator expired, session invalid\", {\n authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n now: new Date().toISOString(),\n });\n return false;\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session is valid\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString(),\n });\n return true;\n }\n\n /*\n * Public method to attempt auto-connection using an existing valid session.\n * This should be called after setting up event listeners to avoid race conditions.\n * Silently fails if no valid session exists, enabling seamless reconnection.\n */\n async autoConnect(): Promise<void> {\n try {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting auto-connect attempt\");\n \n // Emit connect_start event for auto-connect\n this.emit(\"connect_start\", { source: \"auto-connect\" });\n\n // Try to use existing connection (redirect resume or completed session)\n const result = await this.tryExistingConnection();\n \n if (result) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Auto-connect successful\", {\n walletId: result.walletId,\n addressCount: result.addresses.length,\n });\n\n this.emit(\"connect\", {\n walletId: result.walletId,\n addresses: result.addresses,\n source: \"auto-connect\",\n });\n return;\n }\n\n // No existing connection available - auto-connect should fail silently\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Auto-connect failed: no valid session found\");\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: \"No valid session found\",\n source: \"auto-connect\",\n });\n \n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Auto-connect failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : \"Auto-connect failed\",\n source: \"auto-connect\",\n });\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; expiresAtMs: number; username: string }> {\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 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 const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n const username = `user-${shortPubKey}`;\n const { organizationId } = await tempClient.createOrganization(organizationName, [\n {\n username,\n role: \"ADMIN\",\n authenticators: [\n {\n authenticatorName: `auth-${shortPubKey}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expirable organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n ],\n },\n ]);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId });\n\n return { organizationId, stamperInfo, expiresAtMs, username };\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 // Emit connect_start event for manual connect\n this.emit(\"connect_start\", { \n source: \"manual-connect\",\n authOptions: authOptions ? { provider: authOptions.provider } : undefined\n });\n\n // Try to use existing connection (redirect resume or completed session)\n const existingResult = await this.tryExistingConnection();\n if (existingResult) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Manual connect using existing connection\", {\n walletId: existingResult.walletId,\n addressCount: existingResult.addresses.length,\n });\n \n // Emit connect event for manual connect success with existing connection\n this.emit(\"connect\", {\n walletId: existingResult.walletId,\n addresses: existingResult.addresses,\n source: \"manual-existing\",\n });\n \n return existingResult;\n }\n\n // Validate auth options before proceeding with new auth flow\n this.validateAuthOptions(authOptions);\n\n // No existing connection available, create new one\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing connection, creating new auth flow\");\n const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();\n const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);\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 // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for manual connect success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"manual\",\n });\n\n return result;\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 // Emit connect_error event for manual connect failure\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : String(error),\n source: \"manual-connect\",\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 const wasConnected = this.client !== null;\n \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 // Emit disconnect event if we were previously connected\n if (wasConnected) {\n this.emit(\"disconnect\", {\n source: \"manual\",\n });\n }\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 | undefined,\n expiresAtMs: number,\n username: string,\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, expiresAtMs, username);\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, username);\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 authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 expiresAtMs: number,\n username: string,\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 authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 username?: string,\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 authenticatorCreatedAt: now,\n authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,\n lastRenewalAttempt: undefined,\n username: username || `user-${stamperInfo.keyId.substring(0, 8)}`,\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 // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * Ensures the authenticator is valid and performs renewal if needed.\n * The renewal of the authenticator can only happen meanwhile the previous authenticator is still valid. \n */\n private async ensureValidAuthenticator(): Promise<void> {\n // Get current session to check authenticator timing\n const session = await this.storage.getSession();\n if (!session) {\n throw new Error(\"No active session found\");\n }\n\n const now = Date.now();\n \n // Sessions without authenticator timing fields are invalid - clear them\n if (!session.authenticatorExpiresAt) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session missing authenticator timing - treating as invalid session\");\n await this.disconnect();\n throw new Error(\"Invalid session - missing authenticator timing\");\n }\n\n const timeUntilExpiry = session.authenticatorExpiresAt - now;\n \n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking authenticator expiration\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n });\n\n // Check if authenticator has expired\n if (timeUntilExpiry <= 0) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Authenticator has expired, disconnecting\");\n await this.disconnect();\n throw new Error(\"Authenticator expired\");\n }\n\n // Check if authenticator needs renewal (within renewal window)\n const renewalWindow = AUTHENTICATOR_RENEWAL_WINDOW_MS;\n if (timeUntilExpiry <= renewalWindow) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator needs renewal\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n renewalWindow,\n });\n\n try {\n await this.renewAuthenticator(session);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewed successfully\");\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to renew authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Don't throw - renewal failure shouldn't break existing functionality\n }\n }\n }\n\n\n /*\n * We use this method to perform silent authenticator renewal.\n * It generates a new keypair, creates a new authenticator, and switches to it.\n */\n private async renewAuthenticator(session: Session): Promise<void> {\n if (!this.client) {\n throw new Error(\"Client not initialized\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting authenticator renewal\");\n\n try {\n // Step 1: Generate new keypair (but don't make it active yet)\n const newKeyInfo = await this.stamper.rotateKeyPair();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Generated new keypair for renewal\", {\n newKeyId: newKeyInfo.keyId,\n newPublicKey: newKeyInfo.publicKey,\n });\n\n // Step 2: Convert public key and set expiration\n const base64urlPublicKey = base64urlEncode(bs58.decode(newKeyInfo.publicKey));\n const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n // Step 3: Create new authenticator with replaceExpirable=true\n let authenticatorResult;\n try {\n authenticatorResult = await this.client.createAuthenticator({\n organizationId: session.organizationId,\n username: session.username,\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticator: {\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expiring organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n replaceExpirable: true,\n } as any);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to create new authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Rollback the rotation on server error\n await this.stamper.rollbackRotation();\n throw new Error(`Failed to create new authenticator: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Created new authenticator\", {\n authenticatorId: (authenticatorResult as any).id,\n });\n\n // Step 4: Commit the rotation (switch stamper to use new keypair)\n await this.stamper.commitRotation((authenticatorResult as any).id || 'unknown');\n\n // Step 5: Update session with new authenticator timing\n const now = Date.now();\n session.stamperInfo = newKeyInfo;\n session.authenticatorCreatedAt = now;\n session.authenticatorExpiresAt = expiresAtMs;\n session.lastRenewalAttempt = now;\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewal completed successfully\", {\n newKeyId: newKeyInfo.keyId,\n expiresAt: new Date(expiresAtMs).toISOString(),\n });\n } catch (error) {\n // Rollback rotation on any failure\n await this.stamper.rollbackRotation();\n throw error;\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","/**\n * Constants for authenticator lifecycle management\n */\n\n/**\n * How long an authenticator is valid before it expires (in milliseconds)\n * Default: 7 days\n * For testing: Use smaller values like 5 * 60 * 1000 (5 minutes)\n */\nexport const AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n/**\n * How long before expiration should we attempt to renew the authenticator (in milliseconds)\n * Default: 2 days before expiration\n * For testing: Use smaller values like 2 * 60 * 1000 (2 minutes)\n */\nexport const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1000; // 2 days\n\n/**\n * Example configurations for testing:\n * \n * Quick testing (5 minute expiration, 2 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 5 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 60 * 1000;\n * \n * Medium testing (1 hour expiration, 15 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 60 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 15 * 60 * 1000;\n * \n * Aggressive testing (30 seconds expiration, 10 second renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 30 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 10 * 1000;\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"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/embedded-provider.ts","../src/constants.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\";\nexport * from \"./constants\";\n","import { PhantomClient } 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\";\nimport { AUTHENTICATOR_EXPIRATION_TIME_MS, AUTHENTICATOR_RENEWAL_WINDOW_MS } from \"./constants\";\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\";\n\nexport type EmbeddedProviderEvent = 'connect' | 'connect_start' | 'connect_error' | 'disconnect' | 'error';\nexport type EventCallback = (data?: any) => void;\n\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 private eventListeners: Map<EmbeddedProviderEvent, Set<EventCallback>> = new Map();\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 \n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n\n // Auto-connect is now handled manually via autoConnect() method to avoid race conditions\n }\n\n /*\n * Event system methods for listening to provider state changes\n */\n on(event: EmbeddedProviderEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener added\", { event });\n }\n\n off(event: EmbeddedProviderEvent, callback: EventCallback): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n listeners.delete(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener removed\", { event });\n }\n }\n\n private emit(event: EmbeddedProviderEvent, data?: any): void {\n const listeners = this.eventListeners.get(event);\n if (listeners && listeners.size > 0) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Emitting event\", { event, listenerCount: listeners.size, data });\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Event callback error\", { event, error });\n }\n });\n }\n }\n\n private async getAndFilterWalletAddresses(walletId: string): Promise<WalletAddress[]> {\n // Get session to access derivation index\n const session = await this.storage.getSession();\n const derivationIndex = session?.accountDerivationIndex ?? 0;\n\n // Get wallet addresses with retry and auto-disconnect on failure\n const addresses = await retryWithBackoff(\n () => this.client!.getWalletAddresses(walletId, undefined, derivationIndex),\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 derivationIndex: derivationIndex,\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 }\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 // For completed sessions, check if session is valid (only checks authenticator expiration)\n if (session.status === \"completed\" && !this.isSessionValid(session)) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session invalid due to authenticator expiration\", {\n sessionId: session.sessionId,\n authenticatorExpiresAt: session.authenticatorExpiresAt,\n });\n // Clear the invalid session\n await this.storage.clearSession();\n return null;\n }\n\n return session;\n }\n\n /*\n * Shared connection logic for both connect() and autoConnect().\n * Handles redirect resume, existing session validation, and session initialization.\n * Returns ConnectResult if connection succeeds, null if should continue with new auth flow.\n */\n private async tryExistingConnection(): Promise<ConnectResult | null> {\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 // If we have a completed session, use it\n if (session && session.status === \"completed\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using existing completed session\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n });\n\n await this.initializeClientFromSession(session);\n\n // Update session timestamp\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Connection from existing session successful\", {\n walletId: this.walletId,\n addressCount: this.addresses.length,\n });\n\n // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for existing session success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"existing-session\",\n });\n\n return result;\n }\n\n // No existing connection available\n return null;\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 validate if a session is still valid.\n * This checks session status, required fields, and authenticator expiration.\n * Sessions never expire by age - only authenticators expire.\n */\n private isSessionValid(session: Session | null): boolean {\n if (!session) {\n return false;\n }\n\n // Check required fields\n if (!session.walletId || !session.organizationId || !session.stamperInfo) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session missing required fields\", {\n hasWalletId: !!session.walletId,\n hasOrganizationId: !!session.organizationId,\n hasStamperInfo: !!session.stamperInfo,\n });\n return false;\n }\n\n // Check session status\n if (session.status !== \"completed\") {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session not completed\", { status: session.status });\n return false;\n }\n\n // Sessions without authenticator timing are invalid\n if (!session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session invalid - missing authenticator timing\", {\n sessionId: session.sessionId,\n });\n return false;\n }\n\n // Check authenticator expiration - if expired, session is invalid\n if (Date.now() >= session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Authenticator expired, session invalid\", {\n authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n now: new Date().toISOString(),\n });\n return false;\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session is valid\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString(),\n });\n return true;\n }\n\n /*\n * Public method to attempt auto-connection using an existing valid session.\n * This should be called after setting up event listeners to avoid race conditions.\n * Silently fails if no valid session exists, enabling seamless reconnection.\n */\n async autoConnect(): Promise<void> {\n try {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting auto-connect attempt\");\n \n // Emit connect_start event for auto-connect\n this.emit(\"connect_start\", { source: \"auto-connect\" });\n\n // Try to use existing connection (redirect resume or completed session)\n const result = await this.tryExistingConnection();\n \n if (result) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Auto-connect successful\", {\n walletId: result.walletId,\n addressCount: result.addresses.length,\n });\n\n this.emit(\"connect\", {\n walletId: result.walletId,\n addresses: result.addresses,\n source: \"auto-connect\",\n });\n return;\n }\n\n // No existing connection available - auto-connect should fail silently\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Auto-connect failed: no valid session found\");\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: \"No valid session found\",\n source: \"auto-connect\",\n });\n \n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Auto-connect failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : \"Auto-connect failed\",\n source: \"auto-connect\",\n });\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; expiresAtMs: number; username: string }> {\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 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 const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n const username = `user-${shortPubKey}`;\n const { organizationId } = await tempClient.createOrganization(organizationName, [\n {\n username,\n role: \"ADMIN\",\n authenticators: [\n {\n authenticatorName: `auth-${shortPubKey}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expirable organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n ],\n },\n ]);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId });\n\n return { organizationId, stamperInfo, expiresAtMs, username };\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 // Emit connect_start event for manual connect\n this.emit(\"connect_start\", { \n source: \"manual-connect\",\n authOptions: authOptions ? { provider: authOptions.provider } : undefined\n });\n\n // Try to use existing connection (redirect resume or completed session)\n const existingResult = await this.tryExistingConnection();\n if (existingResult) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Manual connect using existing connection\", {\n walletId: existingResult.walletId,\n addressCount: existingResult.addresses.length,\n });\n \n // Emit connect event for manual connect success with existing connection\n this.emit(\"connect\", {\n walletId: existingResult.walletId,\n addresses: existingResult.addresses,\n source: \"manual-existing\",\n });\n \n return existingResult;\n }\n\n // Validate auth options before proceeding with new auth flow\n this.validateAuthOptions(authOptions);\n\n // No existing connection available, create new one\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing connection, creating new auth flow\");\n const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();\n const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);\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 // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for manual connect success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"manual\",\n });\n\n return result;\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 // Emit connect_error event for manual connect failure\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : String(error),\n source: \"manual-connect\",\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 const wasConnected = this.client !== null;\n \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 // Emit disconnect event if we were previously connected\n if (wasConnected) {\n this.emit(\"disconnect\", {\n source: \"manual\",\n });\n }\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 session to access derivation index\n const session = await this.storage.getSession();\n const derivationIndex = session?.accountDerivationIndex ?? 0;\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 derivationIndex: derivationIndex,\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 // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 // Get session to access derivation index\n const session = await this.storage.getSession();\n const derivationIndex = session?.accountDerivationIndex ?? 0;\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Parsed transaction for signing\", {\n walletId: this.walletId,\n transaction: parsedTransaction,\n derivationIndex: derivationIndex,\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 derivationIndex: derivationIndex,\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 | undefined,\n expiresAtMs: number,\n username: string,\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, expiresAtMs, username);\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, username);\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 accountDerivationIndex: 0, // App wallets default to index 0\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 expiresAtMs: number,\n username: string,\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 accountDerivationIndex: authResult.accountDerivationIndex,\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 username?: string,\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 accountDerivationIndex: undefined, // Will be set when redirect completes\n status: \"pending\" as const,\n createdAt: now,\n lastUsed: now,\n authenticatorCreatedAt: now,\n authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,\n lastRenewalAttempt: undefined,\n username: username || `user-${stamperInfo.keyId.substring(0, 8)}`,\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.accountDerivationIndex = authResult.accountDerivationIndex;\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.accountDerivationIndex = authResult.accountDerivationIndex;\n session.status = \"completed\";\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n await this.initializeClientFromSession(session);\n\n // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * Ensures the authenticator is valid and performs renewal if needed.\n * The renewal of the authenticator can only happen meanwhile the previous authenticator is still valid. \n */\n private async ensureValidAuthenticator(): Promise<void> {\n // Get current session to check authenticator timing\n const session = await this.storage.getSession();\n if (!session) {\n throw new Error(\"No active session found\");\n }\n\n const now = Date.now();\n \n // Sessions without authenticator timing fields are invalid - clear them\n if (!session.authenticatorExpiresAt) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session missing authenticator timing - treating as invalid session\");\n await this.disconnect();\n throw new Error(\"Invalid session - missing authenticator timing\");\n }\n\n const timeUntilExpiry = session.authenticatorExpiresAt - now;\n \n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking authenticator expiration\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n });\n\n // Check if authenticator has expired\n if (timeUntilExpiry <= 0) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Authenticator has expired, disconnecting\");\n await this.disconnect();\n throw new Error(\"Authenticator expired\");\n }\n\n // Check if authenticator needs renewal (within renewal window)\n const renewalWindow = AUTHENTICATOR_RENEWAL_WINDOW_MS;\n if (timeUntilExpiry <= renewalWindow) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator needs renewal\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n renewalWindow,\n });\n\n try {\n await this.renewAuthenticator(session);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewed successfully\");\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to renew authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Don't throw - renewal failure shouldn't break existing functionality\n }\n }\n }\n\n\n /*\n * We use this method to perform silent authenticator renewal.\n * It generates a new keypair, creates a new authenticator, and switches to it.\n */\n private async renewAuthenticator(session: Session): Promise<void> {\n if (!this.client) {\n throw new Error(\"Client not initialized\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting authenticator renewal\");\n\n try {\n // Step 1: Generate new keypair (but don't make it active yet)\n const newKeyInfo = await this.stamper.rotateKeyPair();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Generated new keypair for renewal\", {\n newKeyId: newKeyInfo.keyId,\n newPublicKey: newKeyInfo.publicKey,\n });\n\n // Step 2: Convert public key and set expiration\n const base64urlPublicKey = base64urlEncode(bs58.decode(newKeyInfo.publicKey));\n const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n // Step 3: Create new authenticator with replaceExpirable=true\n let authenticatorResult;\n try {\n authenticatorResult = await this.client.createAuthenticator({\n organizationId: session.organizationId,\n username: session.username,\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticator: {\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expiring organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n replaceExpirable: true,\n } as any);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to create new authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Rollback the rotation on server error\n await this.stamper.rollbackRotation();\n throw new Error(`Failed to create new authenticator: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Created new authenticator\", {\n authenticatorId: (authenticatorResult as any).id,\n });\n\n // Step 4: Commit the rotation (switch stamper to use new keypair)\n await this.stamper.commitRotation((authenticatorResult as any).id || 'unknown');\n\n // Step 5: Update session with new authenticator timing\n const now = Date.now();\n session.stamperInfo = newKeyInfo;\n session.authenticatorCreatedAt = now;\n session.authenticatorExpiresAt = expiresAtMs;\n session.lastRenewalAttempt = now;\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewal completed successfully\", {\n newKeyId: newKeyInfo.keyId,\n expiresAt: new Date(expiresAtMs).toISOString(),\n });\n } catch (error) {\n // Rollback rotation on any failure\n await this.stamper.rollbackRotation();\n throw error;\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","/**\n * Constants for authenticator lifecycle management\n */\n\n/**\n * How long an authenticator is valid before it expires (in milliseconds)\n * Default: 7 days\n * For testing: Use smaller values like 5 * 60 * 1000 (5 minutes)\n */\nexport const AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n/**\n * How long before expiration should we attempt to renew the authenticator (in milliseconds)\n * Default: 2 days before expiration\n * For testing: Use smaller values like 2 * 60 * 1000 (2 minutes)\n */\nexport const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1000; // 2 days\n\n/**\n * Example configurations for testing:\n * \n * Quick testing (5 minute expiration, 2 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 5 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 60 * 1000;\n * \n * Medium testing (1 hour expiration, 15 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 60 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 15 * 60 * 1000;\n * \n * Aggressive testing (30 seconds expiration, 10 second renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 30 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 10 * 1000;\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
|
@@ -179,14 +179,17 @@ var EmbeddedProvider = class {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
async getAndFilterWalletAddresses(walletId) {
|
|
182
|
+
const session = await this.storage.getSession();
|
|
183
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
182
184
|
const addresses = await retryWithBackoff(
|
|
183
|
-
() => this.client.getWalletAddresses(walletId),
|
|
185
|
+
() => this.client.getWalletAddresses(walletId, void 0, derivationIndex),
|
|
184
186
|
"getWalletAddresses",
|
|
185
187
|
this.logger
|
|
186
188
|
).catch(async (error) => {
|
|
187
189
|
this.logger.error("EMBEDDED_PROVIDER", "getWalletAddresses failed after retries, disconnecting", {
|
|
188
190
|
walletId,
|
|
189
|
-
error: error.message
|
|
191
|
+
error: error.message,
|
|
192
|
+
derivationIndex
|
|
190
193
|
});
|
|
191
194
|
await this.storage.clearSession();
|
|
192
195
|
this.client = null;
|
|
@@ -537,10 +540,13 @@ var EmbeddedProvider = class {
|
|
|
537
540
|
message: params.message
|
|
538
541
|
});
|
|
539
542
|
const parsedMessage = parseMessage(params.message);
|
|
543
|
+
const session = await this.storage.getSession();
|
|
544
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
540
545
|
const rawResponse = await this.client.signMessage({
|
|
541
546
|
walletId: this.walletId,
|
|
542
547
|
message: parsedMessage.base64url,
|
|
543
|
-
networkId: params.networkId
|
|
548
|
+
networkId: params.networkId,
|
|
549
|
+
derivationIndex
|
|
544
550
|
});
|
|
545
551
|
this.logger.info("EMBEDDED_PROVIDER", "Message signed successfully", {
|
|
546
552
|
walletId: this.walletId,
|
|
@@ -558,14 +564,18 @@ var EmbeddedProvider = class {
|
|
|
558
564
|
networkId: params.networkId
|
|
559
565
|
});
|
|
560
566
|
const parsedTransaction = await parseTransaction(params.transaction, params.networkId);
|
|
567
|
+
const session = await this.storage.getSession();
|
|
568
|
+
const derivationIndex = session?.accountDerivationIndex ?? 0;
|
|
561
569
|
this.logger.log("EMBEDDED_PROVIDER", "Parsed transaction for signing", {
|
|
562
570
|
walletId: this.walletId,
|
|
563
|
-
transaction: parsedTransaction
|
|
571
|
+
transaction: parsedTransaction,
|
|
572
|
+
derivationIndex
|
|
564
573
|
});
|
|
565
574
|
const rawResponse = await this.client.signAndSendTransaction({
|
|
566
575
|
walletId: this.walletId,
|
|
567
576
|
transaction: parsedTransaction.base64url,
|
|
568
|
-
networkId: params.networkId
|
|
577
|
+
networkId: params.networkId,
|
|
578
|
+
derivationIndex
|
|
569
579
|
});
|
|
570
580
|
this.logger.info("EMBEDDED_PROVIDER", "Transaction signed and sent successfully", {
|
|
571
581
|
walletId: this.walletId,
|
|
@@ -622,6 +632,8 @@ var EmbeddedProvider = class {
|
|
|
622
632
|
stamperInfo,
|
|
623
633
|
authProvider: "app-wallet",
|
|
624
634
|
userInfo: { embeddedWalletType: this.config.embeddedWalletType },
|
|
635
|
+
accountDerivationIndex: 0,
|
|
636
|
+
// App wallets default to index 0
|
|
625
637
|
status: "completed",
|
|
626
638
|
createdAt: now,
|
|
627
639
|
lastUsed: now,
|
|
@@ -662,6 +674,7 @@ var EmbeddedProvider = class {
|
|
|
662
674
|
stamperInfo,
|
|
663
675
|
authProvider: authResult.provider,
|
|
664
676
|
userInfo: authResult.userInfo,
|
|
677
|
+
accountDerivationIndex: authResult.accountDerivationIndex,
|
|
665
678
|
status: "completed",
|
|
666
679
|
createdAt: now,
|
|
667
680
|
lastUsed: now,
|
|
@@ -695,6 +708,8 @@ var EmbeddedProvider = class {
|
|
|
695
708
|
stamperInfo,
|
|
696
709
|
authProvider: "phantom-connect",
|
|
697
710
|
userInfo: { provider: authOptions?.provider },
|
|
711
|
+
accountDerivationIndex: void 0,
|
|
712
|
+
// Will be set when redirect completes
|
|
698
713
|
status: "pending",
|
|
699
714
|
createdAt: now,
|
|
700
715
|
lastUsed: now,
|
|
@@ -733,6 +748,7 @@ var EmbeddedProvider = class {
|
|
|
733
748
|
});
|
|
734
749
|
tempSession.walletId = authResult.walletId;
|
|
735
750
|
tempSession.authProvider = authResult.provider || tempSession.authProvider;
|
|
751
|
+
tempSession.accountDerivationIndex = authResult.accountDerivationIndex;
|
|
736
752
|
tempSession.status = "completed";
|
|
737
753
|
tempSession.lastUsed = Date.now();
|
|
738
754
|
await this.storage.saveSession(tempSession);
|
|
@@ -748,6 +764,7 @@ var EmbeddedProvider = class {
|
|
|
748
764
|
}
|
|
749
765
|
session.walletId = authResult.walletId;
|
|
750
766
|
session.authProvider = authResult.provider || session.authProvider;
|
|
767
|
+
session.accountDerivationIndex = authResult.accountDerivationIndex;
|
|
751
768
|
session.status = "completed";
|
|
752
769
|
session.lastUsed = Date.now();
|
|
753
770
|
await this.storage.saveSession(session);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/embedded-provider.ts","../src/constants.ts","../src/auth/jwt-auth.ts","../src/utils/session.ts","../src/utils/retry.ts"],"sourcesContent":["import { PhantomClient } 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\";\nimport { AUTHENTICATOR_EXPIRATION_TIME_MS, AUTHENTICATOR_RENEWAL_WINDOW_MS } from \"./constants\";\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\";\n\nexport type EmbeddedProviderEvent = 'connect' | 'connect_start' | 'connect_error' | 'disconnect' | 'error';\nexport type EventCallback = (data?: any) => void;\n\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 private eventListeners: Map<EmbeddedProviderEvent, Set<EventCallback>> = new Map();\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 \n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n\n // Auto-connect is now handled manually via autoConnect() method to avoid race conditions\n }\n\n /*\n * Event system methods for listening to provider state changes\n */\n on(event: EmbeddedProviderEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener added\", { event });\n }\n\n off(event: EmbeddedProviderEvent, callback: EventCallback): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n listeners.delete(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener removed\", { event });\n }\n }\n\n private emit(event: EmbeddedProviderEvent, data?: any): void {\n const listeners = this.eventListeners.get(event);\n if (listeners && listeners.size > 0) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Emitting event\", { event, listenerCount: listeners.size, data });\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Event callback error\", { event, error });\n }\n });\n }\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 }\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 // For completed sessions, check if session is valid (only checks authenticator expiration)\n if (session.status === \"completed\" && !this.isSessionValid(session)) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session invalid due to authenticator expiration\", {\n sessionId: session.sessionId,\n authenticatorExpiresAt: session.authenticatorExpiresAt,\n });\n // Clear the invalid session\n await this.storage.clearSession();\n return null;\n }\n\n return session;\n }\n\n /*\n * Shared connection logic for both connect() and autoConnect().\n * Handles redirect resume, existing session validation, and session initialization.\n * Returns ConnectResult if connection succeeds, null if should continue with new auth flow.\n */\n private async tryExistingConnection(): Promise<ConnectResult | null> {\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 // If we have a completed session, use it\n if (session && session.status === \"completed\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using existing completed session\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n });\n\n await this.initializeClientFromSession(session);\n\n // Update session timestamp\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Connection from existing session successful\", {\n walletId: this.walletId,\n addressCount: this.addresses.length,\n });\n\n // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for existing session success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"existing-session\",\n });\n\n return result;\n }\n\n // No existing connection available\n return null;\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 validate if a session is still valid.\n * This checks session status, required fields, and authenticator expiration.\n * Sessions never expire by age - only authenticators expire.\n */\n private isSessionValid(session: Session | null): boolean {\n if (!session) {\n return false;\n }\n\n // Check required fields\n if (!session.walletId || !session.organizationId || !session.stamperInfo) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session missing required fields\", {\n hasWalletId: !!session.walletId,\n hasOrganizationId: !!session.organizationId,\n hasStamperInfo: !!session.stamperInfo,\n });\n return false;\n }\n\n // Check session status\n if (session.status !== \"completed\") {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session not completed\", { status: session.status });\n return false;\n }\n\n // Sessions without authenticator timing are invalid\n if (!session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session invalid - missing authenticator timing\", {\n sessionId: session.sessionId,\n });\n return false;\n }\n\n // Check authenticator expiration - if expired, session is invalid\n if (Date.now() >= session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Authenticator expired, session invalid\", {\n authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n now: new Date().toISOString(),\n });\n return false;\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session is valid\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString(),\n });\n return true;\n }\n\n /*\n * Public method to attempt auto-connection using an existing valid session.\n * This should be called after setting up event listeners to avoid race conditions.\n * Silently fails if no valid session exists, enabling seamless reconnection.\n */\n async autoConnect(): Promise<void> {\n try {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting auto-connect attempt\");\n \n // Emit connect_start event for auto-connect\n this.emit(\"connect_start\", { source: \"auto-connect\" });\n\n // Try to use existing connection (redirect resume or completed session)\n const result = await this.tryExistingConnection();\n \n if (result) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Auto-connect successful\", {\n walletId: result.walletId,\n addressCount: result.addresses.length,\n });\n\n this.emit(\"connect\", {\n walletId: result.walletId,\n addresses: result.addresses,\n source: \"auto-connect\",\n });\n return;\n }\n\n // No existing connection available - auto-connect should fail silently\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Auto-connect failed: no valid session found\");\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: \"No valid session found\",\n source: \"auto-connect\",\n });\n \n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Auto-connect failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : \"Auto-connect failed\",\n source: \"auto-connect\",\n });\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; expiresAtMs: number; username: string }> {\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 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 const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n const username = `user-${shortPubKey}`;\n const { organizationId } = await tempClient.createOrganization(organizationName, [\n {\n username,\n role: \"ADMIN\",\n authenticators: [\n {\n authenticatorName: `auth-${shortPubKey}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expirable organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n ],\n },\n ]);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId });\n\n return { organizationId, stamperInfo, expiresAtMs, username };\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 // Emit connect_start event for manual connect\n this.emit(\"connect_start\", { \n source: \"manual-connect\",\n authOptions: authOptions ? { provider: authOptions.provider } : undefined\n });\n\n // Try to use existing connection (redirect resume or completed session)\n const existingResult = await this.tryExistingConnection();\n if (existingResult) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Manual connect using existing connection\", {\n walletId: existingResult.walletId,\n addressCount: existingResult.addresses.length,\n });\n \n // Emit connect event for manual connect success with existing connection\n this.emit(\"connect\", {\n walletId: existingResult.walletId,\n addresses: existingResult.addresses,\n source: \"manual-existing\",\n });\n \n return existingResult;\n }\n\n // Validate auth options before proceeding with new auth flow\n this.validateAuthOptions(authOptions);\n\n // No existing connection available, create new one\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing connection, creating new auth flow\");\n const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();\n const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);\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 // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for manual connect success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"manual\",\n });\n\n return result;\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 // Emit connect_error event for manual connect failure\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : String(error),\n source: \"manual-connect\",\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 const wasConnected = this.client !== null;\n \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 // Emit disconnect event if we were previously connected\n if (wasConnected) {\n this.emit(\"disconnect\", {\n source: \"manual\",\n });\n }\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 | undefined,\n expiresAtMs: number,\n username: string,\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, expiresAtMs, username);\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, username);\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 authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 expiresAtMs: number,\n username: string,\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 authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 username?: string,\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 authenticatorCreatedAt: now,\n authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,\n lastRenewalAttempt: undefined,\n username: username || `user-${stamperInfo.keyId.substring(0, 8)}`,\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 // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * Ensures the authenticator is valid and performs renewal if needed.\n * The renewal of the authenticator can only happen meanwhile the previous authenticator is still valid. \n */\n private async ensureValidAuthenticator(): Promise<void> {\n // Get current session to check authenticator timing\n const session = await this.storage.getSession();\n if (!session) {\n throw new Error(\"No active session found\");\n }\n\n const now = Date.now();\n \n // Sessions without authenticator timing fields are invalid - clear them\n if (!session.authenticatorExpiresAt) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session missing authenticator timing - treating as invalid session\");\n await this.disconnect();\n throw new Error(\"Invalid session - missing authenticator timing\");\n }\n\n const timeUntilExpiry = session.authenticatorExpiresAt - now;\n \n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking authenticator expiration\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n });\n\n // Check if authenticator has expired\n if (timeUntilExpiry <= 0) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Authenticator has expired, disconnecting\");\n await this.disconnect();\n throw new Error(\"Authenticator expired\");\n }\n\n // Check if authenticator needs renewal (within renewal window)\n const renewalWindow = AUTHENTICATOR_RENEWAL_WINDOW_MS;\n if (timeUntilExpiry <= renewalWindow) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator needs renewal\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n renewalWindow,\n });\n\n try {\n await this.renewAuthenticator(session);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewed successfully\");\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to renew authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Don't throw - renewal failure shouldn't break existing functionality\n }\n }\n }\n\n\n /*\n * We use this method to perform silent authenticator renewal.\n * It generates a new keypair, creates a new authenticator, and switches to it.\n */\n private async renewAuthenticator(session: Session): Promise<void> {\n if (!this.client) {\n throw new Error(\"Client not initialized\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting authenticator renewal\");\n\n try {\n // Step 1: Generate new keypair (but don't make it active yet)\n const newKeyInfo = await this.stamper.rotateKeyPair();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Generated new keypair for renewal\", {\n newKeyId: newKeyInfo.keyId,\n newPublicKey: newKeyInfo.publicKey,\n });\n\n // Step 2: Convert public key and set expiration\n const base64urlPublicKey = base64urlEncode(bs58.decode(newKeyInfo.publicKey));\n const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n // Step 3: Create new authenticator with replaceExpirable=true\n let authenticatorResult;\n try {\n authenticatorResult = await this.client.createAuthenticator({\n organizationId: session.organizationId,\n username: session.username,\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticator: {\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expiring organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n replaceExpirable: true,\n } as any);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to create new authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Rollback the rotation on server error\n await this.stamper.rollbackRotation();\n throw new Error(`Failed to create new authenticator: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Created new authenticator\", {\n authenticatorId: (authenticatorResult as any).id,\n });\n\n // Step 4: Commit the rotation (switch stamper to use new keypair)\n await this.stamper.commitRotation((authenticatorResult as any).id || 'unknown');\n\n // Step 5: Update session with new authenticator timing\n const now = Date.now();\n session.stamperInfo = newKeyInfo;\n session.authenticatorCreatedAt = now;\n session.authenticatorExpiresAt = expiresAtMs;\n session.lastRenewalAttempt = now;\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewal completed successfully\", {\n newKeyId: newKeyInfo.keyId,\n expiresAt: new Date(expiresAtMs).toISOString(),\n });\n } catch (error) {\n // Rollback rotation on any failure\n await this.stamper.rollbackRotation();\n throw error;\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","/**\n * Constants for authenticator lifecycle management\n */\n\n/**\n * How long an authenticator is valid before it expires (in milliseconds)\n * Default: 7 days\n * For testing: Use smaller values like 5 * 60 * 1000 (5 minutes)\n */\nexport const AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n/**\n * How long before expiration should we attempt to renew the authenticator (in milliseconds)\n * Default: 2 days before expiration\n * For testing: Use smaller values like 2 * 60 * 1000 (2 minutes)\n */\nexport const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1000; // 2 days\n\n/**\n * Example configurations for testing:\n * \n * Quick testing (5 minute expiration, 2 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 5 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 60 * 1000;\n * \n * Medium testing (1 hour expiration, 15 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 60 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 15 * 60 * 1000;\n * \n * Aggressive testing (30 seconds expiration, 10 second renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 30 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 10 * 1000;\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/constants.ts","../src/auth/jwt-auth.ts","../src/utils/session.ts","../src/utils/retry.ts"],"sourcesContent":["import { PhantomClient } 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\";\nimport { AUTHENTICATOR_EXPIRATION_TIME_MS, AUTHENTICATOR_RENEWAL_WINDOW_MS } from \"./constants\";\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\";\n\nexport type EmbeddedProviderEvent = 'connect' | 'connect_start' | 'connect_error' | 'disconnect' | 'error';\nexport type EventCallback = (data?: any) => void;\n\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 private eventListeners: Map<EmbeddedProviderEvent, Set<EventCallback>> = new Map();\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 \n this.logger.info(\"EMBEDDED_PROVIDER\", \"EmbeddedProvider initialized\");\n\n // Auto-connect is now handled manually via autoConnect() method to avoid race conditions\n }\n\n /*\n * Event system methods for listening to provider state changes\n */\n on(event: EmbeddedProviderEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener added\", { event });\n }\n\n off(event: EmbeddedProviderEvent, callback: EventCallback): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n listeners.delete(callback);\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Event listener removed\", { event });\n }\n }\n\n private emit(event: EmbeddedProviderEvent, data?: any): void {\n const listeners = this.eventListeners.get(event);\n if (listeners && listeners.size > 0) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Emitting event\", { event, listenerCount: listeners.size, data });\n listeners.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Event callback error\", { event, error });\n }\n });\n }\n }\n\n private async getAndFilterWalletAddresses(walletId: string): Promise<WalletAddress[]> {\n // Get session to access derivation index\n const session = await this.storage.getSession();\n const derivationIndex = session?.accountDerivationIndex ?? 0;\n\n // Get wallet addresses with retry and auto-disconnect on failure\n const addresses = await retryWithBackoff(\n () => this.client!.getWalletAddresses(walletId, undefined, derivationIndex),\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 derivationIndex: derivationIndex,\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 }\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 // For completed sessions, check if session is valid (only checks authenticator expiration)\n if (session.status === \"completed\" && !this.isSessionValid(session)) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session invalid due to authenticator expiration\", {\n sessionId: session.sessionId,\n authenticatorExpiresAt: session.authenticatorExpiresAt,\n });\n // Clear the invalid session\n await this.storage.clearSession();\n return null;\n }\n\n return session;\n }\n\n /*\n * Shared connection logic for both connect() and autoConnect().\n * Handles redirect resume, existing session validation, and session initialization.\n * Returns ConnectResult if connection succeeds, null if should continue with new auth flow.\n */\n private async tryExistingConnection(): Promise<ConnectResult | null> {\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 // If we have a completed session, use it\n if (session && session.status === \"completed\") {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Using existing completed session\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n });\n\n await this.initializeClientFromSession(session);\n\n // Update session timestamp\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Connection from existing session successful\", {\n walletId: this.walletId,\n addressCount: this.addresses.length,\n });\n\n // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for existing session success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"existing-session\",\n });\n\n return result;\n }\n\n // No existing connection available\n return null;\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 validate if a session is still valid.\n * This checks session status, required fields, and authenticator expiration.\n * Sessions never expire by age - only authenticators expire.\n */\n private isSessionValid(session: Session | null): boolean {\n if (!session) {\n return false;\n }\n\n // Check required fields\n if (!session.walletId || !session.organizationId || !session.stamperInfo) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session missing required fields\", {\n hasWalletId: !!session.walletId,\n hasOrganizationId: !!session.organizationId,\n hasStamperInfo: !!session.stamperInfo,\n });\n return false;\n }\n\n // Check session status\n if (session.status !== \"completed\") {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session not completed\", { status: session.status });\n return false;\n }\n\n // Sessions without authenticator timing are invalid\n if (!session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session invalid - missing authenticator timing\", {\n sessionId: session.sessionId,\n });\n return false;\n }\n\n // Check authenticator expiration - if expired, session is invalid\n if (Date.now() >= session.authenticatorExpiresAt) {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Authenticator expired, session invalid\", {\n authenticatorExpiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n now: new Date().toISOString(),\n });\n return false;\n }\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Session is valid\", {\n sessionId: session.sessionId,\n walletId: session.walletId,\n authenticatorExpires: new Date(session.authenticatorExpiresAt).toISOString(),\n });\n return true;\n }\n\n /*\n * Public method to attempt auto-connection using an existing valid session.\n * This should be called after setting up event listeners to avoid race conditions.\n * Silently fails if no valid session exists, enabling seamless reconnection.\n */\n async autoConnect(): Promise<void> {\n try {\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Starting auto-connect attempt\");\n \n // Emit connect_start event for auto-connect\n this.emit(\"connect_start\", { source: \"auto-connect\" });\n\n // Try to use existing connection (redirect resume or completed session)\n const result = await this.tryExistingConnection();\n \n if (result) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Auto-connect successful\", {\n walletId: result.walletId,\n addressCount: result.addresses.length,\n });\n\n this.emit(\"connect\", {\n walletId: result.walletId,\n addresses: result.addresses,\n source: \"auto-connect\",\n });\n return;\n }\n\n // No existing connection available - auto-connect should fail silently\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Auto-connect failed: no valid session found\");\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: \"No valid session found\",\n source: \"auto-connect\",\n });\n \n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Auto-connect failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n \n // Emit connect_error to reset isConnecting state\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : \"Auto-connect failed\",\n source: \"auto-connect\",\n });\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; expiresAtMs: number; username: string }> {\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 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 const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n const username = `user-${shortPubKey}`;\n const { organizationId } = await tempClient.createOrganization(organizationName, [\n {\n username,\n role: \"ADMIN\",\n authenticators: [\n {\n authenticatorName: `auth-${shortPubKey}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expirable organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n ],\n },\n ]);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Organization created\", { organizationId });\n\n return { organizationId, stamperInfo, expiresAtMs, username };\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 // Emit connect_start event for manual connect\n this.emit(\"connect_start\", { \n source: \"manual-connect\",\n authOptions: authOptions ? { provider: authOptions.provider } : undefined\n });\n\n // Try to use existing connection (redirect resume or completed session)\n const existingResult = await this.tryExistingConnection();\n if (existingResult) {\n // Successfully connected using existing session or redirect\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Manual connect using existing connection\", {\n walletId: existingResult.walletId,\n addressCount: existingResult.addresses.length,\n });\n \n // Emit connect event for manual connect success with existing connection\n this.emit(\"connect\", {\n walletId: existingResult.walletId,\n addresses: existingResult.addresses,\n source: \"manual-existing\",\n });\n \n return existingResult;\n }\n\n // Validate auth options before proceeding with new auth flow\n this.validateAuthOptions(authOptions);\n\n // No existing connection available, create new one\n this.logger.info(\"EMBEDDED_PROVIDER\", \"No existing connection, creating new auth flow\");\n const { organizationId, stamperInfo, expiresAtMs, username } = await this.createOrganizationAndStamper();\n const session = await this.handleAuthFlow(organizationId, stamperInfo, authOptions, expiresAtMs, username);\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 // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n const result: ConnectResult = {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n\n // Emit connect event for manual connect success\n this.emit(\"connect\", {\n walletId: this.walletId,\n addresses: this.addresses,\n source: \"manual\",\n });\n\n return result;\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 // Emit connect_error event for manual connect failure\n this.emit(\"connect_error\", {\n error: error instanceof Error ? error.message : String(error),\n source: \"manual-connect\",\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 const wasConnected = this.client !== null;\n \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 // Emit disconnect event if we were previously connected\n if (wasConnected) {\n this.emit(\"disconnect\", {\n source: \"manual\",\n });\n }\n }\n\n async signMessage(params: SignMessageParams): Promise<ParsedSignatureResult> {\n if (!this.client || !this.walletId) {\n throw new Error(\"Not connected\");\n }\n\n // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 session to access derivation index\n const session = await this.storage.getSession();\n const derivationIndex = session?.accountDerivationIndex ?? 0;\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 derivationIndex: derivationIndex,\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 // Check if authenticator needs renewal before performing the operation\n await this.ensureValidAuthenticator();\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 // Get session to access derivation index\n const session = await this.storage.getSession();\n const derivationIndex = session?.accountDerivationIndex ?? 0;\n\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Parsed transaction for signing\", {\n walletId: this.walletId,\n transaction: parsedTransaction,\n derivationIndex: derivationIndex,\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 derivationIndex: derivationIndex,\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 | undefined,\n expiresAtMs: number,\n username: string,\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, expiresAtMs, username);\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, username);\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 accountDerivationIndex: 0, // App wallets default to index 0\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 expiresAtMs: number,\n username: string,\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 accountDerivationIndex: authResult.accountDerivationIndex,\n status: \"completed\" as const,\n createdAt: now,\n lastUsed: now,\n authenticatorCreatedAt: now,\n authenticatorExpiresAt: expiresAtMs,\n lastRenewalAttempt: undefined,\n username,\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 username?: string,\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 accountDerivationIndex: undefined, // Will be set when redirect completes\n status: \"pending\" as const,\n createdAt: now,\n lastUsed: now,\n authenticatorCreatedAt: now,\n authenticatorExpiresAt: now + AUTHENTICATOR_EXPIRATION_TIME_MS,\n lastRenewalAttempt: undefined,\n username: username || `user-${stamperInfo.keyId.substring(0, 8)}`,\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.accountDerivationIndex = authResult.accountDerivationIndex;\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.accountDerivationIndex = authResult.accountDerivationIndex;\n session.status = \"completed\";\n session.lastUsed = Date.now();\n await this.storage.saveSession(session);\n\n await this.initializeClientFromSession(session);\n\n // Ensure authenticator is valid after successful connection\n await this.ensureValidAuthenticator();\n\n return {\n walletId: this.walletId!,\n addresses: this.addresses,\n status: \"completed\",\n };\n }\n\n /*\n * Ensures the authenticator is valid and performs renewal if needed.\n * The renewal of the authenticator can only happen meanwhile the previous authenticator is still valid. \n */\n private async ensureValidAuthenticator(): Promise<void> {\n // Get current session to check authenticator timing\n const session = await this.storage.getSession();\n if (!session) {\n throw new Error(\"No active session found\");\n }\n\n const now = Date.now();\n \n // Sessions without authenticator timing fields are invalid - clear them\n if (!session.authenticatorExpiresAt) {\n this.logger.warn(\"EMBEDDED_PROVIDER\", \"Session missing authenticator timing - treating as invalid session\");\n await this.disconnect();\n throw new Error(\"Invalid session - missing authenticator timing\");\n }\n\n const timeUntilExpiry = session.authenticatorExpiresAt - now;\n \n this.logger.log(\"EMBEDDED_PROVIDER\", \"Checking authenticator expiration\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n });\n\n // Check if authenticator has expired\n if (timeUntilExpiry <= 0) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Authenticator has expired, disconnecting\");\n await this.disconnect();\n throw new Error(\"Authenticator expired\");\n }\n\n // Check if authenticator needs renewal (within renewal window)\n const renewalWindow = AUTHENTICATOR_RENEWAL_WINDOW_MS;\n if (timeUntilExpiry <= renewalWindow) {\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator needs renewal\", {\n expiresAt: new Date(session.authenticatorExpiresAt).toISOString(),\n timeUntilExpiry,\n renewalWindow,\n });\n\n try {\n await this.renewAuthenticator(session);\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewed successfully\");\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to renew authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Don't throw - renewal failure shouldn't break existing functionality\n }\n }\n }\n\n\n /*\n * We use this method to perform silent authenticator renewal.\n * It generates a new keypair, creates a new authenticator, and switches to it.\n */\n private async renewAuthenticator(session: Session): Promise<void> {\n if (!this.client) {\n throw new Error(\"Client not initialized\");\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Starting authenticator renewal\");\n\n try {\n // Step 1: Generate new keypair (but don't make it active yet)\n const newKeyInfo = await this.stamper.rotateKeyPair();\n this.logger.log(\"EMBEDDED_PROVIDER\", \"Generated new keypair for renewal\", {\n newKeyId: newKeyInfo.keyId,\n newPublicKey: newKeyInfo.publicKey,\n });\n\n // Step 2: Convert public key and set expiration\n const base64urlPublicKey = base64urlEncode(bs58.decode(newKeyInfo.publicKey));\n const expiresAtMs = Date.now() + AUTHENTICATOR_EXPIRATION_TIME_MS;\n\n // Step 3: Create new authenticator with replaceExpirable=true\n let authenticatorResult;\n try {\n authenticatorResult = await this.client.createAuthenticator({\n organizationId: session.organizationId,\n username: session.username,\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticator: {\n authenticatorName: `auth-${newKeyInfo.keyId.substring(0, 8)}`,\n authenticatorKind: \"keypair\",\n publicKey: base64urlPublicKey,\n algorithm: \"Ed25519\",\n // Commented for now until KMS supports fully expiring organizations\n // expiresAtMs: expiresAtMs,\n } as any,\n replaceExpirable: true,\n } as any);\n } catch (error) {\n this.logger.error(\"EMBEDDED_PROVIDER\", \"Failed to create new authenticator\", {\n error: error instanceof Error ? error.message : String(error),\n });\n // Rollback the rotation on server error\n await this.stamper.rollbackRotation();\n throw new Error(`Failed to create new authenticator: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Created new authenticator\", {\n authenticatorId: (authenticatorResult as any).id,\n });\n\n // Step 4: Commit the rotation (switch stamper to use new keypair)\n await this.stamper.commitRotation((authenticatorResult as any).id || 'unknown');\n\n // Step 5: Update session with new authenticator timing\n const now = Date.now();\n session.stamperInfo = newKeyInfo;\n session.authenticatorCreatedAt = now;\n session.authenticatorExpiresAt = expiresAtMs;\n session.lastRenewalAttempt = now;\n await this.storage.saveSession(session);\n\n this.logger.info(\"EMBEDDED_PROVIDER\", \"Authenticator renewal completed successfully\", {\n newKeyId: newKeyInfo.keyId,\n expiresAt: new Date(expiresAtMs).toISOString(),\n });\n } catch (error) {\n // Rollback rotation on any failure\n await this.stamper.rollbackRotation();\n throw error;\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","/**\n * Constants for authenticator lifecycle management\n */\n\n/**\n * How long an authenticator is valid before it expires (in milliseconds)\n * Default: 7 days\n * For testing: Use smaller values like 5 * 60 * 1000 (5 minutes)\n */\nexport const AUTHENTICATOR_EXPIRATION_TIME_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n/**\n * How long before expiration should we attempt to renew the authenticator (in milliseconds)\n * Default: 2 days before expiration\n * For testing: Use smaller values like 2 * 60 * 1000 (2 minutes)\n */\nexport const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 24 * 60 * 60 * 1000; // 2 days\n\n/**\n * Example configurations for testing:\n * \n * Quick testing (5 minute expiration, 2 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 5 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 2 * 60 * 1000;\n * \n * Medium testing (1 hour expiration, 15 minute renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 60 * 60 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 15 * 60 * 1000;\n * \n * Aggressive testing (30 seconds expiration, 10 second renewal window):\n * export const AUTHENTICATOR_EXPIRATION_TIME_MS = 30 * 1000;\n * export const AUTHENTICATOR_RENEWAL_WINDOW_MS = 10 * 1000;\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.
|
|
3
|
+
"version": "0.1.10",
|
|
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",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@phantom/api-key-stamper": "^0.1.5",
|
|
43
43
|
"@phantom/base64url": "^0.1.0",
|
|
44
|
-
"@phantom/client": "^0.1.
|
|
44
|
+
"@phantom/client": "^0.1.11",
|
|
45
45
|
"@phantom/constants": "^0.0.3",
|
|
46
46
|
"@phantom/parsers": "^0.0.7",
|
|
47
47
|
"@phantom/sdk-types": "^0.1.5",
|