UNPKG

@bsv/wallet-toolbox-client

Version:
226 lines 8.65 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SetupClient = void 0; const sdk_1 = require("@bsv/sdk"); const StorageIdb_1 = require("./storage/StorageIdb"); const WalletStorageManager_1 = require("./storage/WalletStorageManager"); const Services_1 = require("./services/Services"); const Monitor_1 = require("./monitor/Monitor"); const PrivilegedKeyManager_1 = require("./sdk/PrivilegedKeyManager"); const Wallet_1 = require("./Wallet"); const utilityHelpers_1 = require("./utility/utilityHelpers"); const StorageClient_1 = require("./storage/remoting/StorageClient"); /** * The 'Setup` class provides static setup functions to construct BRC-100 compatible * wallets in a variety of configurations. * * It serves as a starting point for experimentation and customization. */ class SetupClient { /** * Create a `Wallet`. Storage can optionally be provided or configured later. * * The following components are configured: KeyDeriver, WalletStorageManager, WalletService, WalletStorage. * Optionally, PrivilegedKeyManager is also configured. * * @publicbody */ static async createWallet(args) { const chain = args.chain; const rootKey = sdk_1.PrivateKey.fromHex(args.rootKeyHex); const identityKey = rootKey.toPublicKey().toString(); const keyDeriver = new sdk_1.CachedKeyDeriver(rootKey); const storage = new WalletStorageManager_1.WalletStorageManager(identityKey, args.active, args.backups); if (storage.canMakeAvailable()) await storage.makeAvailable(); const serviceOptions = Services_1.Services.createDefaultOptions(chain); serviceOptions.taalApiKey = args.taalApiKey; const services = new Services_1.Services(serviceOptions); const monopts = Monitor_1.Monitor.createDefaultWalletMonitorOptions(chain, storage, services); const monitor = new Monitor_1.Monitor(monopts); monitor.addDefaultTasks(); const privilegedKeyManager = args.privilegedKeyGetter ? new PrivilegedKeyManager_1.PrivilegedKeyManager(args.privilegedKeyGetter) : undefined; const wallet = new Wallet_1.Wallet({ chain, keyDeriver, storage, services, monitor, privilegedKeyManager }); const r = { rootKey, identityKey, keyDeriver, chain, storage, services, monitor, wallet }; return r; } /** * Setup a new `Wallet` without requiring a .env file. * * @param args.chain - 'main' or 'test' * @param args.rootKeyHex - Root private key for wallet's key deriver. * @param args.storageUrl - Optional. `StorageClient` and `chain` compatible endpoint URL. * @param args.privilegedKeyGetter - Optional. Method that will return the privileged `PrivateKey`, on demand. */ static async createWalletClientNoEnv(args) { const chain = args.chain; const endpointUrl = args.storageUrl || `https://${args.chain !== 'main' ? 'staging-' : ''}storage.babbage.systems`; const rootKey = sdk_1.PrivateKey.fromHex(args.rootKeyHex); const keyDeriver = new sdk_1.CachedKeyDeriver(rootKey); const storage = new WalletStorageManager_1.WalletStorageManager(keyDeriver.identityKey); const services = new Services_1.Services(chain); const privilegedKeyManager = args.privilegedKeyGetter ? new PrivilegedKeyManager_1.PrivilegedKeyManager(args.privilegedKeyGetter) : undefined; const wallet = new Wallet_1.Wallet({ chain, keyDeriver, storage, services, privilegedKeyManager }); const client = new StorageClient_1.StorageClient(wallet, endpointUrl); await storage.addWalletStorageProvider(client); await storage.makeAvailable(); return wallet; } /** * @publicbody */ static async createWalletClient(args) { const wo = await SetupClient.createWallet(args); const endpointUrl = args.endpointUrl || `https://${args.chain !== 'main' ? 'staging-' : ''}storage.babbage.systems`; const client = new StorageClient_1.StorageClient(wo.wallet, endpointUrl); await wo.storage.addWalletStorageProvider(client); await wo.storage.makeAvailable(); return { ...wo, endpointUrl }; } /** * @publicbody */ static getKeyPair(priv) { if (priv === undefined) priv = sdk_1.PrivateKey.fromRandom(); else if (typeof priv === 'string') priv = new sdk_1.PrivateKey(priv, 'hex'); const pub = sdk_1.PublicKey.fromPrivateKey(priv); const address = pub.toAddress(); return { privateKey: priv, publicKey: pub, address }; } /** * @publicbody */ static getLockP2PKH(address) { const p2pkh = new sdk_1.P2PKH(); const lock = p2pkh.lock(address); return lock; } /** * @publicbody */ static getUnlockP2PKH(priv, satoshis) { const p2pkh = new sdk_1.P2PKH(); const lock = SetupClient.getLockP2PKH(SetupClient.getKeyPair(priv).address); // Prepare to pay with SIGHASH_ALL and without ANYONE_CAN_PAY. // In otherwords: // - all outputs must remain in the current order, amount and locking scripts. // - all inputs must remain from the current outpoints and sequence numbers. // (unlock scripts are never signed) const unlock = p2pkh.unlock(priv, 'all', false, satoshis, lock); return unlock; } /** * @publicbody */ static createP2PKHOutputs(outputs) { const os = []; const count = outputs.length; for (let i = 0; i < count; i++) { const o = outputs[i]; os.push({ basket: o.basket, tags: o.tags, satoshis: o.satoshis, lockingScript: SetupClient.getLockP2PKH(o.address).toHex(), outputDescription: o.outputDescription || `p2pkh ${i}` }); } return os; } /** * @publicbody */ static async createP2PKHOutputsAction(wallet, outputs, options) { const os = SetupClient.createP2PKHOutputs(outputs); const createArgs = { description: `createP2PKHOutputs`, outputs: os, options: { ...options, // Don't randomize so we can simplify outpoint creation randomizeOutputs: false } }; const cr = await wallet.createAction(createArgs); let outpoints; if (cr.txid) { outpoints = os.map((o, i) => `${cr.txid}.${i}`); } return { cr, outpoints }; } /** * @publicbody */ static async fundWalletFromP2PKHOutpoints(wallet, outpoints, p2pkhKey, inputBEEF) { // TODO } /** * Adds `indexedDB` based storage to a `Wallet` configured by `SetupClient.createWalletOnly` * * @param args.databaseName Name for this storage. For MySQL, the schema name within the MySQL instance. * @param args.chain Which chain this wallet is on: 'main' or 'test'. Defaults to 'test'. * @param args.rootKeyHex * * @publicbody */ static async createWalletIdb(args) { const wo = await SetupClient.createWallet(args); const activeStorage = await SetupClient.createStorageIdb(args); await wo.storage.addWalletStorageProvider(activeStorage); const { user, isNew } = await activeStorage.findOrInsertUser(wo.identityKey); const userId = user.userId; const r = { ...wo, activeStorage, userId }; return r; } /** * @returns {StorageIdb} - `Knex` based storage provider for a wallet. May be used for either active storage or backup storage. */ static async createStorageIdb(args) { const storage = new StorageIdb_1.StorageIdb({ chain: args.chain, commissionSatoshis: 0, commissionPubKeyHex: undefined, feeModel: { model: 'sat/kb', value: 1 } }); await storage.migrate(args.databaseName, (0, utilityHelpers_1.randomBytesHex)(33)); await storage.makeAvailable(); return storage; } } exports.SetupClient = SetupClient; //# sourceMappingURL=SetupClient.js.map