feat(theseus/aegis): DGB adapter on @dgb-wallet/{core,psbt} vendored packages
Aegis now shares its DGB code with the standalone DigiByte web-wallet at
D:\Dev\SilentCode\Digibyte. Address derivation and PSBT construction come
from that project's @dgb-wallet/core and @dgb-wallet/psbt packages instead
of Aegis-local reimplementations. Any bugfix upstream flows in via a
re-vendor of dist/*.
- lib/dgb/{core,psbt}/ — vendored dist/ output of the two packages plus
a tiny package.json shim marking them as ESM. @dgb-wallet/core's own
import specifier "@dgb-wallet/core" inside psbt/*.js is rewritten to
"../core/index.js" so the sibling module resolves without a workspace.
- New Theseus deps: bitcoinjs-lib, bip32, bip39, @bitcoinerlab/secp256k1,
ecpair — the peer deps the vendored packages need. Loaded via
api.require in index.js's loadDeps().
- chain-dgb.js is a thin adapter now: BIP32 tree via bip32 + DGB
Network object, addresses via core.p2wpkhAddress, tx via
psbt.buildPsbt + PSBT.signInput (per-input, since each UTXO's key
differs) + psbt.finalizeAndExtract. Runtime backend stays the same —
Theseus's lib/electrum.js against the DGB ElectrumX pool.
- Verified end-to-end in scratchpad: abandon×11 mnemonic derives
dgb1q9gmf0pv8jdymcly6lz6fl7lf6mhslsd72e2jq8 (matches iancoleman.io/bip39
and the previous inline implementation, so no on-chain address change
for anyone who was already using Aegis's DGB slot). PSBT build+sign+
finalize on a mock UTXO produces a valid 223-byte witness tx.
BIP44 (D…) and BIP49 (S…) address families are implemented in the
vendored core but not yet exposed in Aegis's picker — the panel needs
an "address family" selector inside the DGB settings block first. Left
for a follow-up; today's DGB pick uses BIP84 native SegWit only.
This commit is contained in:
parent
118de0ef5c
commit
4c63ae1bc7
28 changed files with 1183 additions and 214 deletions
|
|
@ -32,7 +32,6 @@ async function loadDeps(api) {
|
|||
const { keccak_256 } = await api.import("@noble/hashes/sha3.js");
|
||||
const { blake2b } = await api.import("@noble/hashes/blake2.js");
|
||||
const { HDKey } = await api.import("@scure/bip32");
|
||||
const { bech32 } = await api.import("@scure/base");
|
||||
const WebSocket = api.require("ws");
|
||||
const cashaddr = require("./lib/cashaddr.js");
|
||||
const keysLib = require("./lib/keys.js")({ HDKey, secp256k1, sha256, ripemd160, cashaddr });
|
||||
|
|
@ -46,12 +45,26 @@ async function loadDeps(api) {
|
|||
HDKey, secp256k1, sha256, keccak_256, base58check,
|
||||
});
|
||||
const siaAdapter = require("./lib/chain-sia.js")({ ed25519, blake2b });
|
||||
// DGB delegates address derivation + PSBT to the vendored @dgb-wallet/*
|
||||
// packages under lib/dgb/. Those are ESM; the peer deps (bitcoinjs-lib,
|
||||
// bip32, ecpair, @bitcoinerlab/secp256k1) are CommonJS and reachable via
|
||||
// api.require from the Theseus dependency tree.
|
||||
const { pathToFileURL } = require("node:url");
|
||||
const dgbCore = await import(pathToFileURL(path.join(api.folder, "lib/dgb/core/index.js")).href);
|
||||
const dgbPsbt = await import(pathToFileURL(path.join(api.folder, "lib/dgb/psbt/index.js")).href);
|
||||
const bitcoinjs = api.require("bitcoinjs-lib");
|
||||
const { BIP32Factory } = api.require("bip32");
|
||||
const { ECPairFactory } = api.require("ecpair");
|
||||
const ecc = api.require("@bitcoinerlab/secp256k1");
|
||||
const dgbAdapter = require("./lib/chain-dgb.js")({
|
||||
HDKey, secp256k1, sha256, ripemd160, bech32, electrum,
|
||||
dgbCore, dgbPsbt, bitcoinjs,
|
||||
bip32Factory: BIP32Factory, ecpairFactory: ECPairFactory, ecc,
|
||||
sha256, electrum,
|
||||
});
|
||||
return { HDKey, secp256k1, ed25519, sha256, ripemd160, keccak_256, blake2b, bech32,
|
||||
return { HDKey, secp256k1, ed25519, sha256, ripemd160, keccak_256, blake2b,
|
||||
cashaddr, keysLib, tx, electrum, base58check,
|
||||
bchAdapter, tronAdapter, siaAdapter, dgbAdapter };
|
||||
bchAdapter, tronAdapter, siaAdapter, dgbAdapter,
|
||||
dgbCore, dgbPsbt, bitcoinjs, ecc };
|
||||
}
|
||||
|
||||
// ---- servers ---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,23 +1,25 @@
|
|||
// DigiByte (DGB) chain adapter — BIP84 native SegWit v0 (dgb1q…) over
|
||||
// ElectrumX-DGB. Ported from the DigiByte-mobile design at
|
||||
// SilentCode/Digibyte/packages/core, trimmed to what a browser-side wallet
|
||||
// needs: HD derivation, address/balance/history + BIP143 P2WPKH send.
|
||||
// DigiByte (DGB) chain adapter — thin bridge over the @dgb-wallet/* packages
|
||||
// vendored under lib/dgb/ from D:\Dev\SilentCode\Digibyte\packages\{core,psbt}.
|
||||
// Address derivation, network params and PSBT construction come from the
|
||||
// upstream design; Aegis provides the runtime shell (ElectrumX transport,
|
||||
// gap-limit scanning, wallet-manager plumbing).
|
||||
//
|
||||
// Chain params from DGB Core src/kernel/chainparams.cpp CMainParams:
|
||||
// pubKeyHash 0x1e, scriptHash 0x3f, bech32 HRP "dgb", SLIP-44 coin type 20.
|
||||
// Backend: DGB ElectrumX pool via Theseus's existing lib/electrum.js — same
|
||||
// TCP-over-wss stack the BCH wallet uses, no separate protocol adapter.
|
||||
// Optional Blockbook mode is on the roadmap; ElectrumX is the default
|
||||
// because it matches Aegis's transport shape and needs no per-server keys.
|
||||
//
|
||||
// Only BIP84 is implemented here (m/84'/20'/0'/0/x → dgb1q…). Legacy P2PKH
|
||||
// import (D…) and P2SH-wrapped SegWit (S…) are on the roadmap; they need
|
||||
// address-family selection in the panel and a scriptPubKey-selecting
|
||||
// tx.select variant. For now dgb1q covers the modern DGB user's default.
|
||||
// Only BIP84 (m/84'/20'/0'/0/x → dgb1q…) is exposed in this rev; the
|
||||
// vendored core also supports BIP44 (D…) and BIP49 (S…) — plumb them by
|
||||
// switching the purpose passed to accountNode(). Address recovery from any
|
||||
// BIP39 tool at coin type 20 is guaranteed by bitcoinjs-lib's Network
|
||||
// object, so a seed exported here can be restored on iancoleman.io/bip39
|
||||
// or the SilentCode Digibyte web-wallet with matching addresses.
|
||||
|
||||
const NETWORK = "mainnet";
|
||||
const DGB_COIN_TYPE = 20;
|
||||
const DEFAULT_ACCOUNT_PATH = "m/84'/20'/0'";
|
||||
const HRP = "dgb";
|
||||
const DEFAULT_PURPOSE = 84;
|
||||
const EXPLORER_TX = "https://digiexplorer.info/tx/";
|
||||
const EXPLORER_ADDR = "https://digiexplorer.info/address/";
|
||||
// A small pool of DGB ElectrumX endpoints; the client rotates on failure.
|
||||
const DEFAULT_SERVERS = [
|
||||
"wss://electrum1.cyberbits.eu:50022",
|
||||
"wss://electrum3.cyberbits.eu:50022",
|
||||
|
|
@ -25,154 +27,96 @@ const DEFAULT_SERVERS = [
|
|||
];
|
||||
|
||||
module.exports = function makeDgbAdapter({
|
||||
HDKey, secp256k1, sha256, ripemd160, bech32, electrum,
|
||||
dgbCore, // ESM namespace of @dgb-wallet/core (vendored)
|
||||
dgbPsbt, // ESM namespace of @dgb-wallet/psbt (vendored)
|
||||
bitcoinjs, // require("bitcoinjs-lib")
|
||||
bip32Factory, // require("bip32").BIP32Factory
|
||||
ecpairFactory, // require("ecpair").ECPairFactory
|
||||
ecc, // require("@bitcoinerlab/secp256k1")
|
||||
sha256, // @noble/hashes/sha2 (only used for scripthash reversal)
|
||||
electrum,
|
||||
}) {
|
||||
if (!HDKey || !secp256k1 || !sha256 || !ripemd160 || !bech32 || !electrum) {
|
||||
if (!dgbCore || !dgbPsbt || !bitcoinjs || !bip32Factory || !ecpairFactory || !ecc || !electrum) {
|
||||
throw new Error("chain-dgb: missing dep");
|
||||
}
|
||||
const hash160 = (b) => ripemd160(sha256(b));
|
||||
const dsha = (b) => sha256(sha256(b));
|
||||
const toHex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
||||
const fromHex = (h) => Uint8Array.from((h.match(/../g) || []), (x) => parseInt(x, 16));
|
||||
const concat = (...ps) => { const n = ps.reduce((a, p) => a + p.length, 0); const o = new Uint8Array(n); let k = 0; for (const p of ps) { o.set(p, k); k += p.length; } return o; };
|
||||
const u32le = (n) => Uint8Array.from([n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff]);
|
||||
const u64le = (n) => { let v = BigInt(n); const o = new Uint8Array(8); for (let i = 0; i < 8; i++) { o[i] = Number(v & 0xffn); v >>= 8n; } return o; };
|
||||
const varint = (n) => {
|
||||
if (n < 0xfd) return Uint8Array.from([n]);
|
||||
if (n <= 0xffff) return Uint8Array.from([0xfd, n & 0xff, (n >> 8) & 0xff]);
|
||||
return concat(Uint8Array.from([0xfe]), u32le(n));
|
||||
};
|
||||
const varbytes = (b) => concat(varint(b.length), b);
|
||||
const { rootFromSeed, accountNode, addressNode, p2wpkhAddress, digibyte, DGB_COIN_TYPE } = dgbCore;
|
||||
const { buildPsbt, signAllInputs, finalizeAndExtract, feeSats } = dgbPsbt;
|
||||
const { payments, Psbt } = bitcoinjs;
|
||||
const bip32 = bip32Factory(ecc);
|
||||
const ECPair = ecpairFactory(ecc);
|
||||
|
||||
// ---- addresses --------------------------------------------------------
|
||||
// dgb1q…: bech32 (BIP173), witness version 0, program = h160(pubkey).
|
||||
function encodeSegwitV0(h160) {
|
||||
// @scure/base bech32.encode takes hrp and 5-bit words; the version byte
|
||||
// is prepended verbatim (no toWords for it).
|
||||
const words = [0, ...bech32.toWords(h160)];
|
||||
return bech32.encode(HRP, words);
|
||||
const toHex = (b) => Buffer.from(b).toString("hex");
|
||||
// Electrum scripthash: sha256(scriptPubKey), byte-reversed, hex.
|
||||
function scripthashOf(scriptBuf) {
|
||||
const h = sha256(scriptBuf);
|
||||
const rev = Buffer.from(h).reverse();
|
||||
return rev.toString("hex");
|
||||
}
|
||||
function decodeAddress(str) {
|
||||
const s = String(str || "").trim().toLowerCase();
|
||||
if (!s.startsWith(HRP + "1")) throw new Error(`not a DGB bech32 address (want ${HRP}1…)`);
|
||||
const dec = bech32.decode(s);
|
||||
if (dec.prefix !== HRP) throw new Error(`bad HRP: ${dec.prefix}`);
|
||||
const version = dec.words[0];
|
||||
const program = bech32.fromWords(dec.words.slice(1));
|
||||
if (version !== 0 || program.length !== 20) {
|
||||
throw new Error("only P2WPKH (dgb1q…, 20-byte program) is supported in this build");
|
||||
}
|
||||
return { version, program: Uint8Array.from(program) };
|
||||
function scriptPubKeyBuf(pubkeyBuf) {
|
||||
return payments.p2wpkh({ pubkey: pubkeyBuf, network: digibyte }).output;
|
||||
}
|
||||
function scriptPubKeyOf(address) {
|
||||
const { program } = decodeAddress(address);
|
||||
return concat(Uint8Array.from([0x00, 0x14]), program); // OP_0 <20>
|
||||
}
|
||||
// electrum scripthash: sha256(script), byte-reversed, hex.
|
||||
const scripthash = (script) => toHex(sha256(script).slice().reverse());
|
||||
|
||||
// ---- keys -------------------------------------------------------------
|
||||
// ---- keys --------------------------------------------------------------
|
||||
// The HD node is the sole owner of the private key material; every derived
|
||||
// entry keeps a reference so PSBT.signInput(index, node) can sign each
|
||||
// input under its own key.
|
||||
class WalletKeys {
|
||||
constructor(root32, accountPath = DEFAULT_ACCOUNT_PATH) {
|
||||
this._accountPath = /^m(\/\d+'?)+$/.test(accountPath) ? accountPath : DEFAULT_ACCOUNT_PATH;
|
||||
this._account = HDKey.fromMasterSeed(root32).derive(this._accountPath);
|
||||
this._branch = [this._account.deriveChild(0), this._account.deriveChild(1)];
|
||||
constructor(root32, accountPath) {
|
||||
const purpose = parsePurposeFromPath(accountPath) || DEFAULT_PURPOSE;
|
||||
this._purpose = purpose;
|
||||
// bip32.fromSeed uses bitcoinjs-lib's Network object — pass DGB's so
|
||||
// extended keys serialize with the right BIP32 magic (0x0488B21E).
|
||||
this._root = bip32.fromSeed(Buffer.from(root32), digibyte);
|
||||
this._account = this._root.derivePath(`m/${purpose}'/${DGB_COIN_TYPE}'/0'`);
|
||||
this._accountPath = `m/${purpose}'/${DGB_COIN_TYPE}'/0'`;
|
||||
this._branch = [this._account.derive(0), this._account.derive(1)];
|
||||
this._cache = new Map();
|
||||
}
|
||||
get xpub() { return this._account.publicExtendedKey; }
|
||||
get xprv() { return this._account.privateExtendedKey; }
|
||||
get xpub() { return this._account.neutered().toBase58(); }
|
||||
get xprv() { return this._account.toBase58(); }
|
||||
get accountPath() { return this._accountPath; }
|
||||
entry(branch, index) {
|
||||
const k = branch + "/" + index;
|
||||
let e = this._cache.get(k);
|
||||
if (!e) {
|
||||
const node = this._branch[branch].deriveChild(index);
|
||||
const compressed = secp256k1.getPublicKey(node.privateKey, true);
|
||||
const h160 = hash160(compressed);
|
||||
const script = concat(Uint8Array.from([0x00, 0x14]), h160);
|
||||
const address = encodeSegwitV0(h160);
|
||||
const node = this._branch[branch].derive(index);
|
||||
const pubkey = Buffer.from(node.publicKey);
|
||||
const address = p2wpkhAddress(node, digibyte);
|
||||
const script = Buffer.from(scriptPubKeyBuf(pubkey));
|
||||
e = {
|
||||
branch, index, path: this._accountPath + "/" + branch + "/" + index,
|
||||
publicKey: compressed, h160, script, scriptHex: toHex(script),
|
||||
scripthash: scripthash(script),
|
||||
address, _node: node,
|
||||
publicKey: pubkey, script, scriptHex: script.toString("hex"),
|
||||
scripthash: scripthashOf(script),
|
||||
address,
|
||||
_node: node,
|
||||
};
|
||||
this._cache.set(k, e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
signDigest(entry, digest32) {
|
||||
// BIP143 sighash uses ECDSA over the preimage double-sha; signature is
|
||||
// low-S DER with sighash byte appended by the caller.
|
||||
const sig = secp256k1.sign(digest32, entry._node.privateKey, { prehash: false, lowS: true, format: "der" });
|
||||
return sig;
|
||||
signerFor(entry) {
|
||||
// bitcoinjs-lib's PSBT accepts anything with .publicKey + .sign(hash).
|
||||
// BIP32Interface fits, but ECPair.fromPrivateKey gives a plain signer
|
||||
// that matches what the DGB web-wallet uses — pick that for parity.
|
||||
return ECPair.fromPrivateKey(Buffer.from(entry._node.privateKey), { network: digibyte });
|
||||
}
|
||||
wipe() {
|
||||
for (const e of this._cache.values()) { try { e._node.wipePrivateData(); } catch {} }
|
||||
// BIP32Interface holds Buffers; drop references so GC picks them up.
|
||||
for (const e of this._cache.values()) e._node = null;
|
||||
this._cache.clear();
|
||||
for (const b of this._branch) try { b.wipePrivateData(); } catch {}
|
||||
try { this._account.wipePrivateData(); } catch {}
|
||||
this._branch = null;
|
||||
this._account = null;
|
||||
this._root = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- BIP143 P2WPKH sighash + tx serialize -----------------------------
|
||||
// Legacy scriptSigs are empty for pure-SegWit tx; witnesses carry the sig.
|
||||
const SIGHASH_ALL = 0x01;
|
||||
function scriptCodeFor(h160) {
|
||||
// 0x1976a914{h160}88ac wrapped as varlen bytes for the sighash preimage.
|
||||
return varbytes(concat(Uint8Array.from([0x76, 0xa9, 0x14]), h160, Uint8Array.from([0x88, 0xac])));
|
||||
}
|
||||
function sighashP2WPKH(txDraft, inputIndex) {
|
||||
const version = u32le(2);
|
||||
const locktime = u32le(0);
|
||||
const sequence = u32le(0xffffffff);
|
||||
const hashPrevouts = dsha(concat(...txDraft.inputs.map((i) => concat(fromHex(i.txid).reverse(), u32le(i.vout)))));
|
||||
const hashSequence = dsha(concat(...txDraft.inputs.map(() => sequence)));
|
||||
const hashOutputs = dsha(concat(...txDraft.outputs.map((o) => concat(u64le(o.value), varbytes(o.script)))));
|
||||
const inp = txDraft.inputs[inputIndex];
|
||||
const outpoint = concat(fromHex(inp.txid).reverse(), u32le(inp.vout));
|
||||
const preimage = concat(
|
||||
version, hashPrevouts, hashSequence, outpoint,
|
||||
scriptCodeFor(inp.entry.h160), u64le(inp.value), sequence,
|
||||
hashOutputs, locktime, u32le(SIGHASH_ALL),
|
||||
);
|
||||
return dsha(preimage);
|
||||
}
|
||||
function serializeWithWitnesses(txDraft, witnesses) {
|
||||
const version = u32le(2);
|
||||
const locktime = u32le(0);
|
||||
const sequence = u32le(0xffffffff);
|
||||
// marker/flag come between input-count and inputs.
|
||||
return concat(
|
||||
version,
|
||||
Uint8Array.from([0x00, 0x01]),
|
||||
varint(txDraft.inputs.length),
|
||||
...txDraft.inputs.map((i) => concat(fromHex(i.txid).reverse(), u32le(i.vout), varbytes(new Uint8Array(0)), sequence)),
|
||||
varint(txDraft.outputs.length),
|
||||
...txDraft.outputs.map((o) => concat(u64le(o.value), varbytes(o.script))),
|
||||
...witnesses.map((stack) => concat(varint(stack.length), ...stack.map(varbytes))),
|
||||
locktime,
|
||||
);
|
||||
}
|
||||
function txidOf(txDraft) {
|
||||
const version = u32le(2);
|
||||
const locktime = u32le(0);
|
||||
const sequence = u32le(0xffffffff);
|
||||
const noWitness = concat(
|
||||
version,
|
||||
varint(txDraft.inputs.length),
|
||||
...txDraft.inputs.map((i) => concat(fromHex(i.txid).reverse(), u32le(i.vout), varbytes(new Uint8Array(0)), sequence)),
|
||||
varint(txDraft.outputs.length),
|
||||
...txDraft.outputs.map((o) => concat(u64le(o.value), varbytes(o.script))),
|
||||
locktime,
|
||||
);
|
||||
return toHex(dsha(noWitness).slice().reverse());
|
||||
function parsePurposeFromPath(p) {
|
||||
const m = /^m\/(\d+)'\/\d+'\/\d+'$/.exec(String(p || ""));
|
||||
return m ? Number(m[1]) : null;
|
||||
}
|
||||
|
||||
// Rough vsize model for fee selection: base tx + 1 P2WPKH out per output +
|
||||
// per-input contribution (BIP141 discounts witness data by 4×).
|
||||
// ---- vsize model (fee estimation ahead of PSBT.getFee) -----------------
|
||||
const OVERHEAD_VB = 10.5;
|
||||
const P2WPKH_INPUT_VB = 68; // ~ (41 base + 108 witness/4)
|
||||
const P2WPKH_INPUT_VB = 68;
|
||||
const P2WPKH_OUTPUT_VB = 31;
|
||||
const feeVb = (nIn, nOut, feePerVb) => Math.ceil((OVERHEAD_VB + nIn * P2WPKH_INPUT_VB + nOut * P2WPKH_OUTPUT_VB) * feePerVb);
|
||||
|
||||
|
|
@ -188,7 +132,7 @@ module.exports = function makeDgbAdapter({
|
|||
class DgbWallet {
|
||||
constructor(root32, {
|
||||
walletId, storage, log = () => {}, onChange = () => {}, servers,
|
||||
accountPath = DEFAULT_ACCOUNT_PATH,
|
||||
accountPath,
|
||||
} = {}) {
|
||||
if (!walletId) throw new Error("chain-dgb: walletId required");
|
||||
this.walletId = walletId;
|
||||
|
|
@ -204,7 +148,7 @@ module.exports = function makeDgbAdapter({
|
|||
this._client.onServer = () => this._emit();
|
||||
this._state = {
|
||||
used: new Set(),
|
||||
watched: new Map(), // scripthash -> entry
|
||||
watched: new Map(),
|
||||
height: 0,
|
||||
balance: { confirmed: 0, unconfirmed: 0 },
|
||||
utxos: [],
|
||||
|
|
@ -215,8 +159,6 @@ module.exports = function makeDgbAdapter({
|
|||
};
|
||||
this._refreshTimer = null;
|
||||
this._subscribedHeaders = false;
|
||||
// DGB's electrum notifications behave the same as BCH's — hook the
|
||||
// client's onNotify to a debounced re-refresh.
|
||||
this._client.onNotify = (method, params) => {
|
||||
if (method === "blockchain.headers.subscribe") {
|
||||
const h = params && params[0] && params[0].height;
|
||||
|
|
@ -229,7 +171,7 @@ module.exports = function makeDgbAdapter({
|
|||
|
||||
_emit() { try { this.onChange(); } catch {} }
|
||||
|
||||
// ---- discovery + refresh (gap-limit) --------------------------------
|
||||
// ---- discovery (gap-limit) -----------------------------------------
|
||||
async _historyOf(entry) {
|
||||
const h = await this._client.call("blockchain.scripthash.get_history", [entry.scripthash]);
|
||||
return Array.isArray(h) ? h : [];
|
||||
|
|
@ -278,11 +220,9 @@ module.exports = function makeDgbAdapter({
|
|||
this._state.balance = { confirmed, unconfirmed };
|
||||
}
|
||||
async _loadHistory() {
|
||||
// Minimal shape — enough for the panel to show tx rows. Deep decoding
|
||||
// (per-input attribution, "sent to" heuristic) is skipped for the
|
||||
// first DGB rev; delta comes from listunspent-derived UTXOs plus the
|
||||
// scripthash history height. Real per-tx delta requires get_transaction
|
||||
// (verbose) which DGB electrum supports; wired here as best effort.
|
||||
// Best-effort tx-history summary: pull the transactions listed against
|
||||
// any used scripthash, sum ours-vs-not to get a delta per tx. Fine on
|
||||
// the DGB electrum pool (get_transaction verbose is supported).
|
||||
const entries = [...this._state.watched.values()].filter((e) => this._state.used.has(e.branch + "/" + e.index));
|
||||
const merged = new Map();
|
||||
const lists = await Promise.all(entries.map((e) => this._historyOf(e)));
|
||||
|
|
@ -320,7 +260,7 @@ module.exports = function makeDgbAdapter({
|
|||
status: (t.confirmations || 0) > 0 ? "confirmed" : "pending",
|
||||
kind: "transfer",
|
||||
});
|
||||
} catch (e) {
|
||||
} catch {
|
||||
out.push({ txid: h.txid, height: h.height, confirmations: 0, time: 0, delta: 0, fee: null, to: null, status: "pending", kind: "transfer" });
|
||||
}
|
||||
}
|
||||
|
|
@ -357,7 +297,6 @@ module.exports = function makeDgbAdapter({
|
|||
this._refreshTimer = setTimeout(() => this.refresh(false), ms);
|
||||
}
|
||||
|
||||
// ---- addresses -------------------------------------------------------
|
||||
current() { return this._keys.entry(0, this._state.receiveIndex); }
|
||||
nextAddress() {
|
||||
let r = this._state.receiveIndex + 1;
|
||||
|
|
@ -381,12 +320,19 @@ module.exports = function makeDgbAdapter({
|
|||
this._client.setServers(this._servers);
|
||||
}
|
||||
|
||||
// ---- plan + sign -----------------------------------------------------
|
||||
// ---- plan + sign (via @dgb-wallet/psbt) -----------------------------
|
||||
plan({ to, amount, feeRate = 20, sendMax = false }) {
|
||||
const rate = Math.min(500, Math.max(1, Number(feeRate) || 20)); // sat/vB
|
||||
const script = scriptPubKeyOf(String(to || ""));
|
||||
const targets = [{ value: sendMax ? 0 : Math.round(Number(amount) || 0), script, to: String(to) }];
|
||||
// Spend confirmed first; unconfirmed if needed.
|
||||
const rate = Math.min(500, Math.max(1, Number(feeRate) || 20));
|
||||
const dest = String(to || "");
|
||||
// The `payments` decoder will reject anything that isn't a valid
|
||||
// DGB address; catch and re-raise as a sane error.
|
||||
try { payments.address({ address: dest, network: digibyte }); }
|
||||
catch {
|
||||
// bitcoinjs-lib's address decoder is `address.toOutputScript`, not
|
||||
// payments.address; use it for validation.
|
||||
try { bitcoinjs.address.toOutputScript(dest, digibyte); }
|
||||
catch (e) { throw new Error(`bad DGB address: ${e?.message || dest}`); }
|
||||
}
|
||||
const spendable = this._state.utxos.slice().sort((a, b) => (b.height > 0) - (a.height > 0));
|
||||
const change = this._changeEntry();
|
||||
if (sendMax) {
|
||||
|
|
@ -394,29 +340,29 @@ module.exports = function makeDgbAdapter({
|
|||
const sum = chosen.reduce((a, u) => a + u.value, 0);
|
||||
const fee = feeVb(chosen.length, 1, rate);
|
||||
if (sum <= fee) throw new Error("balance does not cover the fee");
|
||||
targets[0].value = sum - fee;
|
||||
return {
|
||||
inputs: chosen, outputs: [{ value: sum - fee, script, to }],
|
||||
_chosen: chosen, _rate: rate, _to: dest, _sendMax: true, _change: change,
|
||||
recipients: [{ to: dest, value: sum - fee }],
|
||||
fee, feeRate: rate, change: 0,
|
||||
recipients: [{ to, value: sum - fee }], total: sum,
|
||||
total: sum,
|
||||
};
|
||||
}
|
||||
if (!(targets[0].value > 0)) throw new Error("amount must be > 0");
|
||||
const value = Math.round(Number(amount) || 0);
|
||||
if (!(value > 0)) throw new Error("amount must be > 0");
|
||||
let sum = 0; const chosen = [];
|
||||
for (const u of spendable) {
|
||||
chosen.push(u); sum += u.value;
|
||||
const withChange = feeVb(chosen.length, 2, rate);
|
||||
if (sum >= targets[0].value + withChange) {
|
||||
const changeVal = sum - targets[0].value - withChange;
|
||||
const outs = changeVal > 546
|
||||
? [targets[0], { value: changeVal, script: change.script, to: change.address }]
|
||||
: [targets[0]];
|
||||
const fee = changeVal > 546 ? withChange : sum - targets[0].value;
|
||||
if (sum >= value + withChange) {
|
||||
const changeVal = sum - value - withChange;
|
||||
const fee = changeVal > 546 ? withChange : sum - value;
|
||||
return {
|
||||
inputs: chosen, outputs: outs, fee, feeRate: rate,
|
||||
_chosen: chosen, _rate: rate, _to: dest, _value: value,
|
||||
_change: change, _changeVal: changeVal > 546 ? changeVal : 0,
|
||||
recipients: [{ to: dest, value }],
|
||||
fee, feeRate: rate,
|
||||
change: changeVal > 546 ? changeVal : 0,
|
||||
recipients: [{ to, value: targets[0].value }],
|
||||
total: targets[0].value + fee,
|
||||
total: value + fee,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -424,23 +370,34 @@ module.exports = function makeDgbAdapter({
|
|||
}
|
||||
|
||||
async signAndBroadcast(plan) {
|
||||
const witnesses = plan.inputs.map((_, i) => {
|
||||
const digest = sighashP2WPKH(plan, i);
|
||||
const sigDer = this._keys.signDigest(plan.inputs[i].entry, digest);
|
||||
const sigWithHash = concat(sigDer, Uint8Array.from([SIGHASH_ALL]));
|
||||
return [sigWithHash, plan.inputs[i].entry.publicKey];
|
||||
});
|
||||
const rawTx = serializeWithWitnesses(plan, witnesses);
|
||||
const rawHex = toHex(rawTx);
|
||||
const txid = await this._client.call("blockchain.transaction.broadcast", [rawHex]);
|
||||
if (typeof txid !== "string" || txid.length !== 64) throw new Error("broadcast rejected: " + JSON.stringify(txid));
|
||||
const psbtInputs = plan._chosen.map((u) => ({
|
||||
txid: u.txid,
|
||||
vout: u.vout,
|
||||
witness: { scriptHex: u.entry.scriptHex, value: u.value },
|
||||
}));
|
||||
const psbtOutputs = [{ address: plan._to, value: plan._sendMax ? plan.recipients[0].value : plan._value }];
|
||||
if (!plan._sendMax && plan._changeVal > 0) {
|
||||
psbtOutputs.push({ address: plan._change.address, value: plan._changeVal });
|
||||
}
|
||||
const psbt = buildPsbt({ inputs: psbtInputs, outputs: psbtOutputs }, digibyte);
|
||||
// Sign per-input with the exact key that funded that UTXO. signAllInputs
|
||||
// would work when all inputs share a key, but each derived address
|
||||
// has its own key, so we go per-input.
|
||||
for (let i = 0; i < plan._chosen.length; i++) {
|
||||
const signer = this._keys.signerFor(plan._chosen[i].entry);
|
||||
psbt.signInput(i, signer);
|
||||
}
|
||||
const { hex, txid } = finalizeAndExtract(psbt);
|
||||
const broadcast = await this._client.call("blockchain.transaction.broadcast", [hex]);
|
||||
if (typeof broadcast !== "string" || broadcast.length !== 64) {
|
||||
throw new Error("broadcast rejected: " + JSON.stringify(broadcast));
|
||||
}
|
||||
this.log("broadcast", txid);
|
||||
this._scheduleRefresh(1200);
|
||||
return { txid, hex: rawHex, fee: plan.fee };
|
||||
return { txid, hex, fee: plan.fee };
|
||||
}
|
||||
|
||||
// Minimal BIP-137-style signature over sha256d of the message with a
|
||||
// "DigiByte Signed Message:\n" magic — parallels the BCH build.
|
||||
// BIP-137-style: 65-byte recoverable signature over sha256d(magic || msg).
|
||||
signMessage(message) {
|
||||
const enc = new TextEncoder();
|
||||
const varstr = (s) => { const b = enc.encode(s); if (b.length >= 0xfd) throw new Error("too long"); return Uint8Array.from([b.length, ...b]); };
|
||||
|
|
@ -448,11 +405,15 @@ module.exports = function makeDgbAdapter({
|
|||
const payload = Uint8Array.from([...varstr(MAGIC), ...varstr(String(message))]);
|
||||
const digest = sha256(sha256(payload));
|
||||
const entry = this.current();
|
||||
const sig = secp256k1.sign(digest, entry._node.privateKey, { prehash: false, lowS: true, format: "recovered" });
|
||||
const out = new Uint8Array(65);
|
||||
out[0] = 27 + sig[0] + 4; // 4 = compressed
|
||||
out.set(sig.subarray(1), 1);
|
||||
return { address: entry.address, signature: Buffer.from(out).toString("base64") };
|
||||
const signer = this._keys.signerFor(entry);
|
||||
// ECPair's `signSchnorr` and `sign` don't emit recoverable sigs; fall
|
||||
// back to node's ecc.signRecoverable through @bitcoinerlab/secp256k1
|
||||
// (which the vendored @dgb-wallet/core already loaded).
|
||||
const sig = ecc.signRecoverable(Buffer.from(digest), signer.privateKey);
|
||||
const out = Buffer.alloc(65);
|
||||
out[0] = 27 + sig.recoveryId + 4; // +4 = compressed pubkey
|
||||
Buffer.from(sig.signature).copy(out, 1);
|
||||
return { address: entry.address, signature: out.toString("base64") };
|
||||
}
|
||||
|
||||
recovery() {
|
||||
|
|
@ -486,5 +447,5 @@ module.exports = function makeDgbAdapter({
|
|||
}
|
||||
}
|
||||
|
||||
return { DgbWallet, DEFAULT_ACCOUNT_PATH, HRP, EXPLORER_TX, EXPLORER_ADDR, encodeSegwitV0, decodeAddress };
|
||||
return { DgbWallet, EXPLORER_TX, EXPLORER_ADDR };
|
||||
};
|
||||
|
|
|
|||
10
bundled-addons/bchwallet/lib/dgb/core/address.d.ts
vendored
Normal file
10
bundled-addons/bchwallet/lib/dgb/core/address.d.ts
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import type { BIP32Interface } from 'bip32';
|
||||
import { type Network } from './network.js';
|
||||
export declare function p2pkhAddress(node: BIP32Interface, network?: Network): string;
|
||||
export declare function p2shP2wpkhAddress(node: BIP32Interface, network?: Network): string;
|
||||
export declare function p2shP2wpkhAddressesBoth(node: BIP32Interface): {
|
||||
modern: string;
|
||||
legacy: string;
|
||||
};
|
||||
export declare function p2wpkhAddress(node: BIP32Interface, network?: Network): string;
|
||||
export declare function p2trAddress(node: BIP32Interface, network?: Network): string;
|
||||
53
bundled-addons/bchwallet/lib/dgb/core/address.js
Normal file
53
bundled-addons/bchwallet/lib/dgb/core/address.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import { payments, initEccLib } from 'bitcoinjs-lib';
|
||||
import * as ecc from '@bitcoinerlab/secp256k1';
|
||||
import { digibyte, digibyteLegacyP2SH } from './network.js';
|
||||
// Required for Taproot address derivation (P2TR).
|
||||
initEccLib(ecc);
|
||||
export function p2pkhAddress(node, network = digibyte) {
|
||||
const { address } = payments.p2pkh({
|
||||
pubkey: Buffer.from(node.publicKey),
|
||||
network,
|
||||
});
|
||||
if (!address)
|
||||
throw new Error('p2pkh derivation returned no address');
|
||||
return address;
|
||||
}
|
||||
export function p2shP2wpkhAddress(node, network = digibyte) {
|
||||
const redeem = payments.p2wpkh({
|
||||
pubkey: Buffer.from(node.publicKey),
|
||||
network,
|
||||
});
|
||||
const { address } = payments.p2sh({ redeem, network });
|
||||
if (!address)
|
||||
throw new Error('p2sh-p2wpkh derivation returned no address');
|
||||
return address;
|
||||
}
|
||||
// Derive the "S..." (current DGB, scriptHash 0x3f) AND "3..." (legacy
|
||||
// Bitcoin-compatible, scriptHash 0x05) BIP49 addresses for the same
|
||||
// key. Ian Coleman's BIP39 tool and several older wallets generate the
|
||||
// legacy "3..." variant, so any seed-recovery scan must check both.
|
||||
export function p2shP2wpkhAddressesBoth(node) {
|
||||
return {
|
||||
modern: p2shP2wpkhAddress(node, digibyte),
|
||||
legacy: p2shP2wpkhAddress(node, digibyteLegacyP2SH),
|
||||
};
|
||||
}
|
||||
export function p2wpkhAddress(node, network = digibyte) {
|
||||
const { address } = payments.p2wpkh({
|
||||
pubkey: Buffer.from(node.publicKey),
|
||||
network,
|
||||
});
|
||||
if (!address)
|
||||
throw new Error('p2wpkh derivation returned no address');
|
||||
return address;
|
||||
}
|
||||
// BIP86 Taproot address using the x-only pubkey with no script tree,
|
||||
// which applies the standard BIP86 tweak internally in bitcoinjs-lib.
|
||||
export function p2trAddress(node, network = digibyte) {
|
||||
const internalPubkey = Buffer.from(node.publicKey.subarray(1, 33));
|
||||
const { address } = payments.p2tr({ internalPubkey, network });
|
||||
if (!address)
|
||||
throw new Error('p2tr derivation returned no address');
|
||||
return address;
|
||||
}
|
||||
//# sourceMappingURL=address.js.map
|
||||
5
bundled-addons/bchwallet/lib/dgb/core/descriptor.d.ts
vendored
Normal file
5
bundled-addons/bchwallet/lib/dgb/core/descriptor.d.ts
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import type { BIP32Interface } from 'bip32';
|
||||
import type { Purpose } from './hd.js';
|
||||
export declare function derivationPath(purpose: Purpose, account: number, change: 0 | 1, index: number): string;
|
||||
export declare function accountXpub(accountNode: BIP32Interface): string;
|
||||
export declare function accountXprv(accountNode: BIP32Interface): string;
|
||||
18
bundled-addons/bchwallet/lib/dgb/core/descriptor.js
Normal file
18
bundled-addons/bchwallet/lib/dgb/core/descriptor.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { DGB_COIN_TYPE } from './network.js';
|
||||
// Convenience helper: full derivation-path string for a specific
|
||||
// address, e.g. m/84'/20'/0'/0/5.
|
||||
export function derivationPath(purpose, account, change, index) {
|
||||
return `m/${purpose}'/${DGB_COIN_TYPE}'/${account}'/${change}/${index}`;
|
||||
}
|
||||
// xpub for an account, ready to be shared with a watch-only or
|
||||
// external indexer. Never share the corresponding xprv.
|
||||
export function accountXpub(accountNode) {
|
||||
return accountNode.neutered().toBase58();
|
||||
}
|
||||
export function accountXprv(accountNode) {
|
||||
if (!accountNode.privateKey) {
|
||||
throw new Error('Node has no private key; cannot export xprv');
|
||||
}
|
||||
return accountNode.toBase58();
|
||||
}
|
||||
//# sourceMappingURL=descriptor.js.map
|
||||
8
bundled-addons/bchwallet/lib/dgb/core/hd.d.ts
vendored
Normal file
8
bundled-addons/bchwallet/lib/dgb/core/hd.d.ts
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { type BIP32Interface } from 'bip32';
|
||||
import { type Network } from './network.js';
|
||||
export type Purpose = 44 | 49 | 84 | 86;
|
||||
export declare const PURPOSE_LABEL: Record<Purpose, string>;
|
||||
export declare function rootFromSeed(seed: Buffer, network?: Network): BIP32Interface;
|
||||
export declare function accountNode(root: BIP32Interface, purpose: Purpose, account?: number): BIP32Interface;
|
||||
export declare function addressNode(account: BIP32Interface, change: 0 | 1, index: number): BIP32Interface;
|
||||
export type { BIP32Interface };
|
||||
24
bundled-addons/bchwallet/lib/dgb/core/hd.js
Normal file
24
bundled-addons/bchwallet/lib/dgb/core/hd.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { BIP32Factory } from 'bip32';
|
||||
import * as ecc from '@bitcoinerlab/secp256k1';
|
||||
import { digibyte, DGB_COIN_TYPE } from './network.js';
|
||||
const bip32 = BIP32Factory(ecc);
|
||||
export const PURPOSE_LABEL = {
|
||||
44: 'BIP44 legacy P2PKH',
|
||||
49: 'BIP49 P2SH-wrapped SegWit',
|
||||
84: 'BIP84 native SegWit v0',
|
||||
86: 'BIP86 Taproot (SegWit v1)',
|
||||
};
|
||||
export function rootFromSeed(seed, network = digibyte) {
|
||||
return bip32.fromSeed(seed, network);
|
||||
}
|
||||
// Standard account-level derivation: m/purpose'/coin'/account'.
|
||||
// account defaults to 0 (the first account).
|
||||
export function accountNode(root, purpose, account = 0) {
|
||||
return root.derivePath(`m/${purpose}'/${DGB_COIN_TYPE}'/${account}'`);
|
||||
}
|
||||
// Address-level derivation from an account node.
|
||||
// change = 0 for external (receive) addresses, 1 for internal (change).
|
||||
export function addressNode(account, change, index) {
|
||||
return account.derive(change).derive(index);
|
||||
}
|
||||
//# sourceMappingURL=hd.js.map
|
||||
6
bundled-addons/bchwallet/lib/dgb/core/index.d.ts
vendored
Normal file
6
bundled-addons/bchwallet/lib/dgb/core/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export * from './network.js';
|
||||
export * from './seed.js';
|
||||
export * from './hd.js';
|
||||
export * from './address.js';
|
||||
export * from './wif.js';
|
||||
export * from './descriptor.js';
|
||||
7
bundled-addons/bchwallet/lib/dgb/core/index.js
Normal file
7
bundled-addons/bchwallet/lib/dgb/core/index.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export * from './network.js';
|
||||
export * from './seed.js';
|
||||
export * from './hd.js';
|
||||
export * from './address.js';
|
||||
export * from './wif.js';
|
||||
export * from './descriptor.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
13
bundled-addons/bchwallet/lib/dgb/core/network.d.ts
vendored
Normal file
13
bundled-addons/bchwallet/lib/dgb/core/network.d.ts
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import type { networks } from 'bitcoinjs-lib';
|
||||
export type Network = (typeof networks)['bitcoin'];
|
||||
export declare const digibyte: Network;
|
||||
export declare const digibyteLegacyP2SH: Network;
|
||||
export declare const digibyteLegacyWIF: Network;
|
||||
export declare const digibyteTestnet: Network;
|
||||
export declare const DGB_COIN_TYPE = 20;
|
||||
export declare const DGB_P2P: {
|
||||
readonly magic: 3669410810;
|
||||
readonly defaultPort: 12024;
|
||||
readonly rpcPort: 14022;
|
||||
readonly dnsSeeds: readonly ["seed.digibyte.io", "seed.diginode.tools", "seed.digibyte.link", "seed.aroundtheblock.app", "seed.tuyul.cc"];
|
||||
};
|
||||
74
bundled-addons/bchwallet/lib/dgb/core/network.js
Normal file
74
bundled-addons/bchwallet/lib/dgb/core/network.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// DigiByte mainnet parameters. Sourced from
|
||||
// github.com/DigiByte-Core/digibyte src/kernel/chainparams.cpp CMainParams.
|
||||
//
|
||||
// Note on scriptHash: DGB Core defines BOTH SCRIPT_ADDRESS = 0x3f ("S..."
|
||||
// addresses, the current default) and SCRIPT_ADDRESS2 = 0x05 ("3..."
|
||||
// addresses, kept for Bitcoin compatibility). Older BIP39 tools and
|
||||
// wallets that forked bitcoinjs-lib params generate 3-addresses; current
|
||||
// DGB Core generates S-addresses. `digibyte` below uses the current
|
||||
// default; use `digibyteLegacyP2SH` when recovering from Ian Coleman's
|
||||
// BIP39 tool, older Atomic/Exodus vintages, or anything else that
|
||||
// inherited Bitcoin's 0x05 P2SH byte. Both are valid on-chain.
|
||||
export const digibyte = {
|
||||
messagePrefix: '\x19DigiByte Signed Message:\n',
|
||||
bech32: 'dgb',
|
||||
bip32: {
|
||||
public: 0x0488b21e,
|
||||
private: 0x0488ade4,
|
||||
},
|
||||
pubKeyHash: 0x1e,
|
||||
scriptHash: 0x3f,
|
||||
wif: 0x80,
|
||||
};
|
||||
// Same as `digibyte`, but with the legacy Bitcoin-compatible P2SH
|
||||
// version byte. Use for producing/scanning "3..."-style P2SH addresses
|
||||
// during seed recovery from tools that predate the 0x3f switch.
|
||||
// DGB Core keeps SCRIPT_ADDRESS_OLD = 5 for backward compatibility.
|
||||
export const digibyteLegacyP2SH = {
|
||||
...digibyte,
|
||||
scriptHash: 0x05,
|
||||
};
|
||||
// Same as `digibyte`, but with the legacy WIF version byte.
|
||||
// DGB Core keeps SECRET_KEY_OLD = 158 (0x9e) for backward compatibility.
|
||||
// Older DGB tools may have exported private keys with this prefix.
|
||||
// The wallet's WIF-import path should try both `digibyte` and this
|
||||
// variant before rejecting a key.
|
||||
export const digibyteLegacyWIF = {
|
||||
...digibyte,
|
||||
wif: 0x9e,
|
||||
};
|
||||
// DigiByte testnet parameters. From CTestNetParams in chainparams.cpp.
|
||||
export const digibyteTestnet = {
|
||||
messagePrefix: '\x19DigiByte Signed Message:\n',
|
||||
bech32: 'dgbt',
|
||||
bip32: {
|
||||
public: 0x043587cf,
|
||||
private: 0x04358394,
|
||||
},
|
||||
pubKeyHash: 0x7e,
|
||||
scriptHash: 0x8c,
|
||||
wif: 0xef,
|
||||
};
|
||||
// SLIP-0044 registered coin type.
|
||||
export const DGB_COIN_TYPE = 20;
|
||||
// P2P network constants (unused by @dgb-wallet/core itself, exposed for
|
||||
// the P2P client package that will consume them).
|
||||
export const DGB_P2P = {
|
||||
// pchMessageStart in DGB Core chainparams.cpp is the byte sequence
|
||||
// 0xFA 0xC3 0xB6 0xDA on the wire. `writeUInt32LE(magic)` writes
|
||||
// least-significant-byte first, so the integer value stored here must
|
||||
// be the LE-reading: 0xDAB6C3FA (byte 0 = 0xFA, byte 3 = 0xDA).
|
||||
// Getting this wrong means peers see wrong-network frames and close
|
||||
// immediately at handshake.
|
||||
magic: 0xdab6c3fa,
|
||||
defaultPort: 12024,
|
||||
rpcPort: 14022,
|
||||
dnsSeeds: [
|
||||
'seed.digibyte.io',
|
||||
'seed.diginode.tools',
|
||||
'seed.digibyte.link',
|
||||
'seed.aroundtheblock.app',
|
||||
'seed.tuyul.cc',
|
||||
],
|
||||
};
|
||||
//# sourceMappingURL=network.js.map
|
||||
1
bundled-addons/bchwallet/lib/dgb/core/package.json
Normal file
1
bundled-addons/bchwallet/lib/dgb/core/package.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"type":"module","main":"./index.js"}
|
||||
4
bundled-addons/bchwallet/lib/dgb/core/seed.d.ts
vendored
Normal file
4
bundled-addons/bchwallet/lib/dgb/core/seed.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export type SeedStrength = 128 | 160 | 192 | 224 | 256;
|
||||
export declare function generateSeedPhrase(strength?: SeedStrength): string;
|
||||
export declare function validateSeedPhrase(phrase: string, wordlist?: string[]): boolean;
|
||||
export declare function seedFromPhrase(phrase: string, passphrase?: string): Promise<Buffer>;
|
||||
17
bundled-addons/bchwallet/lib/dgb/core/seed.js
Normal file
17
bundled-addons/bchwallet/lib/dgb/core/seed.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { generateMnemonic, validateMnemonic, mnemonicToSeed, wordlists, } from 'bip39';
|
||||
// Word count → entropy strength for BIP39.
|
||||
// 12 → 128, 15 → 160, 18 → 192, 21 → 224, 24 → 256.
|
||||
export function generateSeedPhrase(strength = 128) {
|
||||
return generateMnemonic(strength);
|
||||
}
|
||||
// BIP39 checksum + wordlist validation. Returns false for typos, bad
|
||||
// word counts, and out-of-wordlist words.
|
||||
export function validateSeedPhrase(phrase, wordlist = wordlists.english) {
|
||||
return validateMnemonic(phrase.trim(), wordlist);
|
||||
}
|
||||
// BIP39 seed derivation. Passphrase is the optional "25th word";
|
||||
// changing it produces a different wallet from the same mnemonic.
|
||||
export async function seedFromPhrase(phrase, passphrase = '') {
|
||||
return mnemonicToSeed(phrase.trim(), passphrase);
|
||||
}
|
||||
//# sourceMappingURL=seed.js.map
|
||||
27
bundled-addons/bchwallet/lib/dgb/core/wif.d.ts
vendored
Normal file
27
bundled-addons/bchwallet/lib/dgb/core/wif.d.ts
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { type ECPairInterface } from 'ecpair';
|
||||
import { type Network } from './network.js';
|
||||
export type WifImportResult = {
|
||||
keyPair: ECPairInterface;
|
||||
variant: 'modern' | 'legacy';
|
||||
};
|
||||
export declare function importWif(wif: string): WifImportResult;
|
||||
export declare function importWifStrict(wif: string, network?: Network): ECPairInterface;
|
||||
export declare function exportWif(keyPair: ECPairInterface): string;
|
||||
export interface PubkeyAddresses {
|
||||
p2pkh: string;
|
||||
p2shP2wpkhModern: string;
|
||||
p2shP2wpkhLegacy: string;
|
||||
p2wpkh: string;
|
||||
p2tr: string;
|
||||
scripts: {
|
||||
p2pkh: string;
|
||||
p2shP2wpkh: string;
|
||||
p2wpkh: string;
|
||||
p2tr: string;
|
||||
};
|
||||
}
|
||||
export declare function addressesForPubkey(pubkey: Buffer, network?: Network): PubkeyAddresses;
|
||||
export interface WifImportWithAddresses extends WifImportResult, PubkeyAddresses {
|
||||
}
|
||||
export declare function importWifWithAddresses(wif: string): WifImportWithAddresses;
|
||||
export type { ECPairInterface };
|
||||
72
bundled-addons/bchwallet/lib/dgb/core/wif.js
Normal file
72
bundled-addons/bchwallet/lib/dgb/core/wif.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { ECPairFactory } from 'ecpair';
|
||||
import * as ecc from '@bitcoinerlab/secp256k1';
|
||||
import { payments, initEccLib } from 'bitcoinjs-lib';
|
||||
import { digibyte, digibyteLegacyP2SH, digibyteLegacyWIF } from './network.js';
|
||||
const ECPair = ECPairFactory(ecc);
|
||||
initEccLib(ecc);
|
||||
// Import a DigiByte private key in WIF (Wallet Import Format).
|
||||
// Tries the modern 0x80 prefix first, falls back to the legacy 0x9e
|
||||
// prefix that older DGB tools produced. Rejects anything else with a
|
||||
// clear message that identifies the network mismatch.
|
||||
export function importWif(wif) {
|
||||
const trimmed = wif.trim();
|
||||
try {
|
||||
return { keyPair: ECPair.fromWIF(trimmed, digibyte), variant: 'modern' };
|
||||
}
|
||||
catch {
|
||||
// fall through to legacy attempt
|
||||
}
|
||||
try {
|
||||
return { keyPair: ECPair.fromWIF(trimmed, digibyteLegacyWIF), variant: 'legacy' };
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Not a valid DigiByte WIF (tried both current 0x80 and legacy 0x9e prefixes). ` +
|
||||
`Underlying error: ${e.message}. Check the key is for DGB mainnet, not testnet or another chain.`);
|
||||
}
|
||||
}
|
||||
// Import against a specific network only (advanced / testing).
|
||||
export function importWifStrict(wif, network = digibyte) {
|
||||
return ECPair.fromWIF(wif.trim(), network);
|
||||
}
|
||||
export function exportWif(keyPair) {
|
||||
return keyPair.toWIF();
|
||||
}
|
||||
export function addressesForPubkey(pubkey, network = digibyte) {
|
||||
const p2pkh = payments.p2pkh({ pubkey, network });
|
||||
const wpkhRedeem = payments.p2wpkh({ pubkey, network });
|
||||
// bitcoinjs-lib enforces `redeem.network === outerNetwork` (identity
|
||||
// comparison, not shape). To render the legacy 3-prefix P2SH address
|
||||
// we need a fresh redeem whose .network property is the legacy variant
|
||||
// — same bytes on the wire, different object identity.
|
||||
const wpkhRedeemLegacy = payments.p2wpkh({ pubkey, network: digibyteLegacyP2SH });
|
||||
const p2shModern = payments.p2sh({ redeem: wpkhRedeem, network });
|
||||
const p2shLegacy = payments.p2sh({ redeem: wpkhRedeemLegacy, network: digibyteLegacyP2SH });
|
||||
const p2wpkh = payments.p2wpkh({ pubkey, network });
|
||||
const p2tr = payments.p2tr({ internalPubkey: pubkey.subarray(1, 33), network });
|
||||
if (!p2pkh.address || !p2shModern.address || !p2shLegacy.address || !p2wpkh.address || !p2tr.address) {
|
||||
throw new Error('bitcoinjs-lib returned an empty address for one of the payment types');
|
||||
}
|
||||
if (!p2pkh.output || !p2shModern.output || !p2wpkh.output || !p2tr.output) {
|
||||
throw new Error('bitcoinjs-lib returned an empty scriptPubKey for one of the payment types');
|
||||
}
|
||||
return {
|
||||
p2pkh: p2pkh.address,
|
||||
p2shP2wpkhModern: p2shModern.address,
|
||||
p2shP2wpkhLegacy: p2shLegacy.address,
|
||||
p2wpkh: p2wpkh.address,
|
||||
p2tr: p2tr.address,
|
||||
scripts: {
|
||||
p2pkh: Buffer.from(p2pkh.output).toString('hex'),
|
||||
p2shP2wpkh: Buffer.from(p2shModern.output).toString('hex'),
|
||||
p2wpkh: Buffer.from(p2wpkh.output).toString('hex'),
|
||||
p2tr: Buffer.from(p2tr.output).toString('hex'),
|
||||
},
|
||||
};
|
||||
}
|
||||
export function importWifWithAddresses(wif) {
|
||||
const imported = importWif(wif);
|
||||
const pubkey = Buffer.from(imported.keyPair.publicKey);
|
||||
const addrs = addressesForPubkey(pubkey);
|
||||
return { ...imported, ...addrs };
|
||||
}
|
||||
//# sourceMappingURL=wif.js.map
|
||||
4
bundled-addons/bchwallet/lib/dgb/psbt/build.d.ts
vendored
Normal file
4
bundled-addons/bchwallet/lib/dgb/psbt/build.d.ts
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
import { Psbt } from 'bitcoinjs-lib';
|
||||
import { type Network } from '@dgb-wallet/core';
|
||||
import type { BuildParams } from './types.js';
|
||||
export declare function buildPsbt(params: BuildParams, network?: Network): Psbt;
|
||||
56
bundled-addons/bchwallet/lib/dgb/psbt/build.js
Normal file
56
bundled-addons/bchwallet/lib/dgb/psbt/build.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
import { Psbt } from 'bitcoinjs-lib';
|
||||
import { digibyte } from '../core/index.js';
|
||||
// Construct an unsigned PSBT from a set of UTXOs and destination outputs.
|
||||
// Does not add a change output — the caller decides change amount and
|
||||
// address. Does not compute fees — the caller must have already subtracted
|
||||
// fee from outputs.
|
||||
export function buildPsbt(params, network = digibyte) {
|
||||
const psbt = new Psbt({ network });
|
||||
const inputs = params.sortBip69 === false ? params.inputs : sortInputs(params.inputs);
|
||||
const outputs = params.sortBip69 === false ? params.outputs : sortOutputs(params.outputs);
|
||||
for (const u of inputs) {
|
||||
psbt.addInput(inputToPsbtInput(u));
|
||||
}
|
||||
for (const o of outputs) {
|
||||
psbt.addOutput({ address: o.address, value: o.value });
|
||||
}
|
||||
return psbt;
|
||||
}
|
||||
function inputToPsbtInput(u) {
|
||||
const input = {
|
||||
hash: u.txid,
|
||||
index: u.vout,
|
||||
};
|
||||
if (u.witness) {
|
||||
input.witnessUtxo = {
|
||||
script: Buffer.from(u.witness.scriptHex, 'hex'),
|
||||
value: u.witness.value,
|
||||
};
|
||||
}
|
||||
if (u.nonWitnessTxHex) {
|
||||
input.nonWitnessUtxo = Buffer.from(u.nonWitnessTxHex, 'hex');
|
||||
}
|
||||
if (u.redeemScriptHex) {
|
||||
input.redeemScript = Buffer.from(u.redeemScriptHex, 'hex');
|
||||
}
|
||||
if (u.tapInternalKeyHex) {
|
||||
input.tapInternalKey = Buffer.from(u.tapInternalKeyHex, 'hex');
|
||||
}
|
||||
return input;
|
||||
}
|
||||
// BIP69 lexicographic ordering. Improves privacy by not revealing input
|
||||
// selection order (which can hint at wallet coin-selection strategy).
|
||||
function sortInputs(inputs) {
|
||||
return [...inputs].sort((a, b) => {
|
||||
const cmp = a.txid.localeCompare(b.txid);
|
||||
return cmp !== 0 ? cmp : a.vout - b.vout;
|
||||
});
|
||||
}
|
||||
function sortOutputs(outputs) {
|
||||
return [...outputs].sort((a, b) => {
|
||||
if (a.value !== b.value)
|
||||
return a.value - b.value;
|
||||
return a.address.localeCompare(b.address);
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=build.js.map
|
||||
3
bundled-addons/bchwallet/lib/dgb/psbt/index.d.ts
vendored
Normal file
3
bundled-addons/bchwallet/lib/dgb/psbt/index.d.ts
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export * from './types.js';
|
||||
export * from './build.js';
|
||||
export * from './sign.js';
|
||||
4
bundled-addons/bchwallet/lib/dgb/psbt/index.js
Normal file
4
bundled-addons/bchwallet/lib/dgb/psbt/index.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export * from './types.js';
|
||||
export * from './build.js';
|
||||
export * from './sign.js';
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
bundled-addons/bchwallet/lib/dgb/psbt/package.json
Normal file
1
bundled-addons/bchwallet/lib/dgb/psbt/package.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"type":"module","main":"./index.js"}
|
||||
9
bundled-addons/bchwallet/lib/dgb/psbt/sign.d.ts
vendored
Normal file
9
bundled-addons/bchwallet/lib/dgb/psbt/sign.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import type { Psbt } from 'bitcoinjs-lib';
|
||||
import type { ECPairInterface } from 'ecpair';
|
||||
export declare function signAllInputs(psbt: Psbt, keyPair: ECPairInterface): Psbt;
|
||||
export declare function finalizeAndExtract(psbt: Psbt): {
|
||||
hex: string;
|
||||
txid: string;
|
||||
};
|
||||
export declare function feeSats(psbt: Psbt): number;
|
||||
export declare function feeRateSatsPerByte(psbt: Psbt): number;
|
||||
25
bundled-addons/bchwallet/lib/dgb/psbt/sign.js
Normal file
25
bundled-addons/bchwallet/lib/dgb/psbt/sign.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Sign every input of a PSBT with the given key. Fails loudly if any
|
||||
// input can't be signed by this key (rather than silently leaving it
|
||||
// unsigned), so callers notice before broadcasting a half-signed tx.
|
||||
export function signAllInputs(psbt, keyPair) {
|
||||
psbt.signAllInputs(keyPair);
|
||||
return psbt;
|
||||
}
|
||||
// After all inputs are signed by all necessary parties, finalize and
|
||||
// extract the network-ready hex-encoded transaction.
|
||||
export function finalizeAndExtract(psbt) {
|
||||
psbt.finalizeAllInputs();
|
||||
const tx = psbt.extractTransaction();
|
||||
return { hex: tx.toHex(), txid: tx.getId() };
|
||||
}
|
||||
// Fee computed from the difference between total input value and total
|
||||
// output value. Requires all inputs to have witnessUtxo or
|
||||
// nonWitnessUtxo populated (which `buildPsbt` in this package
|
||||
// guarantees when the caller populates Utxo.value fields).
|
||||
export function feeSats(psbt) {
|
||||
return psbt.getFee();
|
||||
}
|
||||
export function feeRateSatsPerByte(psbt) {
|
||||
return psbt.getFeeRate();
|
||||
}
|
||||
//# sourceMappingURL=sign.js.map
|
||||
23
bundled-addons/bchwallet/lib/dgb/psbt/types.d.ts
vendored
Normal file
23
bundled-addons/bchwallet/lib/dgb/psbt/types.d.ts
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
export interface Utxo {
|
||||
txid: string;
|
||||
vout: number;
|
||||
value: number;
|
||||
address: string;
|
||||
scriptPubKey: string;
|
||||
witness?: {
|
||||
scriptHex: string;
|
||||
value: number;
|
||||
};
|
||||
nonWitnessTxHex?: string;
|
||||
redeemScriptHex?: string;
|
||||
tapInternalKeyHex?: string;
|
||||
}
|
||||
export interface Output {
|
||||
address: string;
|
||||
value: number;
|
||||
}
|
||||
export interface BuildParams {
|
||||
inputs: Utxo[];
|
||||
outputs: Output[];
|
||||
sortBip69?: boolean;
|
||||
}
|
||||
2
bundled-addons/bchwallet/lib/dgb/psbt/types.js
Normal file
2
bundled-addons/bchwallet/lib/dgb/psbt/types.js
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
export {};
|
||||
//# sourceMappingURL=types.js.map
|
||||
582
package-lock.json
generated
582
package-lock.json
generated
|
|
@ -1,16 +1,21 @@
|
|||
{
|
||||
"name": "theseus-navigator",
|
||||
"version": "0.3.6",
|
||||
"version": "0.3.16",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "theseus-navigator",
|
||||
"version": "0.3.6",
|
||||
"version": "0.3.16",
|
||||
"dependencies": {
|
||||
"@bitcoinerlab/secp256k1": "^1.2.0",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@noble/hashes": "^2.0.1",
|
||||
"@scure/bip32": "^2.0.1",
|
||||
"bip32": "^4.0.0",
|
||||
"bip39": "^3.1.0",
|
||||
"bitcoinjs-lib": "^6.1.7",
|
||||
"ecpair": "^2.1.0",
|
||||
"fetch-socks": "^1.3.3",
|
||||
"nostr-tools": "^2.10.4",
|
||||
"psl": "^1.15.0",
|
||||
|
|
@ -22,6 +27,42 @@
|
|||
"electron-builder": "^25.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@bitcoinerlab/secp256k1": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@bitcoinerlab/secp256k1/-/secp256k1-1.2.0.tgz",
|
||||
"integrity": "sha512-jeujZSzb3JOZfmJYI0ph1PVpCRV5oaexCgy+RvCXV8XlY+XFB/2n3WOcvBsKLsOw78KYgnQrQWb2HrKE4be88Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/curves": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bitcoinerlab/secp256k1/node_modules/@noble/curves": {
|
||||
"version": "1.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz",
|
||||
"integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "1.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@bitcoinerlab/secp256k1/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/@develar/schema-utils": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
|
||||
|
|
@ -1251,6 +1292,21 @@
|
|||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/available-typed-arrays": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
|
||||
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"possible-typed-array-names": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
|
|
@ -1261,6 +1317,12 @@
|
|||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/base-x": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz",
|
||||
"integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
|
|
@ -1282,6 +1344,107 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bech32": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
|
||||
"integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/bip174": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.1.tgz",
|
||||
"integrity": "sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bip32": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bip32/-/bip32-4.0.0.tgz",
|
||||
"integrity": "sha512-aOGy88DDlVUhspIXJN+dVEtclhIsfAUppD43V0j40cPTld3pv/0X/MlrZSZ6jowIaQQzFwP8M6rFU2z2mVYjDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"@scure/base": "^1.1.1",
|
||||
"typeforce": "^1.11.5",
|
||||
"wif": "^2.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bip32/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/bip32/node_modules/@scure/base": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz",
|
||||
"integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/bip39": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz",
|
||||
"integrity": "sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bip39/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/bitcoinjs-lib": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.1.7.tgz",
|
||||
"integrity": "sha512-tlf/r2DGMbF7ky1MgUqXHzypYHakkEnm0SZP23CJKIqNY/5uNAnMbFhMJdhjrL/7anfb/U8+AlpdjPWjPnAalg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"bech32": "^2.0.0",
|
||||
"bip174": "^2.1.1",
|
||||
"bs58check": "^3.0.1",
|
||||
"typeforce": "^1.11.3",
|
||||
"varuint-bitcoin": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bitcoinjs-lib/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
|
|
@ -1333,6 +1496,37 @@
|
|||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/bs58": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz",
|
||||
"integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base-x": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bs58check": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz",
|
||||
"integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.2.0",
|
||||
"bs58": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bs58check/node_modules/@noble/hashes": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz",
|
||||
"integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
|
|
@ -1572,11 +1766,28 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
|
||||
"integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"get-intrinsic": "^1.3.0",
|
||||
"set-function-length": "^1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
|
|
@ -1586,6 +1797,22 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bound": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
|
||||
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"get-intrinsic": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
|
|
@ -1636,6 +1863,20 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cipher-base": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz",
|
||||
"integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.4",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"to-buffer": "^1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
|
|
@ -1902,7 +2143,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/crc": {
|
||||
|
|
@ -1945,6 +2185,19 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/create-hash": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
|
||||
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cipher-base": "^1.0.1",
|
||||
"inherits": "^2.0.1",
|
||||
"md5.js": "^1.3.4",
|
||||
"ripemd160": "^2.0.1",
|
||||
"sha.js": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
|
|
@ -2033,9 +2286,7 @@
|
|||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
|
|
@ -2260,7 +2511,6 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
|
|
@ -2278,6 +2528,20 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ecpair": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ecpair/-/ecpair-2.1.0.tgz",
|
||||
"integrity": "sha512-cL/mh3MtJutFOvFc27GPZE2pWL3a3k4YvzUWEOvilnfZVlH3Jwgx/7d6tlD7/75tNk8TG2m+7Kgtz0SI1tWcqw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"randombytes": "^2.1.0",
|
||||
"typeforce": "^1.18.0",
|
||||
"wif": "^2.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
|
||||
|
|
@ -2535,7 +2799,6 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -2545,7 +2808,6 @@
|
|||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -2555,7 +2817,6 @@
|
|||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
|
||||
"integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
|
|
@ -2725,6 +2986,21 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
|
||||
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-callable": "^1.2.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
|
|
@ -2819,7 +3095,6 @@
|
|||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
|
|
@ -2860,7 +3135,6 @@
|
|||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
|
|
@ -2885,7 +3159,6 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
|
|
@ -3019,7 +3292,6 @@
|
|||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -3075,9 +3347,7 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
|
|
@ -3089,7 +3359,6 @@
|
|||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
@ -3102,7 +3371,6 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
|
|
@ -3121,11 +3389,61 @@
|
|||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/hash-base": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz",
|
||||
"integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^2.3.8",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"to-buffer": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/hash-base/node_modules/readable-stream": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
|
||||
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/hash-base/node_modules/string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hash-base/node_modules/string_decoder/node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
||||
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
|
|
@ -3321,7 +3639,6 @@
|
|||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ip-address": {
|
||||
|
|
@ -3333,6 +3650,18 @@
|
|||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/is-callable": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
|
||||
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-ci": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
|
||||
|
|
@ -3373,6 +3702,21 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-typed-array": {
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
|
||||
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"which-typed-array": "^1.1.16"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||
|
|
@ -3390,9 +3734,7 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/isbinaryfile": {
|
||||
"version": "5.0.7",
|
||||
|
|
@ -3783,12 +4125,22 @@
|
|||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/md5.js": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hash-base": "^3.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"safe-buffer": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||
|
|
@ -4387,13 +4739,20 @@
|
|||
"node": ">=10.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/possible-typed-array-names": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
|
||||
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
|
|
@ -4471,6 +4830,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/read-binary-file-arch": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz",
|
||||
|
|
@ -4632,6 +5000,19 @@
|
|||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/ripemd160": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz",
|
||||
"integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"hash-base": "^3.1.2",
|
||||
"inherits": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/roarr": {
|
||||
"version": "2.15.4",
|
||||
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
|
||||
|
|
@ -4655,7 +5036,6 @@
|
|||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
|
|
@ -4741,6 +5121,43 @@
|
|||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/sha.js": {
|
||||
"version": "2.4.12",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
|
||||
"integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
|
||||
"license": "(MIT AND BSD-3-Clause)",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.4",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"to-buffer": "^1.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"sha.js": "bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
|
|
@ -5113,6 +5530,26 @@
|
|||
"tmp": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/to-buffer": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
|
||||
"integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"isarray": "^2.0.5",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"typed-array-buffer": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/to-buffer/node_modules/isarray": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/truncate-utf8-bytes": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
|
||||
|
|
@ -5137,6 +5574,26 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-array-buffer": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
|
||||
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bound": "^1.0.3",
|
||||
"es-errors": "^1.3.0",
|
||||
"is-typed-array": "^1.1.14"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/typeforce": {
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
|
||||
"integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
|
|
@ -5224,9 +5681,17 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/varuint-bitcoin": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz",
|
||||
"integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/verror": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
|
||||
|
|
@ -5269,6 +5734,27 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.22",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz",
|
||||
"integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.9",
|
||||
"call-bound": "^1.0.4",
|
||||
"for-each": "^0.3.5",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||
|
|
@ -5279,6 +5765,44 @@
|
|||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"node_modules/wif": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
|
||||
"integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bs58check": "<3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wif/node_modules/base-x": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz",
|
||||
"integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/wif/node_modules/bs58": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
||||
"integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base-x": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/wif/node_modules/bs58check": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
|
||||
"integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bs58": "^4.0.0",
|
||||
"create-hash": "^1.1.0",
|
||||
"safe-buffer": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -11,9 +11,14 @@
|
|||
"dist": "electron-builder --win nsis portable"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bitcoinerlab/secp256k1": "^1.1.1",
|
||||
"@noble/curves": "^2.0.1",
|
||||
"@noble/hashes": "^2.0.1",
|
||||
"@scure/bip32": "^2.0.1",
|
||||
"bip32": "^4.0.0",
|
||||
"bip39": "^3.1.0",
|
||||
"bitcoinjs-lib": "^6.1.7",
|
||||
"ecpair": "^2.1.0",
|
||||
"fetch-socks": "^1.3.3",
|
||||
"nostr-tools": "^2.10.4",
|
||||
"psl": "^1.15.0",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue