@sovereign-sdk/multisig 0.1.2 → 0.3.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/dist/index.d.mts CHANGED
@@ -104,6 +104,28 @@ declare class MultisigTransaction {
104
104
  * @returns A readonly view of the unsigned transaction
105
105
  */
106
106
  get unsignedTransaction(): Readonly<UnsignedTransaction<unknown>>;
107
+ /**
108
+ * Gets the signatures and public keys collected so far.
109
+ * @returns A readonly view of the signatures and public keys
110
+ */
111
+ get signaturesAndPubKeys(): Readonly<SignatureAndPubKey[]>;
112
+ /**
113
+ * Gets the remaining public keys that haven't signed yet.
114
+ * @returns A readonly view of the remaining public keys
115
+ */
116
+ get remainingPubKeys(): Readonly<Set<HexString>>;
117
+ /**
118
+ * Gets the threshold number of signatures required for the multisig to be complete.
119
+ * @returns The threshold number of signatures
120
+ */
121
+ get threshold(): number;
122
+ /**
123
+ * Calculates the multisig address (credential ID) by hashing the threshold and sorted public keys.
124
+ * This matches the Rust implementation: hash(threshold || borsh(sorted_pubkeys))
125
+ * @param hasher - The hash algorithm to use (currently only 'sha256' is supported)
126
+ * @returns The 32-byte multisig address as a Uint8Array
127
+ */
128
+ getMultisigAddress(hasher?: "sha256"): Uint8Array;
107
129
  /**
108
130
  * Converts the multisig to a V1 transaction that can be submitted to the network.
109
131
  * @returns A V1 transaction containing all collected signatures and unused public keys
package/dist/index.d.ts CHANGED
@@ -104,6 +104,28 @@ declare class MultisigTransaction {
104
104
  * @returns A readonly view of the unsigned transaction
105
105
  */
106
106
  get unsignedTransaction(): Readonly<UnsignedTransaction<unknown>>;
107
+ /**
108
+ * Gets the signatures and public keys collected so far.
109
+ * @returns A readonly view of the signatures and public keys
110
+ */
111
+ get signaturesAndPubKeys(): Readonly<SignatureAndPubKey[]>;
112
+ /**
113
+ * Gets the remaining public keys that haven't signed yet.
114
+ * @returns A readonly view of the remaining public keys
115
+ */
116
+ get remainingPubKeys(): Readonly<Set<HexString>>;
117
+ /**
118
+ * Gets the threshold number of signatures required for the multisig to be complete.
119
+ * @returns The threshold number of signatures
120
+ */
121
+ get threshold(): number;
122
+ /**
123
+ * Calculates the multisig address (credential ID) by hashing the threshold and sorted public keys.
124
+ * This matches the Rust implementation: hash(threshold || borsh(sorted_pubkeys))
125
+ * @param hasher - The hash algorithm to use (currently only 'sha256' is supported)
126
+ * @returns The 32-byte multisig address as a Uint8Array
127
+ */
128
+ getMultisigAddress(hasher?: "sha256"): Uint8Array;
107
129
  /**
108
130
  * Converts the multisig to a V1 transaction that can be submitted to the network.
109
131
  * @returns A V1 transaction containing all collected signatures and unused public keys
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -27,6 +37,9 @@ __export(src_exports, {
27
37
  TransactionMismatchError: () => TransactionMismatchError
28
38
  });
29
39
  module.exports = __toCommonJS(src_exports);
40
+ var import_sha2 = require("@noble/hashes/sha2");
41
+ var import_utils = require("@sovereign-sdk/utils");
42
+ var borsh = __toESM(require("borsh"));
30
43
  var MultisigError = class extends Error {
31
44
  };
32
45
  var InvalidTransactionVersionError = class extends MultisigError {
@@ -153,6 +166,50 @@ var MultisigTransaction = class _MultisigTransaction {
153
166
  get unsignedTransaction() {
154
167
  return this.unsignedTx;
155
168
  }
169
+ /**
170
+ * Gets the signatures and public keys collected so far.
171
+ * @returns A readonly view of the signatures and public keys
172
+ */
173
+ get signaturesAndPubKeys() {
174
+ return this.signatures;
175
+ }
176
+ /**
177
+ * Gets the remaining public keys that haven't signed yet.
178
+ * @returns A readonly view of the remaining public keys
179
+ */
180
+ get remainingPubKeys() {
181
+ return this.unusedPubKeys;
182
+ }
183
+ /**
184
+ * Gets the threshold number of signatures required for the multisig to be complete.
185
+ * @returns The threshold number of signatures
186
+ */
187
+ get threshold() {
188
+ return this.minSigners;
189
+ }
190
+ /**
191
+ * Calculates the multisig address (credential ID) by hashing the threshold and sorted public keys.
192
+ * This matches the Rust implementation: hash(threshold || borsh(sorted_pubkeys))
193
+ * @param hasher - The hash algorithm to use (currently only 'sha256' is supported)
194
+ * @returns The 32-byte multisig address as a Uint8Array
195
+ */
196
+ getMultisigAddress(hasher = "sha256") {
197
+ if (hasher !== "sha256") {
198
+ throw new Error(`Unsupported hasher: ${hasher}`);
199
+ }
200
+ const allPubKeys = [
201
+ ...this.signatures.map((s) => s.pub_key),
202
+ ...Array.from(this.unusedPubKeys)
203
+ ];
204
+ const sortedPubKeys = allPubKeys.sort();
205
+ const pubKeyBytes = sortedPubKeys.map((pk) => Array.from((0, import_utils.hexToBytes)(pk)));
206
+ const buffer = new borsh.BinaryWriter();
207
+ buffer.writeU8(this.minSigners);
208
+ buffer.writeArray(pubKeyBytes, (pkBytes) => {
209
+ buffer.writeFixedArray(new Uint8Array(pkBytes));
210
+ });
211
+ return (0, import_sha2.sha256)(buffer.toArray());
212
+ }
156
213
  /**
157
214
  * Converts the multisig to a V1 transaction that can be submitted to the network.
158
215
  * @returns A V1 transaction containing all collected signatures and unused public keys
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n SignatureAndPubKey,\n Transaction,\n TransactionV0,\n UnsignedTransaction,\n} from \"@sovereign-sdk/types\";\nimport type { HexString } from \"@sovereign-sdk/utils\";\n\n/**\n * Base error class for multisig-related errors.\n */\nexport class MultisigError extends Error {}\n\n/**\n * Error thrown when a transaction has an unsupported version for multisig operations.\n */\nexport class InvalidTransactionVersionError extends MultisigError {}\n\n/**\n * Error thrown when a provided transaction doesn't match the expected unsigned transaction.\n */\nexport class TransactionMismatchError extends Error {\n constructor() {\n super(\n \"Provided transaction does not match the expected unsigned transaction\",\n );\n }\n}\n\n/**\n * Error thrown when multisig is constructed or used with invalid parameters.\n */\nexport class InvalidMultisigParameterError extends MultisigError {\n constructor(desc: string) {\n super(`Multisig was constructed with invalid parameter: ${desc}`);\n }\n}\n\n/**\n * Parameters for constructing a MultisigTransaction.\n */\nexport type MultisigParams = {\n /** The unsigned transaction to be signed by multiple parties */\n unsignedTx: UnsignedTransaction<unknown>;\n /** Array of signatures with pubkeys already collected */\n signatures: SignatureAndPubKey[];\n /** Array of public keys that haven't signed yet */\n unusedPubKeys: HexString[];\n /** Minimum number of signatures required */\n minSigners: number;\n};\n\n/**\n * Parameters for creating a MultisigTransaction from existing signed transactions.\n */\nexport type FromTransactionsParams = {\n /** Array of signed transactions to extract signatures from */\n txns: Transaction<unknown>[];\n /** Minimum number of signatures required */\n minSigners: number;\n /** All public keys that are members of the multisig */\n allPubKeys: HexString[];\n};\n\n/**\n * Represents a multisig transaction that collects signatures from multiple parties.\n * Only supports nonce-based transactions and V0 transaction variants for signature collection.\n */\nexport class MultisigTransaction {\n private unsignedTx: UnsignedTransaction<unknown>;\n private signatures: SignatureAndPubKey[] = [];\n private minSigners: number;\n private unusedPubKeys = new Set<HexString>();\n\n /**\n * Creates a new MultisigTransaction instance.\n * @param params - The multisig parameters including unsigned transaction, signatures, and public keys\n */\n constructor({\n unsignedTx,\n signatures,\n unusedPubKeys,\n minSigners,\n }: MultisigParams) {\n this.unsignedTx = unsignedTx;\n this.signatures = signatures;\n this.unusedPubKeys = new Set(unusedPubKeys);\n this.minSigners = minSigners;\n }\n\n /**\n * Creates an empty MultisigTransaction with no signatures collected yet.\n * @param unsignedTx - The unsigned transaction to be signed by multiple parties\n * @param minSigners - Minimum number of signatures required for completion\n * @param allPubKeys - All public keys that are members of the multisig\n * @returns A new empty MultisigTransaction instance\n */\n static empty(\n unsignedTx: UnsignedTransaction<unknown>,\n minSigners: number,\n allPubKeys: HexString[],\n ): MultisigTransaction {\n return new MultisigTransaction({\n unsignedTx,\n signatures: [],\n unusedPubKeys: allPubKeys,\n minSigners,\n });\n }\n\n /**\n * Creates a MultisigTransaction from an array of already-signed transactions.\n * Extracts signatures and validates that all transactions are identical except for signatures.\n * @param params - Parameters including the signed transactions, minimum signers, and all public keys\n * @returns A new MultisigTransaction instance\n * @throws {InvalidTransactionVersionError} If any transaction is not V0 variant\n * @throws {TransactionMismatchError} If transactions don't match each other\n * @throws {InvalidMultisigParameterError} If public keys are invalid or transaction is not nonce-based\n */\n static fromTransactions({\n txns,\n minSigners,\n allPubKeys,\n }: FromTransactionsParams): MultisigTransaction {\n const signatures: SignatureAndPubKey[] = [];\n const unsignedTx = asUnsignedTransaction(txns[0]);\n const unusedPubKeys = new Set<HexString>(allPubKeys);\n\n assertIsNonceBasedTx(unsignedTx);\n\n for (const tx of txns) {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n if (!unusedPubKeys.delete(pub_key)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pub_key}`,\n );\n }\n\n signatures.push({ pub_key, signature });\n }\n\n return new MultisigTransaction({\n unsignedTx,\n signatures,\n unusedPubKeys: Array.from(unusedPubKeys),\n minSigners,\n });\n }\n\n /**\n * Adds a signature & public key from a signed transaction to the multisig transaction.\n * @param tx - The signed transaction to extract signature from\n * @throws {InvalidTransactionVersionError} If the transaction is not V0 variant\n * @throws {TransactionMismatchError} If the transaction doesn't match the unsigned transaction\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignedTransaction(tx: Transaction<unknown>): void {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, this.unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n this.addSignature(signature, pub_key);\n }\n\n /**\n * Adds a signature to the multisig transaction.\n * @param signature - The signature to add\n * @param pubKey - The public key corresponding to the signature\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignature(signature: HexString, pubKey: HexString): void {\n if (!this.unusedPubKeys.delete(pubKey)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pubKey}`,\n );\n }\n\n this.signatures.push({ pub_key: pubKey, signature });\n }\n\n /**\n * Checks if the multisig has collected enough signatures to be complete.\n * @returns True if the number of signatures meets or exceeds the minimum required\n */\n get isComplete(): boolean {\n return this.signatures.length >= this.minSigners;\n }\n\n /**\n * Gets the unsigned transaction.\n * @returns A readonly view of the unsigned transaction\n */\n get unsignedTransaction(): Readonly<UnsignedTransaction<unknown>> {\n return this.unsignedTx;\n }\n\n /**\n * Converts the multisig to a V1 transaction that can be submitted to the network.\n * @returns A V1 transaction containing all collected signatures and unused public keys\n */\n asTransaction(): Transaction<unknown> {\n return {\n V1: {\n runtime_call: this.unsignedTx.runtime_call,\n uniqueness: this.unsignedTx.uniqueness,\n details: this.unsignedTx.details,\n unused_pub_keys: Array.from(this.unusedPubKeys),\n signatures: this.signatures,\n min_signers: this.minSigners,\n },\n };\n }\n}\n\nfunction assertTxVariant(\n tx: Transaction<unknown>,\n): asserts tx is TransactionV0<unknown> {\n if (\"V1\" in tx) {\n throw new InvalidTransactionVersionError(\n \"Input transaction was an unsupported variant (V1)\",\n );\n }\n}\n\nfunction asUnsignedTransaction(\n tx: Transaction<unknown>,\n): UnsignedTransaction<unknown> {\n if (\"V0\" in tx) {\n return {\n runtime_call: tx.V0.runtime_call,\n uniqueness: tx.V0.uniqueness,\n details: tx.V0.details,\n };\n }\n\n if (\"V1\" in tx) {\n return {\n runtime_call: tx.V1.runtime_call,\n uniqueness: tx.V1.uniqueness,\n details: tx.V1.details,\n };\n }\n\n throw new InvalidTransactionVersionError(\n \"Transaction variant is neither V0 nor V1\",\n );\n}\n\nfunction assertTxMatchesUnsignedTx(\n tx: Transaction<unknown>,\n unsignedTx: UnsignedTransaction<unknown>,\n): void {\n const txAsUnsigned = asUnsignedTransaction(tx);\n\n if (JSON.stringify(txAsUnsigned) !== JSON.stringify(unsignedTx)) {\n throw new TransactionMismatchError();\n }\n}\n\nfunction assertIsNonceBasedTx(unsignedTx: UnsignedTransaction<unknown>): void {\n if (!(\"nonce\" in unsignedTx.uniqueness)) {\n throw new InvalidMultisigParameterError(\n \"Only nonce-based transactions are supported for multisig\",\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2\";\nimport type {\n SignatureAndPubKey,\n Transaction,\n TransactionV0,\n UnsignedTransaction,\n} from \"@sovereign-sdk/types\";\nimport type { HexString } from \"@sovereign-sdk/utils\";\nimport { bytesToHex, hexToBytes } from \"@sovereign-sdk/utils\";\nimport * as borsh from \"borsh\";\n\n/**\n * Base error class for multisig-related errors.\n */\nexport class MultisigError extends Error {}\n\n/**\n * Error thrown when a transaction has an unsupported version for multisig operations.\n */\nexport class InvalidTransactionVersionError extends MultisigError {}\n\n/**\n * Error thrown when a provided transaction doesn't match the expected unsigned transaction.\n */\nexport class TransactionMismatchError extends Error {\n constructor() {\n super(\n \"Provided transaction does not match the expected unsigned transaction\",\n );\n }\n}\n\n/**\n * Error thrown when multisig is constructed or used with invalid parameters.\n */\nexport class InvalidMultisigParameterError extends MultisigError {\n constructor(desc: string) {\n super(`Multisig was constructed with invalid parameter: ${desc}`);\n }\n}\n\n/**\n * Parameters for constructing a MultisigTransaction.\n */\nexport type MultisigParams = {\n /** The unsigned transaction to be signed by multiple parties */\n unsignedTx: UnsignedTransaction<unknown>;\n /** Array of signatures with pubkeys already collected */\n signatures: SignatureAndPubKey[];\n /** Array of public keys that haven't signed yet */\n unusedPubKeys: HexString[];\n /** Minimum number of signatures required */\n minSigners: number;\n};\n\n/**\n * Parameters for creating a MultisigTransaction from existing signed transactions.\n */\nexport type FromTransactionsParams = {\n /** Array of signed transactions to extract signatures from */\n txns: Transaction<unknown>[];\n /** Minimum number of signatures required */\n minSigners: number;\n /** All public keys that are members of the multisig */\n allPubKeys: HexString[];\n};\n\n/**\n * Represents a multisig transaction that collects signatures from multiple parties.\n * Only supports nonce-based transactions and V0 transaction variants for signature collection.\n */\nexport class MultisigTransaction {\n private unsignedTx: UnsignedTransaction<unknown>;\n private signatures: SignatureAndPubKey[] = [];\n private minSigners: number;\n private unusedPubKeys = new Set<HexString>();\n\n /**\n * Creates a new MultisigTransaction instance.\n * @param params - The multisig parameters including unsigned transaction, signatures, and public keys\n */\n constructor({\n unsignedTx,\n signatures,\n unusedPubKeys,\n minSigners,\n }: MultisigParams) {\n this.unsignedTx = unsignedTx;\n this.signatures = signatures;\n this.unusedPubKeys = new Set(unusedPubKeys);\n this.minSigners = minSigners;\n }\n\n /**\n * Creates an empty MultisigTransaction with no signatures collected yet.\n * @param unsignedTx - The unsigned transaction to be signed by multiple parties\n * @param minSigners - Minimum number of signatures required for completion\n * @param allPubKeys - All public keys that are members of the multisig\n * @returns A new empty MultisigTransaction instance\n */\n static empty(\n unsignedTx: UnsignedTransaction<unknown>,\n minSigners: number,\n allPubKeys: HexString[],\n ): MultisigTransaction {\n return new MultisigTransaction({\n unsignedTx,\n signatures: [],\n unusedPubKeys: allPubKeys,\n minSigners,\n });\n }\n\n /**\n * Creates a MultisigTransaction from an array of already-signed transactions.\n * Extracts signatures and validates that all transactions are identical except for signatures.\n * @param params - Parameters including the signed transactions, minimum signers, and all public keys\n * @returns A new MultisigTransaction instance\n * @throws {InvalidTransactionVersionError} If any transaction is not V0 variant\n * @throws {TransactionMismatchError} If transactions don't match each other\n * @throws {InvalidMultisigParameterError} If public keys are invalid or transaction is not nonce-based\n */\n static fromTransactions({\n txns,\n minSigners,\n allPubKeys,\n }: FromTransactionsParams): MultisigTransaction {\n const signatures: SignatureAndPubKey[] = [];\n const unsignedTx = asUnsignedTransaction(txns[0]);\n const unusedPubKeys = new Set<HexString>(allPubKeys);\n\n assertIsNonceBasedTx(unsignedTx);\n\n for (const tx of txns) {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n if (!unusedPubKeys.delete(pub_key)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pub_key}`,\n );\n }\n\n signatures.push({ pub_key, signature });\n }\n\n return new MultisigTransaction({\n unsignedTx,\n signatures,\n unusedPubKeys: Array.from(unusedPubKeys),\n minSigners,\n });\n }\n\n /**\n * Adds a signature & public key from a signed transaction to the multisig transaction.\n * @param tx - The signed transaction to extract signature from\n * @throws {InvalidTransactionVersionError} If the transaction is not V0 variant\n * @throws {TransactionMismatchError} If the transaction doesn't match the unsigned transaction\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignedTransaction(tx: Transaction<unknown>): void {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, this.unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n this.addSignature(signature, pub_key);\n }\n\n /**\n * Adds a signature to the multisig transaction.\n * @param signature - The signature to add\n * @param pubKey - The public key corresponding to the signature\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignature(signature: HexString, pubKey: HexString): void {\n if (!this.unusedPubKeys.delete(pubKey)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pubKey}`,\n );\n }\n\n this.signatures.push({ pub_key: pubKey, signature });\n }\n\n /**\n * Checks if the multisig has collected enough signatures to be complete.\n * @returns True if the number of signatures meets or exceeds the minimum required\n */\n get isComplete(): boolean {\n return this.signatures.length >= this.minSigners;\n }\n\n /**\n * Gets the unsigned transaction.\n * @returns A readonly view of the unsigned transaction\n */\n get unsignedTransaction(): Readonly<UnsignedTransaction<unknown>> {\n return this.unsignedTx;\n }\n\n /**\n * Gets the signatures and public keys collected so far.\n * @returns A readonly view of the signatures and public keys\n */\n get signaturesAndPubKeys(): Readonly<SignatureAndPubKey[]> {\n return this.signatures;\n }\n\n /**\n * Gets the remaining public keys that haven't signed yet.\n * @returns A readonly view of the remaining public keys\n */\n get remainingPubKeys(): Readonly<Set<HexString>> {\n return this.unusedPubKeys;\n }\n\n /**\n * Gets the threshold number of signatures required for the multisig to be complete.\n * @returns The threshold number of signatures\n */\n get threshold(): number {\n return this.minSigners;\n }\n\n /**\n * Calculates the multisig address (credential ID) by hashing the threshold and sorted public keys.\n * This matches the Rust implementation: hash(threshold || borsh(sorted_pubkeys))\n * @param hasher - The hash algorithm to use (currently only 'sha256' is supported)\n * @returns The 32-byte multisig address as a Uint8Array\n */\n getMultisigAddress(hasher: \"sha256\" = \"sha256\"): Uint8Array {\n if (hasher !== \"sha256\") {\n throw new Error(`Unsupported hasher: ${hasher}`);\n }\n\n // Collect all public keys (signatures + unused)\n const allPubKeys = [\n ...this.signatures.map((s) => s.pub_key),\n ...Array.from(this.unusedPubKeys),\n ];\n const sortedPubKeys = allPubKeys.sort();\n const pubKeyBytes = sortedPubKeys.map((pk) => Array.from(hexToBytes(pk)));\n const buffer = new borsh.BinaryWriter();\n\n buffer.writeU8(this.minSigners);\n buffer.writeArray(pubKeyBytes, (pkBytes: number[]) => {\n buffer.writeFixedArray(new Uint8Array(pkBytes));\n });\n\n return sha256(buffer.toArray());\n }\n\n /**\n * Converts the multisig to a V1 transaction that can be submitted to the network.\n * @returns A V1 transaction containing all collected signatures and unused public keys\n */\n asTransaction(): Transaction<unknown> {\n return {\n V1: {\n runtime_call: this.unsignedTx.runtime_call,\n uniqueness: this.unsignedTx.uniqueness,\n details: this.unsignedTx.details,\n unused_pub_keys: Array.from(this.unusedPubKeys),\n signatures: this.signatures,\n min_signers: this.minSigners,\n },\n };\n }\n}\n\nfunction assertTxVariant(\n tx: Transaction<unknown>,\n): asserts tx is TransactionV0<unknown> {\n if (\"V1\" in tx) {\n throw new InvalidTransactionVersionError(\n \"Input transaction was an unsupported variant (V1)\",\n );\n }\n}\n\nfunction asUnsignedTransaction(\n tx: Transaction<unknown>,\n): UnsignedTransaction<unknown> {\n if (\"V0\" in tx) {\n return {\n runtime_call: tx.V0.runtime_call,\n uniqueness: tx.V0.uniqueness,\n details: tx.V0.details,\n };\n }\n\n if (\"V1\" in tx) {\n return {\n runtime_call: tx.V1.runtime_call,\n uniqueness: tx.V1.uniqueness,\n details: tx.V1.details,\n };\n }\n\n throw new InvalidTransactionVersionError(\n \"Transaction variant is neither V0 nor V1\",\n );\n}\n\nfunction assertTxMatchesUnsignedTx(\n tx: Transaction<unknown>,\n unsignedTx: UnsignedTransaction<unknown>,\n): void {\n const txAsUnsigned = asUnsignedTransaction(tx);\n\n if (JSON.stringify(txAsUnsigned) !== JSON.stringify(unsignedTx)) {\n throw new TransactionMismatchError();\n }\n}\n\nfunction assertIsNonceBasedTx(unsignedTx: UnsignedTransaction<unknown>): void {\n if (!(\"nonce\" in unsignedTx.uniqueness)) {\n throw new InvalidMultisigParameterError(\n \"Only nonce-based transactions are supported for multisig\",\n );\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -1,4 +1,7 @@
1
1
  // src/index.ts
2
+ import { sha256 } from "@noble/hashes/sha2";
3
+ import { hexToBytes } from "@sovereign-sdk/utils";
4
+ import * as borsh from "borsh";
2
5
  var MultisigError = class extends Error {
3
6
  };
4
7
  var InvalidTransactionVersionError = class extends MultisigError {
@@ -125,6 +128,50 @@ var MultisigTransaction = class _MultisigTransaction {
125
128
  get unsignedTransaction() {
126
129
  return this.unsignedTx;
127
130
  }
131
+ /**
132
+ * Gets the signatures and public keys collected so far.
133
+ * @returns A readonly view of the signatures and public keys
134
+ */
135
+ get signaturesAndPubKeys() {
136
+ return this.signatures;
137
+ }
138
+ /**
139
+ * Gets the remaining public keys that haven't signed yet.
140
+ * @returns A readonly view of the remaining public keys
141
+ */
142
+ get remainingPubKeys() {
143
+ return this.unusedPubKeys;
144
+ }
145
+ /**
146
+ * Gets the threshold number of signatures required for the multisig to be complete.
147
+ * @returns The threshold number of signatures
148
+ */
149
+ get threshold() {
150
+ return this.minSigners;
151
+ }
152
+ /**
153
+ * Calculates the multisig address (credential ID) by hashing the threshold and sorted public keys.
154
+ * This matches the Rust implementation: hash(threshold || borsh(sorted_pubkeys))
155
+ * @param hasher - The hash algorithm to use (currently only 'sha256' is supported)
156
+ * @returns The 32-byte multisig address as a Uint8Array
157
+ */
158
+ getMultisigAddress(hasher = "sha256") {
159
+ if (hasher !== "sha256") {
160
+ throw new Error(`Unsupported hasher: ${hasher}`);
161
+ }
162
+ const allPubKeys = [
163
+ ...this.signatures.map((s) => s.pub_key),
164
+ ...Array.from(this.unusedPubKeys)
165
+ ];
166
+ const sortedPubKeys = allPubKeys.sort();
167
+ const pubKeyBytes = sortedPubKeys.map((pk) => Array.from(hexToBytes(pk)));
168
+ const buffer = new borsh.BinaryWriter();
169
+ buffer.writeU8(this.minSigners);
170
+ buffer.writeArray(pubKeyBytes, (pkBytes) => {
171
+ buffer.writeFixedArray(new Uint8Array(pkBytes));
172
+ });
173
+ return sha256(buffer.toArray());
174
+ }
128
175
  /**
129
176
  * Converts the multisig to a V1 transaction that can be submitted to the network.
130
177
  * @returns A V1 transaction containing all collected signatures and unused public keys
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n SignatureAndPubKey,\n Transaction,\n TransactionV0,\n UnsignedTransaction,\n} from \"@sovereign-sdk/types\";\nimport type { HexString } from \"@sovereign-sdk/utils\";\n\n/**\n * Base error class for multisig-related errors.\n */\nexport class MultisigError extends Error {}\n\n/**\n * Error thrown when a transaction has an unsupported version for multisig operations.\n */\nexport class InvalidTransactionVersionError extends MultisigError {}\n\n/**\n * Error thrown when a provided transaction doesn't match the expected unsigned transaction.\n */\nexport class TransactionMismatchError extends Error {\n constructor() {\n super(\n \"Provided transaction does not match the expected unsigned transaction\",\n );\n }\n}\n\n/**\n * Error thrown when multisig is constructed or used with invalid parameters.\n */\nexport class InvalidMultisigParameterError extends MultisigError {\n constructor(desc: string) {\n super(`Multisig was constructed with invalid parameter: ${desc}`);\n }\n}\n\n/**\n * Parameters for constructing a MultisigTransaction.\n */\nexport type MultisigParams = {\n /** The unsigned transaction to be signed by multiple parties */\n unsignedTx: UnsignedTransaction<unknown>;\n /** Array of signatures with pubkeys already collected */\n signatures: SignatureAndPubKey[];\n /** Array of public keys that haven't signed yet */\n unusedPubKeys: HexString[];\n /** Minimum number of signatures required */\n minSigners: number;\n};\n\n/**\n * Parameters for creating a MultisigTransaction from existing signed transactions.\n */\nexport type FromTransactionsParams = {\n /** Array of signed transactions to extract signatures from */\n txns: Transaction<unknown>[];\n /** Minimum number of signatures required */\n minSigners: number;\n /** All public keys that are members of the multisig */\n allPubKeys: HexString[];\n};\n\n/**\n * Represents a multisig transaction that collects signatures from multiple parties.\n * Only supports nonce-based transactions and V0 transaction variants for signature collection.\n */\nexport class MultisigTransaction {\n private unsignedTx: UnsignedTransaction<unknown>;\n private signatures: SignatureAndPubKey[] = [];\n private minSigners: number;\n private unusedPubKeys = new Set<HexString>();\n\n /**\n * Creates a new MultisigTransaction instance.\n * @param params - The multisig parameters including unsigned transaction, signatures, and public keys\n */\n constructor({\n unsignedTx,\n signatures,\n unusedPubKeys,\n minSigners,\n }: MultisigParams) {\n this.unsignedTx = unsignedTx;\n this.signatures = signatures;\n this.unusedPubKeys = new Set(unusedPubKeys);\n this.minSigners = minSigners;\n }\n\n /**\n * Creates an empty MultisigTransaction with no signatures collected yet.\n * @param unsignedTx - The unsigned transaction to be signed by multiple parties\n * @param minSigners - Minimum number of signatures required for completion\n * @param allPubKeys - All public keys that are members of the multisig\n * @returns A new empty MultisigTransaction instance\n */\n static empty(\n unsignedTx: UnsignedTransaction<unknown>,\n minSigners: number,\n allPubKeys: HexString[],\n ): MultisigTransaction {\n return new MultisigTransaction({\n unsignedTx,\n signatures: [],\n unusedPubKeys: allPubKeys,\n minSigners,\n });\n }\n\n /**\n * Creates a MultisigTransaction from an array of already-signed transactions.\n * Extracts signatures and validates that all transactions are identical except for signatures.\n * @param params - Parameters including the signed transactions, minimum signers, and all public keys\n * @returns A new MultisigTransaction instance\n * @throws {InvalidTransactionVersionError} If any transaction is not V0 variant\n * @throws {TransactionMismatchError} If transactions don't match each other\n * @throws {InvalidMultisigParameterError} If public keys are invalid or transaction is not nonce-based\n */\n static fromTransactions({\n txns,\n minSigners,\n allPubKeys,\n }: FromTransactionsParams): MultisigTransaction {\n const signatures: SignatureAndPubKey[] = [];\n const unsignedTx = asUnsignedTransaction(txns[0]);\n const unusedPubKeys = new Set<HexString>(allPubKeys);\n\n assertIsNonceBasedTx(unsignedTx);\n\n for (const tx of txns) {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n if (!unusedPubKeys.delete(pub_key)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pub_key}`,\n );\n }\n\n signatures.push({ pub_key, signature });\n }\n\n return new MultisigTransaction({\n unsignedTx,\n signatures,\n unusedPubKeys: Array.from(unusedPubKeys),\n minSigners,\n });\n }\n\n /**\n * Adds a signature & public key from a signed transaction to the multisig transaction.\n * @param tx - The signed transaction to extract signature from\n * @throws {InvalidTransactionVersionError} If the transaction is not V0 variant\n * @throws {TransactionMismatchError} If the transaction doesn't match the unsigned transaction\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignedTransaction(tx: Transaction<unknown>): void {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, this.unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n this.addSignature(signature, pub_key);\n }\n\n /**\n * Adds a signature to the multisig transaction.\n * @param signature - The signature to add\n * @param pubKey - The public key corresponding to the signature\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignature(signature: HexString, pubKey: HexString): void {\n if (!this.unusedPubKeys.delete(pubKey)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pubKey}`,\n );\n }\n\n this.signatures.push({ pub_key: pubKey, signature });\n }\n\n /**\n * Checks if the multisig has collected enough signatures to be complete.\n * @returns True if the number of signatures meets or exceeds the minimum required\n */\n get isComplete(): boolean {\n return this.signatures.length >= this.minSigners;\n }\n\n /**\n * Gets the unsigned transaction.\n * @returns A readonly view of the unsigned transaction\n */\n get unsignedTransaction(): Readonly<UnsignedTransaction<unknown>> {\n return this.unsignedTx;\n }\n\n /**\n * Converts the multisig to a V1 transaction that can be submitted to the network.\n * @returns A V1 transaction containing all collected signatures and unused public keys\n */\n asTransaction(): Transaction<unknown> {\n return {\n V1: {\n runtime_call: this.unsignedTx.runtime_call,\n uniqueness: this.unsignedTx.uniqueness,\n details: this.unsignedTx.details,\n unused_pub_keys: Array.from(this.unusedPubKeys),\n signatures: this.signatures,\n min_signers: this.minSigners,\n },\n };\n }\n}\n\nfunction assertTxVariant(\n tx: Transaction<unknown>,\n): asserts tx is TransactionV0<unknown> {\n if (\"V1\" in tx) {\n throw new InvalidTransactionVersionError(\n \"Input transaction was an unsupported variant (V1)\",\n );\n }\n}\n\nfunction asUnsignedTransaction(\n tx: Transaction<unknown>,\n): UnsignedTransaction<unknown> {\n if (\"V0\" in tx) {\n return {\n runtime_call: tx.V0.runtime_call,\n uniqueness: tx.V0.uniqueness,\n details: tx.V0.details,\n };\n }\n\n if (\"V1\" in tx) {\n return {\n runtime_call: tx.V1.runtime_call,\n uniqueness: tx.V1.uniqueness,\n details: tx.V1.details,\n };\n }\n\n throw new InvalidTransactionVersionError(\n \"Transaction variant is neither V0 nor V1\",\n );\n}\n\nfunction assertTxMatchesUnsignedTx(\n tx: Transaction<unknown>,\n unsignedTx: UnsignedTransaction<unknown>,\n): void {\n const txAsUnsigned = asUnsignedTransaction(tx);\n\n if (JSON.stringify(txAsUnsigned) !== JSON.stringify(unsignedTx)) {\n throw new TransactionMismatchError();\n }\n}\n\nfunction assertIsNonceBasedTx(unsignedTx: UnsignedTransaction<unknown>): void {\n if (!(\"nonce\" in unsignedTx.uniqueness)) {\n throw new InvalidMultisigParameterError(\n \"Only nonce-based transactions are supported for multisig\",\n );\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { sha256 } from \"@noble/hashes/sha2\";\nimport type {\n SignatureAndPubKey,\n Transaction,\n TransactionV0,\n UnsignedTransaction,\n} from \"@sovereign-sdk/types\";\nimport type { HexString } from \"@sovereign-sdk/utils\";\nimport { bytesToHex, hexToBytes } from \"@sovereign-sdk/utils\";\nimport * as borsh from \"borsh\";\n\n/**\n * Base error class for multisig-related errors.\n */\nexport class MultisigError extends Error {}\n\n/**\n * Error thrown when a transaction has an unsupported version for multisig operations.\n */\nexport class InvalidTransactionVersionError extends MultisigError {}\n\n/**\n * Error thrown when a provided transaction doesn't match the expected unsigned transaction.\n */\nexport class TransactionMismatchError extends Error {\n constructor() {\n super(\n \"Provided transaction does not match the expected unsigned transaction\",\n );\n }\n}\n\n/**\n * Error thrown when multisig is constructed or used with invalid parameters.\n */\nexport class InvalidMultisigParameterError extends MultisigError {\n constructor(desc: string) {\n super(`Multisig was constructed with invalid parameter: ${desc}`);\n }\n}\n\n/**\n * Parameters for constructing a MultisigTransaction.\n */\nexport type MultisigParams = {\n /** The unsigned transaction to be signed by multiple parties */\n unsignedTx: UnsignedTransaction<unknown>;\n /** Array of signatures with pubkeys already collected */\n signatures: SignatureAndPubKey[];\n /** Array of public keys that haven't signed yet */\n unusedPubKeys: HexString[];\n /** Minimum number of signatures required */\n minSigners: number;\n};\n\n/**\n * Parameters for creating a MultisigTransaction from existing signed transactions.\n */\nexport type FromTransactionsParams = {\n /** Array of signed transactions to extract signatures from */\n txns: Transaction<unknown>[];\n /** Minimum number of signatures required */\n minSigners: number;\n /** All public keys that are members of the multisig */\n allPubKeys: HexString[];\n};\n\n/**\n * Represents a multisig transaction that collects signatures from multiple parties.\n * Only supports nonce-based transactions and V0 transaction variants for signature collection.\n */\nexport class MultisigTransaction {\n private unsignedTx: UnsignedTransaction<unknown>;\n private signatures: SignatureAndPubKey[] = [];\n private minSigners: number;\n private unusedPubKeys = new Set<HexString>();\n\n /**\n * Creates a new MultisigTransaction instance.\n * @param params - The multisig parameters including unsigned transaction, signatures, and public keys\n */\n constructor({\n unsignedTx,\n signatures,\n unusedPubKeys,\n minSigners,\n }: MultisigParams) {\n this.unsignedTx = unsignedTx;\n this.signatures = signatures;\n this.unusedPubKeys = new Set(unusedPubKeys);\n this.minSigners = minSigners;\n }\n\n /**\n * Creates an empty MultisigTransaction with no signatures collected yet.\n * @param unsignedTx - The unsigned transaction to be signed by multiple parties\n * @param minSigners - Minimum number of signatures required for completion\n * @param allPubKeys - All public keys that are members of the multisig\n * @returns A new empty MultisigTransaction instance\n */\n static empty(\n unsignedTx: UnsignedTransaction<unknown>,\n minSigners: number,\n allPubKeys: HexString[],\n ): MultisigTransaction {\n return new MultisigTransaction({\n unsignedTx,\n signatures: [],\n unusedPubKeys: allPubKeys,\n minSigners,\n });\n }\n\n /**\n * Creates a MultisigTransaction from an array of already-signed transactions.\n * Extracts signatures and validates that all transactions are identical except for signatures.\n * @param params - Parameters including the signed transactions, minimum signers, and all public keys\n * @returns A new MultisigTransaction instance\n * @throws {InvalidTransactionVersionError} If any transaction is not V0 variant\n * @throws {TransactionMismatchError} If transactions don't match each other\n * @throws {InvalidMultisigParameterError} If public keys are invalid or transaction is not nonce-based\n */\n static fromTransactions({\n txns,\n minSigners,\n allPubKeys,\n }: FromTransactionsParams): MultisigTransaction {\n const signatures: SignatureAndPubKey[] = [];\n const unsignedTx = asUnsignedTransaction(txns[0]);\n const unusedPubKeys = new Set<HexString>(allPubKeys);\n\n assertIsNonceBasedTx(unsignedTx);\n\n for (const tx of txns) {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n if (!unusedPubKeys.delete(pub_key)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pub_key}`,\n );\n }\n\n signatures.push({ pub_key, signature });\n }\n\n return new MultisigTransaction({\n unsignedTx,\n signatures,\n unusedPubKeys: Array.from(unusedPubKeys),\n minSigners,\n });\n }\n\n /**\n * Adds a signature & public key from a signed transaction to the multisig transaction.\n * @param tx - The signed transaction to extract signature from\n * @throws {InvalidTransactionVersionError} If the transaction is not V0 variant\n * @throws {TransactionMismatchError} If the transaction doesn't match the unsigned transaction\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignedTransaction(tx: Transaction<unknown>): void {\n assertTxVariant(tx);\n assertTxMatchesUnsignedTx(tx, this.unsignedTx);\n\n const { pub_key, signature } = tx.V0;\n\n this.addSignature(signature, pub_key);\n }\n\n /**\n * Adds a signature to the multisig transaction.\n * @param signature - The signature to add\n * @param pubKey - The public key corresponding to the signature\n * @throws {InvalidMultisigParameterError} If the public key is not a member or has already signed\n */\n addSignature(signature: HexString, pubKey: HexString): void {\n if (!this.unusedPubKeys.delete(pubKey)) {\n throw new InvalidMultisigParameterError(\n `Public key is not a member of the multisig or has already signed: ${pubKey}`,\n );\n }\n\n this.signatures.push({ pub_key: pubKey, signature });\n }\n\n /**\n * Checks if the multisig has collected enough signatures to be complete.\n * @returns True if the number of signatures meets or exceeds the minimum required\n */\n get isComplete(): boolean {\n return this.signatures.length >= this.minSigners;\n }\n\n /**\n * Gets the unsigned transaction.\n * @returns A readonly view of the unsigned transaction\n */\n get unsignedTransaction(): Readonly<UnsignedTransaction<unknown>> {\n return this.unsignedTx;\n }\n\n /**\n * Gets the signatures and public keys collected so far.\n * @returns A readonly view of the signatures and public keys\n */\n get signaturesAndPubKeys(): Readonly<SignatureAndPubKey[]> {\n return this.signatures;\n }\n\n /**\n * Gets the remaining public keys that haven't signed yet.\n * @returns A readonly view of the remaining public keys\n */\n get remainingPubKeys(): Readonly<Set<HexString>> {\n return this.unusedPubKeys;\n }\n\n /**\n * Gets the threshold number of signatures required for the multisig to be complete.\n * @returns The threshold number of signatures\n */\n get threshold(): number {\n return this.minSigners;\n }\n\n /**\n * Calculates the multisig address (credential ID) by hashing the threshold and sorted public keys.\n * This matches the Rust implementation: hash(threshold || borsh(sorted_pubkeys))\n * @param hasher - The hash algorithm to use (currently only 'sha256' is supported)\n * @returns The 32-byte multisig address as a Uint8Array\n */\n getMultisigAddress(hasher: \"sha256\" = \"sha256\"): Uint8Array {\n if (hasher !== \"sha256\") {\n throw new Error(`Unsupported hasher: ${hasher}`);\n }\n\n // Collect all public keys (signatures + unused)\n const allPubKeys = [\n ...this.signatures.map((s) => s.pub_key),\n ...Array.from(this.unusedPubKeys),\n ];\n const sortedPubKeys = allPubKeys.sort();\n const pubKeyBytes = sortedPubKeys.map((pk) => Array.from(hexToBytes(pk)));\n const buffer = new borsh.BinaryWriter();\n\n buffer.writeU8(this.minSigners);\n buffer.writeArray(pubKeyBytes, (pkBytes: number[]) => {\n buffer.writeFixedArray(new Uint8Array(pkBytes));\n });\n\n return sha256(buffer.toArray());\n }\n\n /**\n * Converts the multisig to a V1 transaction that can be submitted to the network.\n * @returns A V1 transaction containing all collected signatures and unused public keys\n */\n asTransaction(): Transaction<unknown> {\n return {\n V1: {\n runtime_call: this.unsignedTx.runtime_call,\n uniqueness: this.unsignedTx.uniqueness,\n details: this.unsignedTx.details,\n unused_pub_keys: Array.from(this.unusedPubKeys),\n signatures: this.signatures,\n min_signers: this.minSigners,\n },\n };\n }\n}\n\nfunction assertTxVariant(\n tx: Transaction<unknown>,\n): asserts tx is TransactionV0<unknown> {\n if (\"V1\" in tx) {\n throw new InvalidTransactionVersionError(\n \"Input transaction was an unsupported variant (V1)\",\n );\n }\n}\n\nfunction asUnsignedTransaction(\n tx: Transaction<unknown>,\n): UnsignedTransaction<unknown> {\n if (\"V0\" in tx) {\n return {\n runtime_call: tx.V0.runtime_call,\n uniqueness: tx.V0.uniqueness,\n details: tx.V0.details,\n };\n }\n\n if (\"V1\" in tx) {\n return {\n runtime_call: tx.V1.runtime_call,\n uniqueness: tx.V1.uniqueness,\n details: tx.V1.details,\n };\n }\n\n throw new InvalidTransactionVersionError(\n \"Transaction variant is neither V0 nor V1\",\n );\n}\n\nfunction assertTxMatchesUnsignedTx(\n tx: Transaction<unknown>,\n unsignedTx: UnsignedTransaction<unknown>,\n): void {\n const txAsUnsigned = asUnsignedTransaction(tx);\n\n if (JSON.stringify(txAsUnsigned) !== JSON.stringify(unsignedTx)) {\n throw new TransactionMismatchError();\n }\n}\n\nfunction assertIsNonceBasedTx(unsignedTx: UnsignedTransaction<unknown>): void {\n if (!(\"nonce\" in unsignedTx.uniqueness)) {\n throw new InvalidMultisigParameterError(\n \"Only nonce-based transactions are supported for multisig\",\n );\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sovereign-sdk/multisig",
3
- "version": "0.1.2",
3
+ "version": "0.3.0",
4
4
  "description": "Multisig functionality for Sovereign SDK applications",
5
5
  "repository": "github:Sovereign-Labs/sovereign-sdk",
6
6
  "files": [
@@ -23,7 +23,7 @@
23
23
  "typescript": "^5.6.3",
24
24
  "vitest": "4.0.7",
25
25
  "@sovereign-sdk/types": "^0.1.2",
26
- "@sovereign-sdk/web3": "^0.12.0"
26
+ "@sovereign-sdk/web3": "^0.12.2"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "tsup": "^8.3.0",
@@ -33,7 +33,9 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@sovereign-sdk/signers": "^0.4.0",
36
+ "@noble/hashes": "^1.5.0",
37
+ "borsh": "0.7.0",
38
+ "@sovereign-sdk/signers": "^0.5.1",
37
39
  "@sovereign-sdk/utils": "^0.0.4"
38
40
  },
39
41
  "scripts": {