UNPKG

bitmask-core

Version:

Core functionality for the BitMask wallet

164 lines (163 loc) 9.09 kB
"use strict"; // Methods meant to work with BDK defined within the web::bitcoin module from bitmask-core: // https://github.com/diba-io/bitmask-core/blob/development/src/web.rs var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.quoteSwapFeeSats = exports.guessSwapVbytes = exports.feeFromRate = exports.fetchFeeEstimates = exports.bumpFee = exports.drainWallet = exports.getAssetsVault = exports.fundVault = exports.sendSats = exports.getNewAddress = exports.getWalletData = exports.encryptWallet = exports.newWallet = exports.syncWallets = exports.upgradeWallet = exports.decryptWallet = exports.hashPassword = void 0; const BMC = __importStar(require("./bitmask_core")); const constants_1 = require("./constants"); const hashPassword = (password) => BMC.hash_password(password); exports.hashPassword = hashPassword; const decryptWallet = (hash, encryptedDescriptors, seedPassword = "") => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.decrypt_wallet(hash, encryptedDescriptors, seedPassword)); }); exports.decryptWallet = decryptWallet; const upgradeWallet = (hash, encryptedDescriptors, seedPassword = "") => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.upgrade_wallet(hash, encryptedDescriptors, seedPassword)); }); exports.upgradeWallet = upgradeWallet; const syncWallets = () => __awaiter(void 0, void 0, void 0, function* () { return BMC.sync_wallets(); }); exports.syncWallets = syncWallets; const newWallet = (hash, seedPassword) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.new_wallet(hash, seedPassword)); }); exports.newWallet = newWallet; const encryptWallet = (mnemonic, hash, seedPassword) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.encrypt_wallet(mnemonic, hash, seedPassword)); }); exports.encryptWallet = encryptWallet; const getWalletData = (descriptor, changeDescriptor) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.get_wallet_data(descriptor, changeDescriptor)); }); exports.getWalletData = getWalletData; const getNewAddress = (descriptor, changeDescriptor) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.get_new_address(descriptor, changeDescriptor)); }); exports.getNewAddress = getNewAddress; const sendSats = (descriptor, changeDescriptor, address, amount, broadcast, feeRate) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.send_sats(descriptor, changeDescriptor, address, amount, broadcast, feeRate)); }); exports.sendSats = sendSats; const fundVault = (descriptor, changeDescriptor, rgbAddress, broadcast, feeRate) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.fund_vault(descriptor, changeDescriptor, rgbAddress, broadcast, feeRate)); }); exports.fundVault = fundVault; const getAssetsVault = (rgbDescriptorXpub) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.get_assets_vault(rgbDescriptorXpub)); }); exports.getAssetsVault = getAssetsVault; const drainWallet = (destination, descriptor, changeDescriptor, feeRate) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.drain_wallet(destination, descriptor, changeDescriptor, feeRate)); }); exports.drainWallet = drainWallet; const bumpFee = (txid, feeRate, broadcast, descriptor, changeDescriptor) => __awaiter(void 0, void 0, void 0, function* () { return JSON.parse(yield BMC.bump_fee(txid, feeRate, descriptor, changeDescriptor, broadcast)); }); exports.bumpFee = bumpFee; function fetchFeeEstimates() { return __awaiter(this, void 0, void 0, function* () { const net = yield (0, constants_1.getNetwork)(); // Map exact network to explicit env key as requested // bitcoin -> BITCOIN_EXPLORER_API_MAINNET // testnet -> BITCOIN_EXPLORER_API_TESTNET // signet -> BITCOIN_EXPLORER_API_SIGNET // regtest -> BITCOIN_EXPLORER_API_REGTEST let envKey; switch (net) { case "bitcoin": envKey = "BITCOIN_EXPLORER_API_MAINNET"; break; case "testnet": envKey = "BITCOIN_EXPLORER_API_TESTNET"; break; case "signet": envKey = "BITCOIN_EXPLORER_API_SIGNET"; break; case "regtest": envKey = "BITCOIN_EXPLORER_API_REGTEST"; break; default: // Fallback to testnet if unknown string is returned envKey = "BITCOIN_EXPLORER_API_TESTNET"; break; } const base = yield (0, constants_1.getEnv)(envKey); if (!base) { throw new Error(`fee-estimates: missing env ${envKey} for network ${net}`); } const baseUrl = (base || "").replace(/\/$/, ""); const url = `${baseUrl}/fee-estimates`; const resp = yield fetch(url, { method: "GET" }); if (!resp.ok) { const text = yield resp.text().catch(() => ""); throw new Error(`fee-estimates fetch failed ${resp.status}: ${text}`); } return (yield resp.json()); }); } exports.fetchFeeEstimates = fetchFeeEstimates; /** * Compute absolute fee in sats from a sat/vB rate and an estimated vsize. * Always ceil so we don't underpay policy minimums. */ function feeFromRate(vbytes, satPerVb) { return Math.ceil(vbytes * satPerVb); } exports.feeFromRate = feeFromRate; /** * Rough vbytes guesser for swap/bid PSBTs when you don't yet know exact inputs/outputs. * Prefer passing a conservative bound to avoid underpaying relays: * - Default assumes ~2 inputs, ~3 outputs, taproot heavy mix, returns ~400 vB. * - Scale linearly for more inputs/outputs. * * If you know inputs/outputs counts beforehand, pass them to tighten the estimate. */ function guessSwapVbytes(inputs = 2, outputs = 3, taprootHeavy = true) { // Heuristic base (conservative): taproot-heavy ~180 vB per input, ~34 vB per output, +10 overhead // Non-taproot may be slightly bigger; this errs on the safe side. const perIn = taprootHeavy ? 180 : 200; const perOut = 34; const overhead = 10; // Ensure a floor to avoid extremely small estimates in edge cases const est = inputs * perIn + outputs * perOut + overhead; return Math.max(est, 300); } exports.guessSwapVbytes = guessSwapVbytes; /** * Convenience: get a safe absolute fee quote for a swap given a target confirmation bucket. * - bucket can be "1","2","3","6","144", etc., matching Esplora keys. * - vbytesEstimate can be computed via guessSwapVbytes() or a tighter UI estimate. * - Adds a small 10% safety margin on the feerate to reduce min-relay rejections. */ function quoteSwapFeeSats(bucket, vbytesEstimate) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const estimates = yield fetchFeeEstimates(); const satPerVb = (_b = (_a = estimates[bucket]) !== null && _a !== void 0 ? _a : estimates["6"]) !== null && _b !== void 0 ? _b : 1.0; const paddedRate = Math.max(1.0, satPerVb * 1.1); // 10% headroom const fee = feeFromRate(vbytesEstimate, paddedRate); return { rate: paddedRate, fee }; }); } exports.quoteSwapFeeSats = quoteSwapFeeSats;