UNPKG

@bsv/sdk

Version:

BSV Blockchain Software Development Kit

218 lines 9.49 kB
import WindowCWISubstrate from './substrates/window.CWI.js'; import XDMSubstrate from './substrates/XDM.js'; import WalletWireTransceiver from './substrates/WalletWireTransceiver.js'; import HTTPWalletWire from './substrates/HTTPWalletWire.js'; import HTTPWalletJSON from './substrates/HTTPWalletJSON.js'; import ReactNativeWebView from './substrates/ReactNativeWebView.js'; import { validateAbortActionArgs, validateAcquireDirectCertificateArgs, validateAcquireIssuanceCertificateArgs, validateCreateActionArgs, validateDiscoverByAttributesArgs, validateDiscoverByIdentityKeyArgs, validateInternalizeActionArgs, validateListActionsArgs, validateListCertificatesArgs, validateListOutputsArgs, validateProveCertificateArgs, validateRelinquishCertificateArgs, validateRelinquishOutputArgs, validateSignActionArgs } from './validationHelpers.js'; import { WERR_INVALID_PARAMETER } from './WERR_INVALID_PARAMETER.js'; const MAX_XDM_RESPONSE_WAIT = 200; /** * The SDK is how applications communicate with wallets over a communications substrate. */ export default class WalletClient { substrate; originator; constructor(substrate = 'auto', originator) { if (substrate === 'Cicada') { substrate = new WalletWireTransceiver(new HTTPWalletWire(originator)); } if (substrate === 'window.CWI') substrate = new WindowCWISubstrate(); if (substrate === 'XDM') substrate = new XDMSubstrate(); if (substrate === 'json-api') substrate = new HTTPWalletJSON(originator); if (substrate === 'react-native') substrate = new ReactNativeWebView(originator); if (substrate === 'secure-json-api') substrate = new HTTPWalletJSON(originator, 'https://localhost:2121'); this.substrate = substrate; this.originator = originator; } async connectToSubstrate() { if (typeof this.substrate === 'object') { return; // substrate is already connected } const attemptSubstrate = async (factory, timeout) => { try { const sub = factory(); let result; if (typeof timeout === 'number') { result = await Promise.race([ sub.getVersion({}), new Promise((_resolve, reject) => setTimeout(() => reject(new Error('Timed out.')), timeout)) ]); } else { result = await sub.getVersion({}); } if (typeof result !== 'object' || typeof result.version !== 'string') { return { success: false }; } return { success: true, sub }; } catch { return { success: false }; } }; // Try fast substrates first const fastAttempts = [ attemptSubstrate(() => new WindowCWISubstrate()), attemptSubstrate(() => new HTTPWalletJSON(this.originator, 'https://localhost:2121')), attemptSubstrate(() => new HTTPWalletJSON(this.originator)), attemptSubstrate(() => new ReactNativeWebView(this.originator)), attemptSubstrate(() => new WalletWireTransceiver(new HTTPWalletWire(this.originator))) ]; const fastResults = await Promise.allSettled(fastAttempts); const fastSuccessful = fastResults .filter((r) => r.status === 'fulfilled' && r.value.success && r.value.sub !== undefined) .map(r => r.value.sub); if (fastSuccessful.length > 0) { this.substrate = fastSuccessful[0]; return; } // Fall back to slower XDM substrate const xdmResult = await attemptSubstrate(() => new XDMSubstrate(), MAX_XDM_RESPONSE_WAIT); if (xdmResult.success && xdmResult.sub !== undefined) { this.substrate = xdmResult.sub; } else { throw new Error('No wallet available over any communication substrate. Install a BSV wallet today!'); } } async createAction(args) { validateCreateActionArgs(args); await this.connectToSubstrate(); return await this.substrate.createAction(args, this.originator); } async signAction(args) { validateSignActionArgs(args); await this.connectToSubstrate(); return await this.substrate.signAction(args, this.originator); } async abortAction(args) { validateAbortActionArgs(args); await this.connectToSubstrate(); return await this.substrate.abortAction(args, this.originator); } async listActions(args) { validateListActionsArgs(args); await this.connectToSubstrate(); return await this.substrate.listActions(args, this.originator); } async internalizeAction(args) { validateInternalizeActionArgs(args); await this.connectToSubstrate(); return await this.substrate.internalizeAction(args, this.originator); } async listOutputs(args) { validateListOutputsArgs(args); await this.connectToSubstrate(); return await this.substrate.listOutputs(args, this.originator); } async relinquishOutput(args) { validateRelinquishOutputArgs(args); await this.connectToSubstrate(); return await this.substrate.relinquishOutput(args, this.originator); } async getPublicKey(args) { await this.connectToSubstrate(); return await this.substrate.getPublicKey(args, this.originator); } async revealCounterpartyKeyLinkage(args) { await this.connectToSubstrate(); return await this.substrate.revealCounterpartyKeyLinkage(args, this.originator); } async revealSpecificKeyLinkage(args) { await this.connectToSubstrate(); return await this.substrate.revealSpecificKeyLinkage(args, this.originator); } async encrypt(args) { await this.connectToSubstrate(); return await this.substrate.encrypt(args, this.originator); } async decrypt(args) { await this.connectToSubstrate(); return await this.substrate.decrypt(args, this.originator); } async createHmac(args) { await this.connectToSubstrate(); return await this.substrate.createHmac(args, this.originator); } async verifyHmac(args) { await this.connectToSubstrate(); return await this.substrate.verifyHmac(args, this.originator); } async createSignature(args) { await this.connectToSubstrate(); return await this.substrate.createSignature(args, this.originator); } async verifySignature(args) { await this.connectToSubstrate(); return await this.substrate.verifySignature(args, this.originator); } async acquireCertificate(args) { if (args.acquisitionProtocol === 'direct') { validateAcquireDirectCertificateArgs(args); } else if (args.acquisitionProtocol === 'issuance') { validateAcquireIssuanceCertificateArgs(args); } else { throw new WERR_INVALID_PARAMETER('acquisitionProtocol', `valid. ${String(args.acquisitionProtocol)} is unrecognized.`); } await this.connectToSubstrate(); return await this.substrate.acquireCertificate(args, this.originator); } async listCertificates(args) { validateListCertificatesArgs(args); await this.connectToSubstrate(); return await this.substrate.listCertificates(args, this.originator); } async proveCertificate(args) { validateProveCertificateArgs(args); await this.connectToSubstrate(); return await this.substrate.proveCertificate(args, this.originator); } async relinquishCertificate(args) { validateRelinquishCertificateArgs(args); await this.connectToSubstrate(); return await this.substrate.relinquishCertificate(args, this.originator); } async discoverByIdentityKey(args) { validateDiscoverByIdentityKeyArgs(args); await this.connectToSubstrate(); return await this.substrate.discoverByIdentityKey(args, this.originator); } async discoverByAttributes(args) { validateDiscoverByAttributesArgs(args); await this.connectToSubstrate(); return await this.substrate.discoverByAttributes(args, this.originator); } async isAuthenticated(args = {}) { await this.connectToSubstrate(); return await this.substrate.isAuthenticated(args, this.originator); } async waitForAuthentication(args = {}) { await this.connectToSubstrate(); return await this.substrate.waitForAuthentication(args, this.originator); } async getHeight(args = {}) { await this.connectToSubstrate(); return await this.substrate.getHeight(args, this.originator); } async getHeaderForHeight(args) { await this.connectToSubstrate(); return await this.substrate.getHeaderForHeight(args, this.originator); } async getNetwork(args = {}) { await this.connectToSubstrate(); return await this.substrate.getNetwork(args, this.originator); } async getVersion(args = {}) { await this.connectToSubstrate(); return await this.substrate.getVersion(args, this.originator); } } //# sourceMappingURL=WalletClient.js.map