@exodus/bip322-js 2.0.2 → 2.1.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.1.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/bip322-js@2.0.2...@exodus/bip322-js@2.1.0) (2025-04-01)
7
+
8
+ ### Features
9
+
10
+ - feat: support async signing with external signer (#11913)
11
+
6
12
  ## [2.0.2](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/bip322-js@2.0.1...@exodus/bip322-js@2.0.2) (2025-01-07)
7
13
 
8
14
  **Note:** Version bump only for package @exodus/bip322-js
package/dist/Signer.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import * as bitcoin from '@exodus/bitcoinjs';
2
+ import type { Signer as AssetSigner } from '@exodus/asset-types/src/signer';
2
3
  declare class Signer {
3
4
  static sign(privateKeyOrWIF: string | Buffer, address: string, message: string, network?: bitcoin.Network): any;
5
+ static signAsync(signer: string | Buffer | AssetSigner, address: string, message: string, network?: bitcoin.Network): Promise<any>;
4
6
  private static checkPubKeyCorrespondToAddress;
5
7
  }
6
8
  export default Signer;
package/dist/Signer.js CHANGED
@@ -2,6 +2,19 @@ import Address from './Address.js';
2
2
  import BIP322 from './BIP322.js';
3
3
  import * as bitcoin from '@exodus/bitcoinjs';
4
4
  import * as bitcoinMessage from '@exodus/bitcoinjs/message';
5
+ import assert from 'minimalistic-assert';
6
+ const createAsyncSigner = ({ signer, publicKey, tweak }) => {
7
+ return {
8
+ publicKey,
9
+ getPublicKey: () => publicKey,
10
+ sign: async (data) => signer.sign({ signatureType: 'ecdsa', data, enc: 'sig' }),
11
+ signSchnorr: async (hash) => signer.sign({
12
+ signatureType: 'schnorr',
13
+ data: hash,
14
+ tweak,
15
+ }),
16
+ };
17
+ };
5
18
  class Signer {
6
19
  static sign(privateKeyOrWIF, address, message, network = bitcoin.networks.bitcoin) {
7
20
  const ECPair = bitcoin.ECPair;
@@ -37,6 +50,51 @@ class Signer {
37
50
  .finalizeAllInputs();
38
51
  return BIP322.encodeWitness(toSignTxSigned);
39
52
  }
53
+ static async signAsync(signer, address, message, network = bitcoin.networks.bitcoin) {
54
+ if (typeof signer === 'string' || Buffer.isBuffer(signer)) {
55
+ return this.sign(signer, address, message, network);
56
+ }
57
+ const publicKey = await signer.getPublicKey();
58
+ assert(this.checkPubKeyCorrespondToAddress(publicKey, address), `Invalid signer for address "${address}".`);
59
+ if (Address.isP2PKH(address)) {
60
+ const asyncSigner = {
61
+ sign(hash, extraEntropy) {
62
+ return signer.sign({
63
+ signatureType: 'ecdsa',
64
+ data: hash,
65
+ extraEntropy,
66
+ enc: 'sig,rec',
67
+ });
68
+ },
69
+ };
70
+ return bitcoinMessage.signAsync(message, asyncSigner, true);
71
+ }
72
+ const scriptPubKey = Address.convertAdressToScriptPubkey(address);
73
+ const toSpendTx = BIP322.buildToSpendTx(message, scriptPubKey);
74
+ let toSignTx;
75
+ let tweak;
76
+ if (Address.isP2SH(address)) {
77
+ const redeemScript = bitcoin.payments.p2wpkh({
78
+ hash: bitcoin.crypto.hash160(publicKey),
79
+ network,
80
+ }).output;
81
+ toSignTx = BIP322.buildToSignTx(toSpendTx.getId(), redeemScript, true);
82
+ }
83
+ else if (Address.isP2WPKH(address)) {
84
+ toSignTx = BIP322.buildToSignTx(toSpendTx.getId(), scriptPubKey);
85
+ }
86
+ else {
87
+ const internalPublicKey = publicKey.subarray(1, 33);
88
+ tweak = bitcoin.crypto.taggedHash('TapTweak', publicKey.subarray(1, 33));
89
+ toSignTx = BIP322.buildToSignTx(toSpendTx.getId(), scriptPubKey, false, internalPublicKey);
90
+ }
91
+ const asyncSigner = createAsyncSigner({ signer, publicKey, tweak });
92
+ await toSignTx.signAllInputsAsync(asyncSigner, [
93
+ bitcoin.Transaction.SIGHASH_ALL,
94
+ bitcoin.Transaction.SIGHASH_DEFAULT,
95
+ ]);
96
+ return BIP322.encodeWitness(toSignTx.finalizeAllInputs());
97
+ }
40
98
  static checkPubKeyCorrespondToAddress(publicKey, claimedAddress) {
41
99
  let derivedAddresses;
42
100
  if (Address.isP2PKH(claimedAddress)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exodus/bip322-js",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "A Javascript library that provides utility functions related to the BIP-322 signature scheme",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,18 +37,21 @@
37
37
  "devDependencies": {
38
38
  "@exodus/bitcoinerlab-secp256k1": "^1.0.5-exodus.1",
39
39
  "@exodus/secp256k1": "^4.0.2-exodus.0",
40
+ "@types/minimalistic-assert": "^1.0.1",
40
41
  "@types/node": "^20.2.5",
41
42
  "bitcoinjs-message": "^2.2.0",
42
43
  "typedoc": "^0.24.8",
43
44
  "typescript": "^5.1.3"
44
45
  },
45
46
  "dependencies": {
47
+ "@exodus/asset-types": "^0.3.0",
46
48
  "@exodus/bitcoinjs": "^1.4.0",
47
- "@exodus/crypto": "^1.0.0-rc.14"
49
+ "@exodus/crypto": "^1.0.0-rc.14",
50
+ "minimalistic-assert": "^1.0.1"
48
51
  },
49
52
  "homepage": "https://github.com/ExodusMovement/exodus-hydra/tree/master/libraries/bip322-js",
50
53
  "bugs": {
51
54
  "url": "https://github.com/ExodusMovement/exodus-hydra/issues?q=is%3Aissue+is%3Aopen+label%3Abip322-js"
52
55
  },
53
- "gitHead": "9e9c803014c2e0072df754f6360fdde825af92c7"
56
+ "gitHead": "33473ee0dad8187b01d3f0bee0c04f30b60608d7"
54
57
  }