UNPKG

@bsv/wallet-toolbox-client

Version:
113 lines 5.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WalletAuthenticationManager = void 0; const CWIStyleWalletManager_1 = require("./CWIStyleWalletManager"); const sdk_1 = require("@bsv/sdk"); /** * WalletAuthenticationManager * * A wallet manager that integrates * with a WABClient for user authentication flows (e.g. Twilio phone). */ class WalletAuthenticationManager extends CWIStyleWalletManager_1.CWIStyleWalletManager { constructor(adminOriginator, walletBuilder, interactor = new CWIStyleWalletManager_1.OverlayUMPTokenInteractor(), recoveryKeySaver, passwordRetriever, wabClient, authMethod, stateSnapshot) { super(adminOriginator, walletBuilder, interactor, recoveryKeySaver, passwordRetriever, // Here, we provide a custom new wallet funder that uses the Secret Server async (presentationKey, wallet, adminOriginator) => { debugger; const { paymentData } = await this.wabClient.requestFaucet(sdk_1.Utils.toHex(presentationKey)); if (!paymentData.k || !paymentData.tx) { throw new Error('Invalid'); } const tx = sdk_1.Transaction.fromAtomicBEEF(paymentData.tx); console.log(paymentData); const faucetRedeemTXCreationResult = await wallet.createAction({ inputBEEF: tx.toBEEF(), inputs: [ { outpoint: `${paymentData.txid}.0`, unlockingScriptLength: 108, inputDescription: 'Fund from faucet' } ], description: 'Fund wallet', options: { acceptDelayedBroadcast: false } }, adminOriginator); const faucetRedeemTX = sdk_1.Transaction.fromAtomicBEEF(faucetRedeemTXCreationResult.signableTransaction.tx); const faucetRedemptionPuzzle = new sdk_1.RPuzzle(); const randomRedemptionPrivateKey = sdk_1.PrivateKey.fromRandom(); const faucetRedeemUnlocker = faucetRedemptionPuzzle.unlock(new sdk_1.BigNumber(paymentData.k, 16), randomRedemptionPrivateKey); const faucetRedeemUnlockingScript = await faucetRedeemUnlocker.sign(faucetRedeemTX, 0); const signActionResult = await wallet.signAction({ reference: faucetRedeemTXCreationResult.signableTransaction.reference, spends: { 0: { unlockingScript: faucetRedeemUnlockingScript.toHex() } } }); console.log('Sign action result:', signActionResult); }, stateSnapshot); this.wabClient = wabClient; this.authMethod = authMethod; } /** * Sets (or switches) the chosen AuthMethodInteractor at runtime, * in case the user changes their mind or picks a new method in the UI. */ setAuthMethod(method) { this.authMethod = method; } /** * Initiate the WAB-based flow, e.g. sending an SMS code or starting an ID check, * using the chosen AuthMethodInteractor. */ async startAuth(payload) { if (!this.authMethod) { throw new Error('No AuthMethod selected in WalletAuthenticationManager'); } this.tempPresentationKey = this.generateTemporaryPresentationKey(); // For example, if this.authMethod is Twilio, `payload` might contain { phoneNumber: "+1..." } const startRes = await this.wabClient.startAuthMethod(this.authMethod, // The user might not have a presentationKey yet, so we generate one locally to pass to the server. // If it’s an existing user on the WAB side, the WAB will give us the stored key later. // But we do need some placeholder key for the 'startAuth' call: this.tempPresentationKey, payload); if (!startRes.success) { throw new Error(startRes.message || 'Failed to start WAB auth method'); } } /** * Completes the WAB-based flow, retrieving the final presentationKey from WAB if successful. */ async completeAuth(payload) { if (!this.authMethod || !this.tempPresentationKey) { throw new Error('No AuthMethod selected in WalletAuthenticationManager or startAuth has yet to be called.'); } // Unser the temp presentation key early (for security) const tempKey = this.tempPresentationKey; this.tempPresentationKey = undefined; const result = await this.wabClient.completeAuthMethod(this.authMethod, tempKey, payload); if (!result.success || !result.presentationKey) { throw new Error(result.message || 'Failed to complete WAB auth'); } // We now have the final 256-bit key in hex from the WAB const presentationKeyHex = result.presentationKey; const presentationKeyBytes = sdk_1.Utils.toArray(presentationKeyHex, 'hex'); // Provide this presentation key to the underlying CWI logic: // This sets 'this.presentationKey' and determines if it's a new or existing user // based on whether a UMP token exists on chain. We'll do "presentation-key-and-password" // for new user flows, for example, or user might choose "presentation-key-and-recovery-key" if we wanted. // Either way, WAB has now done its job and we are off to base-layer CWI logic at this point! await this.providePresentationKey(presentationKeyBytes); } generateTemporaryPresentationKey() { // For the 'startAuth' call, we can generate a random 32 bytes → 64 hex chars. const randomBytes = (0, sdk_1.Random)(32); // array of length 32 return sdk_1.Utils.toHex(randomBytes); } } exports.WalletAuthenticationManager = WalletAuthenticationManager; //# sourceMappingURL=WalletAuthenticationManager.js.map