@anywalletkit/wallet-btc 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { B as BtcClient, U as Utxo, a as BlockbookTx, b as BtcConfig, c as BtcTxDescription, d as BtcAddressType, e as BtcNetwork, f as BtcSpend, g as BtcTransferOptions, h as BtcMaxSpendableResult, i as BtcReceipt, j as BtcTransaction } from './history-B5fmsCjZ.cjs';
2
2
  export { k as BlockbookAddressPage, l as BlockbookClient, m as BlockbookTxDetails, n as BlockbookVin, o as BlockbookVout, p as BtcChainTx, q as BtcClientConfig, r as BtcHistoryCursor, s as BtcHistoryOptions, t as BtcHistoryPage, u as BtcHistoryRaw, v as BtcHistorySource, w as BtcTxInputDescription, x as BtcTxOutputDescription, y as BtcWarning, C as CAIP2_GENESIS, H as HistoryUnavailableError, z as btcExplorerTxUrl, A as createBtcHistory, D as decodeHistoryCursor, E as encodeHistoryCursor, F as mapBlockbookTx, G as unconfirmedOutgoing } from './history-B5fmsCjZ.cjs';
3
- import { Signer, IWalletAccountReadOnly, IWalletAccount, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
3
+ import { Signer, IWalletAccountReadOnly, IWalletAccount, WriteOptions, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
4
4
  import { Transaction } from '@scure/btc-signer';
5
5
  import { BTC_NETWORK } from '@scure/btc-signer/utils.js';
6
6
 
@@ -359,14 +359,14 @@ declare class WalletAccountBtc extends WalletAccountReadOnlyBtc implements IWall
359
359
  private describeRaw;
360
360
  /** "What you sign": the fully resolved spend (signed, NOT broadcast) or a caller's raw hex. */
361
361
  describeTransaction(tx: BtcTransaction): Promise<BtcTxDescription>;
362
- /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input is returned unchanged. */
363
- signTransaction(tx: BtcTransaction): Promise<string>;
362
+ /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input gets the checks `sendTransaction` runs (prevouts through the client) and is returned unchanged, never re-signed. */
363
+ signTransaction(tx: BtcTransaction, options?: WriteOptions): Promise<string>;
364
364
  quoteSendTransaction(tx: BtcTransaction): Promise<{
365
365
  fee: bigint;
366
366
  }>;
367
- sendTransaction(tx: BtcTransaction): Promise<TransferResult>;
367
+ sendTransaction(tx: BtcTransaction, options?: WriteOptions): Promise<TransferResult>;
368
368
  /** Native BTC only (`token` is rejected). Subject to `transferMaxFee`. */
369
- transfer(o: BtcTransferOptions): Promise<TransferResult>;
369
+ transfer(o: BtcTransferOptions, writeOptions?: WriteOptions): Promise<TransferResult>;
370
370
  /** The same address as a {@link WalletAccountReadOnlyBtc}. */
371
371
  toReadOnlyAccount(): IWalletAccountReadOnly;
372
372
  dispose(): void;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { B as BtcClient, U as Utxo, a as BlockbookTx, b as BtcConfig, c as BtcTxDescription, d as BtcAddressType, e as BtcNetwork, f as BtcSpend, g as BtcTransferOptions, h as BtcMaxSpendableResult, i as BtcReceipt, j as BtcTransaction } from './history-B5fmsCjZ.js';
2
2
  export { k as BlockbookAddressPage, l as BlockbookClient, m as BlockbookTxDetails, n as BlockbookVin, o as BlockbookVout, p as BtcChainTx, q as BtcClientConfig, r as BtcHistoryCursor, s as BtcHistoryOptions, t as BtcHistoryPage, u as BtcHistoryRaw, v as BtcHistorySource, w as BtcTxInputDescription, x as BtcTxOutputDescription, y as BtcWarning, C as CAIP2_GENESIS, H as HistoryUnavailableError, z as btcExplorerTxUrl, A as createBtcHistory, D as decodeHistoryCursor, E as encodeHistoryCursor, F as mapBlockbookTx, G as unconfirmedOutgoing } from './history-B5fmsCjZ.js';
3
- import { Signer, IWalletAccountReadOnly, IWalletAccount, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
3
+ import { Signer, IWalletAccountReadOnly, IWalletAccount, WriteOptions, TransferResult, WalletManager, FeeRates } from '@anywalletkit/core';
4
4
  import { Transaction } from '@scure/btc-signer';
5
5
  import { BTC_NETWORK } from '@scure/btc-signer/utils.js';
6
6
 
@@ -359,14 +359,14 @@ declare class WalletAccountBtc extends WalletAccountReadOnlyBtc implements IWall
359
359
  private describeRaw;
360
360
  /** "What you sign": the fully resolved spend (signed, NOT broadcast) or a caller's raw hex. */
361
361
  describeTransaction(tx: BtcTransaction): Promise<BtcTxDescription>;
362
- /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input is returned unchanged. */
363
- signTransaction(tx: BtcTransaction): Promise<string>;
362
+ /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input gets the checks `sendTransaction` runs (prevouts through the client) and is returned unchanged, never re-signed. */
363
+ signTransaction(tx: BtcTransaction, options?: WriteOptions): Promise<string>;
364
364
  quoteSendTransaction(tx: BtcTransaction): Promise<{
365
365
  fee: bigint;
366
366
  }>;
367
- sendTransaction(tx: BtcTransaction): Promise<TransferResult>;
367
+ sendTransaction(tx: BtcTransaction, options?: WriteOptions): Promise<TransferResult>;
368
368
  /** Native BTC only (`token` is rejected). Subject to `transferMaxFee`. */
369
- transfer(o: BtcTransferOptions): Promise<TransferResult>;
369
+ transfer(o: BtcTransferOptions, writeOptions?: WriteOptions): Promise<TransferResult>;
370
370
  /** The same address as a {@link WalletAccountReadOnlyBtc}. */
371
371
  toReadOnlyAccount(): IWalletAccountReadOnly;
372
372
  dispose(): void;
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  isRecord,
13
13
  mapBlockbookTx,
14
14
  unconfirmedOutgoing
15
- } from "./chunk-KAAQYL5X.js";
15
+ } from "./chunk-4WUAN3DC.js";
16
16
 
17
17
  // src/errors.ts
18
18
  import { InsufficientFundsError, NetworkError, SignerError } from "@anywalletkit/core";
@@ -374,6 +374,7 @@ var DUST_LIMIT_P2TR = dustLimit("tr");
374
374
  var kindOfType = (type) => type === "p2tr" ? "tr" : "wpkh";
375
375
 
376
376
  // src/describe.ts
377
+ import { bigintToNumber } from "@anywalletkit/core";
377
378
  var DEFAULT_MAX_FEE_RATE = 500;
378
379
  var RBF_SEQUENCE = 4294967293;
379
380
  var FINAL_SEQUENCE = 4294967294;
@@ -408,7 +409,7 @@ function describeTransaction(tx, inputValues, ctx) {
408
409
  const fee = inputSum - outputSum;
409
410
  const amount = outputs.filter((o) => o.role !== "change").reduce((s, o) => s + o.value, 0n);
410
411
  const vsize = vsizeOf(tx);
411
- const feeRate = vsize > 0 ? Math.round(Number(fee) / vsize * 100) / 100 : 0;
412
+ const feeRate = vsize > 0 ? Math.round(bigintToNumber(fee) / vsize * 100) / 100 : 0;
412
413
  if (feeRate > (ctx.maxFeeRate ?? DEFAULT_MAX_FEE_RATE)) warnings.add("high-fee-rate");
413
414
  if (amount > 0n && fee * 10n > amount) warnings.add("fee-over-10pct-of-amount");
414
415
  if (!outputs.some((o) => o.role === "change")) warnings.add("no-change");
@@ -603,7 +604,7 @@ var WalletAccountReadOnlyBtc = class {
603
604
  };
604
605
 
605
606
  // src/account.ts
606
- import { InsufficientFundsError as InsufficientFundsError4, LocalSigner, SignerError as SignerError2, requireCurve } from "@anywalletkit/core";
607
+ import { InsufficientFundsError as InsufficientFundsError4, LocalSigner, SignerError as SignerError2, feeLimit, requireCurve } from "@anywalletkit/core";
607
608
  import { SigHash, Transaction as Transaction2, p2pkh } from "@scure/btc-signer";
608
609
  import { schnorr, secp256k1 as secp256k12 } from "@noble/curves/secp256k1.js";
609
610
  import { hex as hex2 } from "@scure/base";
@@ -798,19 +799,23 @@ var WalletAccountBtc = class _WalletAccountBtc extends WalletAccountReadOnlyBtc
798
799
  if (typeof tx === "string") return (await this.describeRaw(tx)).desc;
799
800
  return (await this.buildSignedTransaction(tx)).desc;
800
801
  }
801
- /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input is returned unchanged. */
802
- async signTransaction(tx) {
802
+ /** Sign without broadcasting. Returns the raw transaction hex. Raw hex input gets the checks `sendTransaction` runs (prevouts through the client) and is returned unchanged, never re-signed. */
803
+ async signTransaction(tx, options = {}) {
803
804
  this.live();
804
- if (typeof tx === "string") return tx;
805
+ if (typeof tx === "string") {
806
+ const { desc } = await this.describeRaw(tx);
807
+ this.checkMax(desc.fee, feeLimit(this._config.transactionMaxFee, options), "transaction");
808
+ return tx;
809
+ }
805
810
  const { tx: built, fee } = await this.buildSignedTransaction(tx);
806
- this.checkMax(fee, this._config.transactionMaxFee, "transaction");
811
+ this.checkMax(fee, feeLimit(this._config.transactionMaxFee, options), "transaction");
807
812
  return built.hex;
808
813
  }
809
814
  async quoteSendTransaction(tx) {
810
815
  if (typeof tx === "string") return { fee: (await this.describeRaw(tx)).desc.fee };
811
816
  return super.quoteSendTransaction(tx);
812
817
  }
813
- async sendTransaction(tx) {
818
+ async sendTransaction(tx, options = {}) {
814
819
  this.live();
815
820
  const client = this.requireClient("send transactions");
816
821
  let rawHex, hash, fee;
@@ -825,17 +830,17 @@ var WalletAccountBtc = class _WalletAccountBtc extends WalletAccountReadOnlyBtc
825
830
  hash = built.tx.id;
826
831
  fee = built.fee;
827
832
  }
828
- this.checkMax(fee, this._config.transactionMaxFee, "transaction");
833
+ this.checkMax(fee, feeLimit(this._config.transactionMaxFee, options), "transaction");
829
834
  const txid = await client.broadcast(rawHex);
830
835
  return { hash: txid || hash, fee };
831
836
  }
832
837
  /** Native BTC only (`token` is rejected). Subject to `transferMaxFee`. */
833
- async transfer(o) {
838
+ async transfer(o, writeOptions = {}) {
834
839
  if (o.token) throw new Error("Tokens are not supported on the bitcoin blockchain.");
835
840
  this.live();
836
841
  const client = this.requireClient("transfer");
837
842
  const built = await this.buildSignedTransaction({ to: o.recipient, value: o.amount });
838
- this.checkMax(built.fee, this._config.transferMaxFee, "transfer");
843
+ this.checkMax(built.fee, feeLimit(this._config.transferMaxFee, writeOptions), "transfer");
839
844
  const txid = await client.broadcast(built.tx.hex);
840
845
  return { hash: txid || built.tx.id, fee: built.fee };
841
846
  }
@@ -872,30 +877,26 @@ var WalletManagerBtc = class extends WalletManager {
872
877
  if (cached) return cached;
873
878
  const external = this.externalSigner();
874
879
  if (external) return this.fromSigner(external, full);
875
- const signer = LocalSigner2.leafFromSeed(this.seedBytes(), "secp256k1", full);
876
- const account = new WalletAccountBtc(signer, signer.publicKey, full, this._config);
877
- this._accounts.set(full, account);
878
- return account;
880
+ return this.cachedAccount(full, () => {
881
+ const signer = LocalSigner2.leafFromSeed(this.seedBytes(), "secp256k1", full);
882
+ return new WalletAccountBtc(signer, signer.publicKey, full, this._config);
883
+ });
879
884
  }
880
885
  /** Resolve `path` against an injected signer: the signer itself, or a child when it can derive there. */
881
886
  async fromSigner(signer, path) {
882
887
  this.requireSigner("secp256k1");
883
- let leaf = signer;
888
+ let rel;
884
889
  let key = "external";
885
890
  if (isSeedSigner(signer)) {
886
891
  if (path === signer.path) key = path;
887
892
  else if (path.startsWith(`${signer.path}/`)) {
888
- leaf = await (signer.deriveLeaf ?? signer.derive).call(signer, path.slice(signer.path.length + 1));
893
+ rel = path.slice(signer.path.length + 1);
889
894
  key = path;
890
895
  } else throw new SignerError3(`The injected signer sits at ${signer.path}; it cannot provide ${path}.`);
891
896
  } else if (path !== `${this.basePath}/0'/0/0` && path !== "external") {
892
897
  throw new SignerError3(`An external signer has one account; ${path} is not derivable from it.`);
893
898
  }
894
- const cached = this._accounts.get(key);
895
- if (cached) return cached;
896
- const account = new WalletAccountBtc(leaf, await leaf.getPublicKey(), key, this._config);
897
- this._accounts.set(key, account);
898
- return account;
899
+ return this.signerAccount(key, signer, rel, (leaf, publicKey) => new WalletAccountBtc(leaf, publicKey, key, this._config));
899
900
  }
900
901
  /** A read-only account for any address, with this manager's config. */
901
902
  getReadOnlyAccount(address) {