UNPKG

@turnkey/core

Version:

A core JavaScript web and React Native package for interfacing with Turnkey's infrastructure.

101 lines (98 loc) 4.47 kB
import { isWeb, isReactNative } from '../../utils.mjs'; import { IndexedDbStamper } from './web/stamper.mjs'; import { TurnkeyError, TurnkeyErrorCodes } from '@turnkey/sdk-types'; import { SignatureFormat } from '@turnkey/api-key-stamper'; /** * Cross-platform API key stamper. * * - This stamper uses indexedDB on web and keychain on react-native to securely stamp Turnkey requests. * - ***Only supports P-256 ECDSA key pairs.*** */ class CrossPlatformApiKeyStamper { constructor(storageManager) { this.storageManager = storageManager; // Use init method to set up the stamper based on the platform. It's async, so can't be done in the constructor. } async init() { if (isWeb()) { this.stamper = new IndexedDbStamper(); } else if (isReactNative()) { try { // Dynamic import to prevent bundling the native module in web environments. const { ReactNativeKeychainStamper } = await import('./mobile/stamper.mjs'); this.stamper = new ReactNativeKeychainStamper(); } catch (error) { throw new TurnkeyError(`Failed to load keychain stamper for react-native`, TurnkeyErrorCodes.INITIALIZE_CLIENT_ERROR, error); } } else { throw new TurnkeyError("Unsupported platform for API key stamper", TurnkeyErrorCodes.UNSUPPORTED_PLATFORM); } } listKeyPairs() { if (!this.stamper) { throw new TurnkeyError("Stamper is not initialized. Please call .init() before calling this method.", TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED); } return this.stamper.listKeyPairs(); } createKeyPair(externalKeyPair) { if (!this.stamper) { throw new TurnkeyError("Stamper is not initialized. Please call .init() before calling this method.", TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED); } return this.stamper.createKeyPair(externalKeyPair); } deleteKeyPair(publicKeyHex) { if (!this.stamper) { throw new TurnkeyError("Stamper is not initialized. Please call .init() before calling this method.", TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED); } // If the deleted key pair is the temporary one, clear it. if (this.temporaryPublicKey === publicKeyHex) { this.temporaryPublicKey = undefined; } return this.stamper.deleteKeyPair(publicKeyHex); } // This allows forcing a specific public key to find the key pair for stamping. The key pair must already exist in indexedDB / Keychain. // This is useful if you need to stamp with a specific key pair without having an active session. // See "signUpWithPasskey" function in core.ts for usage setTemporaryPublicKey(publicKeyHex) { this.temporaryPublicKey = publicKeyHex; } getTemporaryPublicKey() { return this.temporaryPublicKey; } clearTemporaryPublicKey() { this.temporaryPublicKey = undefined; } async stamp(payload) { if (!this.stamper) { throw new TurnkeyError("Stamper is not initialized. Please call .init() before calling this method.", TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED); } let publicKeyHex = this.temporaryPublicKey; if (!publicKeyHex) { const session = await this.storageManager.getActiveSession(); if (!session) { throw new TurnkeyError("No active session or token available.", TurnkeyErrorCodes.NO_SESSION_FOUND); } publicKeyHex = session.publicKey; } return this.stamper.stamp(payload, publicKeyHex); } async sign(payload, format = SignatureFormat.Der) { if (!this.stamper) { throw new TurnkeyError("Stamper is not initialized. Please call .init() before calling this method.", TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED); } let publicKeyHex = this.temporaryPublicKey; if (!publicKeyHex) { const session = await this.storageManager.getActiveSession(); if (!session) { throw new TurnkeyError("No active session or token available.", TurnkeyErrorCodes.NO_SESSION_FOUND); } publicKeyHex = session.publicKey; } return this.stamper.sign(payload, publicKeyHex, format); } } export { CrossPlatformApiKeyStamper }; //# sourceMappingURL=base.mjs.map