@getomnichain/omnichain 0.6.0 → 0.6.2
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 +39 -0
- package/dist/cjs/evm/evm_chain.js +16 -0
- package/dist/cjs/evm/evm_chain.js.map +1 -1
- package/dist/cjs/utxo/bytes.js +11 -0
- package/dist/cjs/utxo/bytes.js.map +1 -0
- package/dist/cjs/utxo/index.js +3 -0
- package/dist/cjs/utxo/index.js.map +1 -1
- package/dist/cjs/utxo/keys.js +56 -0
- package/dist/cjs/utxo/keys.js.map +1 -0
- package/dist/cjs/utxo/raw_transaction.js +39 -0
- package/dist/cjs/utxo/raw_transaction.js.map +1 -0
- package/dist/cjs/utxo/script.js.map +1 -1
- package/dist/cjs/utxo/unsigned_utxo_transaction.js +135 -0
- package/dist/cjs/utxo/unsigned_utxo_transaction.js.map +1 -1
- package/dist/cjs/utxo/utxo_chain.js +137 -0
- package/dist/cjs/utxo/utxo_chain.js.map +1 -1
- package/dist/esm/evm/evm_chain.d.ts +1 -0
- package/dist/esm/evm/evm_chain.d.ts.map +1 -1
- package/dist/esm/evm/evm_chain.js +17 -1
- package/dist/esm/evm/evm_chain.js.map +1 -1
- package/dist/esm/utxo/bytes.d.ts +3 -0
- package/dist/esm/utxo/bytes.d.ts.map +1 -0
- package/dist/esm/utxo/bytes.js +7 -0
- package/dist/esm/utxo/bytes.js.map +1 -0
- package/dist/esm/utxo/index.d.ts +1 -0
- package/dist/esm/utxo/index.d.ts.map +1 -1
- package/dist/esm/utxo/index.js +1 -0
- package/dist/esm/utxo/index.js.map +1 -1
- package/dist/esm/utxo/keys.d.ts +8 -0
- package/dist/esm/utxo/keys.d.ts.map +1 -0
- package/dist/esm/utxo/keys.js +17 -0
- package/dist/esm/utxo/keys.js.map +1 -0
- package/dist/esm/utxo/raw_transaction.d.ts +5 -0
- package/dist/esm/utxo/raw_transaction.d.ts.map +1 -0
- package/dist/esm/utxo/raw_transaction.js +35 -0
- package/dist/esm/utxo/raw_transaction.js.map +1 -0
- package/dist/esm/utxo/script.d.ts +1 -0
- package/dist/esm/utxo/script.d.ts.map +1 -1
- package/dist/esm/utxo/script.js.map +1 -1
- package/dist/esm/utxo/unsigned_utxo_transaction.d.ts +7 -1
- package/dist/esm/utxo/unsigned_utxo_transaction.d.ts.map +1 -1
- package/dist/esm/utxo/unsigned_utxo_transaction.js +136 -1
- package/dist/esm/utxo/unsigned_utxo_transaction.js.map +1 -1
- package/dist/esm/utxo/utxo.d.ts +26 -0
- package/dist/esm/utxo/utxo.d.ts.map +1 -1
- package/dist/esm/utxo/utxo_chain.d.ts +8 -1
- package/dist/esm/utxo/utxo_chain.d.ts.map +1 -1
- package/dist/esm/utxo/utxo_chain.js +138 -1
- package/dist/esm/utxo/utxo_chain.js.map +1 -1
- package/dist/esm/utxo/utxo_network_params.d.ts +2 -1
- package/dist/esm/utxo/utxo_network_params.d.ts.map +1 -1
- package/docs/CONNECTIONS.md +7 -0
- package/docs/utxo.md +80 -5
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function isByteArray(value) {
|
|
2
|
+
return ArrayBuffer.isView(value) && value.BYTES_PER_ELEMENT === 1;
|
|
3
|
+
}
|
|
4
|
+
export function sameBytes(a, b) {
|
|
5
|
+
return Buffer.from(a.buffer, a.byteOffset, a.byteLength).equals(Buffer.from(b.buffer, b.byteOffset, b.byteLength));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=bytes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../../utxo/bytes.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,IAAK,KAAoB,CAAC,iBAAiB,KAAK,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,CAAa,EAAE,CAAa;IACpD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AACrH,CAAC"}
|
package/dist/esm/utxo/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './coin_selection.ts';
|
|
2
2
|
export * from './ecc.ts';
|
|
3
3
|
export * from './fee.ts';
|
|
4
|
+
export { utxoFromRawTransaction } from './raw_transaction.ts';
|
|
4
5
|
export * from './script.ts';
|
|
5
6
|
export * from './tools/broadcaster.ts';
|
|
6
7
|
export * from './tools/chain_tip_provider.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../utxo/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../utxo/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
package/dist/esm/utxo/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./coin_selection.js";
|
|
2
2
|
export * from "./ecc.js";
|
|
3
3
|
export * from "./fee.js";
|
|
4
|
+
export { utxoFromRawTransaction } from "./raw_transaction.js";
|
|
4
5
|
export * from "./script.js";
|
|
5
6
|
export * from "./tools/broadcaster.js";
|
|
6
7
|
export * from "./tools/chain_tip_provider.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utxo/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utxo/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC;AACpD,cAAc,0BAA0B,CAAC;AACzC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { payments } from 'bitcoinjs-lib';
|
|
2
|
+
import { UtxoSingleKeyScriptType } from './script.ts';
|
|
3
|
+
import { UtxoNetworkInfo } from './utxo_network_params.ts';
|
|
4
|
+
export declare const COMPACT_SIGNATURE_BYTES = 64;
|
|
5
|
+
export declare function isCompressedPublicKey(publicKey: unknown): publicKey is Uint8Array;
|
|
6
|
+
export declare function singleKeyPayment(publicKey: Uint8Array, scriptType: UtxoSingleKeyScriptType, network: UtxoNetworkInfo): payments.Payment;
|
|
7
|
+
export declare function verifyStrictSignature(publicKey: Uint8Array, hash: Uint8Array, signature: Uint8Array): boolean;
|
|
8
|
+
//# sourceMappingURL=keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../../utxo/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,OAAO,EAAmB,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAE1C,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,IAAI,UAAU,CAEjF;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,UAAU,EACrB,UAAU,EAAE,uBAAuB,EACnC,OAAO,EAAE,eAAe,GACvB,QAAQ,CAAC,OAAO,CAIlB;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,UAAU,EACrB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,UAAU,GACpB,OAAO,CAET"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { payments } from 'bitcoinjs-lib';
|
|
2
|
+
import * as ecc from 'tiny-secp256k1';
|
|
3
|
+
import { isByteArray } from "./bytes.js";
|
|
4
|
+
import { UtxoScriptTypes } from "./script.js";
|
|
5
|
+
export const COMPACT_SIGNATURE_BYTES = 64;
|
|
6
|
+
export function isCompressedPublicKey(publicKey) {
|
|
7
|
+
return isByteArray(publicKey) && ecc.isPointCompressed(publicKey);
|
|
8
|
+
}
|
|
9
|
+
export function singleKeyPayment(publicKey, scriptType, network) {
|
|
10
|
+
return scriptType === UtxoScriptTypes.P2WPKH
|
|
11
|
+
? payments.p2wpkh({ pubkey: publicKey, network })
|
|
12
|
+
: payments.p2pkh({ pubkey: publicKey, network });
|
|
13
|
+
}
|
|
14
|
+
export function verifyStrictSignature(publicKey, hash, signature) {
|
|
15
|
+
return ecc.verify(hash, publicKey, signature, true);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../utxo/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,eAAe,EAA2B,MAAM,aAAa,CAAC;AAGvE,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAE1C,MAAM,UAAU,qBAAqB,CAAC,SAAkB;IACtD,OAAO,WAAW,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAqB,EACrB,UAAmC,EACnC,OAAwB;IAExB,OAAO,UAAU,KAAK,eAAe,CAAC,MAAM;QAC1C,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QACjD,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,SAAqB,EACrB,IAAgB,EAChB,SAAqB;IAErB,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Transaction } from 'bitcoinjs-lib';
|
|
2
|
+
import { UnspentTransactionOutput } from './utxo.ts';
|
|
3
|
+
export declare function decodeRawTransaction(rawTxHex: string): Transaction | null;
|
|
4
|
+
export declare function utxoFromRawTransaction(rawTxHex: string, vout: number, ownerAddress: string): UnspentTransactionOutput;
|
|
5
|
+
//# sourceMappingURL=raw_transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw_transaction.d.ts","sourceRoot":"","sources":["../../../utxo/raw_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAK5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAIrD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAOzE;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,wBAAwB,CA0B1B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Transaction } from 'bitcoinjs-lib';
|
|
2
|
+
import { ChainError, ChainErrorKinds } from "../errors.js";
|
|
3
|
+
import { detectScriptType } from "./script.js";
|
|
4
|
+
const HEX_BYTES = /^(?:[0-9a-fA-F]{2})+$/;
|
|
5
|
+
export function decodeRawTransaction(rawTxHex) {
|
|
6
|
+
if (typeof rawTxHex !== 'string' || !HEX_BYTES.test(rawTxHex))
|
|
7
|
+
return null;
|
|
8
|
+
try {
|
|
9
|
+
return Transaction.fromHex(rawTxHex);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function utxoFromRawTransaction(rawTxHex, vout, ownerAddress) {
|
|
16
|
+
const tx = decodeRawTransaction(rawTxHex);
|
|
17
|
+
if (tx === null) {
|
|
18
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, 'utxoFromRawTransaction: rawTxHex is not a valid transaction');
|
|
19
|
+
}
|
|
20
|
+
const txid = tx.getId();
|
|
21
|
+
const output = Number.isInteger(vout) && vout >= 0 ? tx.outs[vout] : undefined;
|
|
22
|
+
if (output === undefined) {
|
|
23
|
+
throw new ChainError(ChainErrorKinds.InvalidArgument, `utxoFromRawTransaction: transaction ${txid} has no output ${vout} (it has ${tx.outs.length})`, { txHash: txid });
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
txid,
|
|
27
|
+
vout,
|
|
28
|
+
valueSats: Number(output.value),
|
|
29
|
+
scriptPubKeyHex: Buffer.from(output.script).toString('hex'),
|
|
30
|
+
scriptType: detectScriptType(output.script),
|
|
31
|
+
confirmations: 0,
|
|
32
|
+
ownerAddress,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=raw_transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw_transaction.js","sourceRoot":"","sources":["../../../utxo/raw_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG/C,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3E,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,QAAgB,EAChB,IAAY,EACZ,YAAoB;IAEpB,MAAM,EAAE,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAClB,eAAe,CAAC,eAAe,EAC/B,6DAA6D,CAC9D,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,UAAU,CAClB,eAAe,CAAC,eAAe,EAC/B,uCAAuC,IAAI,kBAAkB,IAAI,YAAY,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,EAC9F,EAAE,MAAM,EAAE,IAAI,EAAE,CACjB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;QAC/B,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC3D,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC;QAC3C,aAAa,EAAE,CAAC;QAChB,YAAY;KACb,CAAC;AACJ,CAAC"}
|
|
@@ -9,6 +9,7 @@ export declare const UtxoScriptTypes: {
|
|
|
9
9
|
readonly NonStandard: "non_standard";
|
|
10
10
|
};
|
|
11
11
|
export type UtxoScriptType = (typeof UtxoScriptTypes)[keyof typeof UtxoScriptTypes];
|
|
12
|
+
export type UtxoSingleKeyScriptType = typeof UtxoScriptTypes.P2WPKH | typeof UtxoScriptTypes.P2PKH;
|
|
12
13
|
export declare function detectScriptType(script: Uint8Array): UtxoScriptType;
|
|
13
14
|
export declare function addressToScriptPubKey(addressStr: string, network: networks.Network): Uint8Array;
|
|
14
15
|
export declare function scriptTypeForAddress(addressStr: string, network: networks.Network): UtxoScriptType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../../utxo/script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,QAAQ,EAAgC,MAAM,eAAe,CAAC;AAI9F,eAAO,MAAM,eAAe;;;;;;;;CAQlB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,CA4BnE;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,UAAU,CAE/F;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,cAAc,CAGlG;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAOhE"}
|
|
1
|
+
{"version":3,"file":"script.d.ts","sourceRoot":"","sources":["../../../utxo/script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,QAAQ,EAAgC,MAAM,eAAe,CAAC;AAI9F,eAAO,MAAM,eAAe;;;;;;;;CAQlB,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEpF,MAAM,MAAM,uBAAuB,GAAG,OAAO,eAAe,CAAC,MAAM,GAAG,OAAO,eAAe,CAAC,KAAK,CAAC;AAEnG,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,cAAc,CA4BnE;AAED,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,UAAU,CAE/F;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,cAAc,CAGlG;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAOhE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script.js","sourceRoot":"","sources":["../../../utxo/script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAY,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9F,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,cAAc;CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"script.js","sourceRoot":"","sources":["../../../utxo/script.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Psbt } from 'bitcoinjs-lib';
|
|
2
2
|
import { UnsignedTransaction } from '../unsigned_transaction.ts';
|
|
3
|
-
import { UnspentTransactionOutput } from './utxo.ts';
|
|
3
|
+
import { FinalizedUtxoTransaction, UnspentTransactionOutput, UtxoSigner } from './utxo.ts';
|
|
4
4
|
import { UtxoNetworkParams } from './utxo_network_params.ts';
|
|
5
5
|
export interface UnsignedUtxoTransactionInit {
|
|
6
6
|
chainId: number;
|
|
@@ -28,5 +28,11 @@ export declare class UnsignedUtxoTransaction extends UnsignedTransaction {
|
|
|
28
28
|
readonly inputsToSign: Readonly<Record<string, number[]>>;
|
|
29
29
|
constructor(init: UnsignedUtxoTransactionInit);
|
|
30
30
|
toPsbt(): Psbt;
|
|
31
|
+
signWith(signer: UtxoSigner): UnsignedUtxoTransaction;
|
|
32
|
+
finalize(): FinalizedUtxoTransaction;
|
|
33
|
+
private verifiedPrevouts;
|
|
34
|
+
private inputIndicesOwnedBy;
|
|
35
|
+
private withPsbt;
|
|
36
|
+
private invalid;
|
|
31
37
|
}
|
|
32
38
|
//# sourceMappingURL=unsigned_utxo_transaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unsigned_utxo_transaction.d.ts","sourceRoot":"","sources":["../../../utxo/unsigned_utxo_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"unsigned_utxo_transaction.d.ts","sourceRoot":"","sources":["../../../utxo/unsigned_utxo_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAe,MAAM,eAAe,CAAC;AAIlD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAUjE,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACxC;AAED,qBAAa,uBAAwB,SAAQ,mBAAmB;IAC9D,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;gBAE9C,IAAI,EAAE,2BAA2B;IAc7C,MAAM,IAAI,IAAI;IAId,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,uBAAuB;IAkCrD,QAAQ,IAAI,wBAAwB;IAqBpC,OAAO,CAAC,gBAAgB;IAsCxB,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,OAAO;CAQhB"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { Psbt } from 'bitcoinjs-lib';
|
|
1
|
+
import { Psbt, Transaction } from 'bitcoinjs-lib';
|
|
2
|
+
import { ChainError, ChainErrorKinds, isChainError } from "../errors.js";
|
|
2
3
|
import { NetworkType } from "../network_type.js";
|
|
3
4
|
import { UnsignedTransaction } from "../unsigned_transaction.js";
|
|
5
|
+
import { isByteArray, sameBytes } from "./bytes.js";
|
|
6
|
+
import { COMPACT_SIGNATURE_BYTES, isCompressedPublicKey, singleKeyPayment, verifyStrictSignature, } from "./keys.js";
|
|
7
|
+
import { UtxoScriptTypes } from "./script.js";
|
|
4
8
|
export class UnsignedUtxoTransaction extends UnsignedTransaction {
|
|
5
9
|
params;
|
|
6
10
|
psbtBase64;
|
|
@@ -28,5 +32,136 @@ export class UnsignedUtxoTransaction extends UnsignedTransaction {
|
|
|
28
32
|
toPsbt() {
|
|
29
33
|
return Psbt.fromBase64(this.psbtBase64, { network: this.params.networkInfo });
|
|
30
34
|
}
|
|
35
|
+
signWith(signer) {
|
|
36
|
+
if (!isCompressedPublicKey(signer?.publicKey)) {
|
|
37
|
+
throw this.invalid('signWith: signer.publicKey must be a 33-byte compressed secp256k1 public key');
|
|
38
|
+
}
|
|
39
|
+
const psbt = this.toPsbt();
|
|
40
|
+
const prevouts = this.verifiedPrevouts(psbt, 'signWith');
|
|
41
|
+
const owned = this.inputIndicesOwnedBy(prevouts, signer.publicKey);
|
|
42
|
+
if (owned.length === 0) {
|
|
43
|
+
throw this.invalid('signWith: the signer owns none of the inputs');
|
|
44
|
+
}
|
|
45
|
+
const checkedSigner = {
|
|
46
|
+
publicKey: signer.publicKey,
|
|
47
|
+
sign: (hash) => {
|
|
48
|
+
const signature = signer.sign(hash);
|
|
49
|
+
if (!isByteArray(signature) || signature.length !== COMPACT_SIGNATURE_BYTES) {
|
|
50
|
+
throw this.invalid(`signWith: signer.sign must return a ${COMPACT_SIGNATURE_BYTES}-byte compact ECDSA signature`);
|
|
51
|
+
}
|
|
52
|
+
return signature;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
for (const index of owned) {
|
|
56
|
+
if (hasSignatureFrom(psbt, index, signer.publicKey))
|
|
57
|
+
continue;
|
|
58
|
+
try {
|
|
59
|
+
psbt.signInput(index, checkedSigner);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
if (isChainError(err))
|
|
63
|
+
throw err;
|
|
64
|
+
throw this.invalid(`signWith: signing input ${index} failed: ${errorMessage(err)}`, err);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return this.withPsbt(psbt);
|
|
68
|
+
}
|
|
69
|
+
finalize() {
|
|
70
|
+
const psbt = this.toPsbt();
|
|
71
|
+
this.verifiedPrevouts(psbt, 'finalize');
|
|
72
|
+
psbt.data.inputs.forEach((input, index) => {
|
|
73
|
+
if (!input.partialSig || input.partialSig.length === 0) {
|
|
74
|
+
throw this.invalid(`finalize: input ${index} is not signed`);
|
|
75
|
+
}
|
|
76
|
+
if (!signaturesAreValid(psbt, index)) {
|
|
77
|
+
throw this.invalid(`finalize: input ${index} has an invalid signature`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
let tx;
|
|
81
|
+
try {
|
|
82
|
+
psbt.finalizeAllInputs();
|
|
83
|
+
tx = psbt.extractTransaction();
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
throw this.invalid(`finalize: ${errorMessage(err)}`, err);
|
|
87
|
+
}
|
|
88
|
+
return { hex: tx.toHex(), txid: tx.getId(), vsize: tx.virtualSize() };
|
|
89
|
+
}
|
|
90
|
+
verifiedPrevouts(psbt, method) {
|
|
91
|
+
const prevouts = psbt.data.inputs.map((input, index) => {
|
|
92
|
+
if (!input.nonWitnessUtxo) {
|
|
93
|
+
throw this.invalid(`${method}: input ${index} carries no parent transaction (nonWitnessUtxo)`);
|
|
94
|
+
}
|
|
95
|
+
const parent = parseParent(input.nonWitnessUtxo);
|
|
96
|
+
if (parent === null) {
|
|
97
|
+
throw this.invalid(`${method}: input ${index} has a parent transaction that does not parse`);
|
|
98
|
+
}
|
|
99
|
+
const spent = psbt.txInputs[index];
|
|
100
|
+
if (!sameBytes(parent.getHash(), spent.hash)) {
|
|
101
|
+
throw this.invalid(`${method}: input ${index} has a parent transaction that is not the one it spends`);
|
|
102
|
+
}
|
|
103
|
+
const prevout = parent.outs[spent.index];
|
|
104
|
+
if (prevout === undefined) {
|
|
105
|
+
throw this.invalid(`${method}: input ${index} spends output ${spent.index}, which its parent transaction does not have`);
|
|
106
|
+
}
|
|
107
|
+
if (input.witnessUtxo && input.witnessUtxo.value !== prevout.value) {
|
|
108
|
+
throw this.invalid(`${method}: input ${index} declares ${input.witnessUtxo.value} sats, but its parent output holds ${prevout.value} sats`);
|
|
109
|
+
}
|
|
110
|
+
if (input.witnessUtxo && !sameBytes(input.witnessUtxo.script, prevout.script)) {
|
|
111
|
+
throw this.invalid(`${method}: input ${index} declares a script that differs from its parent output`);
|
|
112
|
+
}
|
|
113
|
+
return prevout;
|
|
114
|
+
});
|
|
115
|
+
const realFeeSats = prevouts.reduce((sum, prevout) => sum + prevout.value, 0n) -
|
|
116
|
+
psbt.txOutputs.reduce((sum, output) => sum + output.value, 0n);
|
|
117
|
+
if (Number(realFeeSats) !== this.feeSats) {
|
|
118
|
+
throw this.invalid(`${method}: the transaction would pay ${realFeeSats} sats in fees, not the reported ${this.feeSats} sats`);
|
|
119
|
+
}
|
|
120
|
+
return prevouts;
|
|
121
|
+
}
|
|
122
|
+
inputIndicesOwnedBy(prevouts, publicKey) {
|
|
123
|
+
const ownedScripts = [UtxoScriptTypes.P2WPKH, UtxoScriptTypes.P2PKH].map((scriptType) => singleKeyPayment(publicKey, scriptType, this.params.networkInfo).output);
|
|
124
|
+
return prevouts.flatMap((prevout, index) => ownedScripts.some((owned) => sameBytes(owned, prevout.script)) ? [index] : []);
|
|
125
|
+
}
|
|
126
|
+
withPsbt(psbt) {
|
|
127
|
+
return new UnsignedUtxoTransaction({
|
|
128
|
+
chainId: this.chainId,
|
|
129
|
+
params: this.params,
|
|
130
|
+
psbtBase64: psbt.toBase64(),
|
|
131
|
+
selectedInputs: this.selectedInputs,
|
|
132
|
+
feeSats: this.feeSats,
|
|
133
|
+
feeRateSatsPerVByte: this.feeRateSatsPerVByte,
|
|
134
|
+
estimatedVBytes: this.estimatedVBytes,
|
|
135
|
+
totalInputSats: this.totalInputSats,
|
|
136
|
+
totalOutputSats: this.totalOutputSats,
|
|
137
|
+
changeAddress: this.changeAddress,
|
|
138
|
+
inputsToSign: this.inputsToSign,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
invalid(message, cause) {
|
|
142
|
+
return new ChainError(ChainErrorKinds.InvalidArgument, `UnsignedUtxoTransaction.${message}`, { chainId: this.chainId }, cause);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function parseParent(nonWitnessUtxo) {
|
|
146
|
+
try {
|
|
147
|
+
return Transaction.fromBuffer(nonWitnessUtxo);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function hasSignatureFrom(psbt, index, publicKey) {
|
|
154
|
+
return psbt.data.inputs[index].partialSig?.some((sig) => sameBytes(sig.pubkey, publicKey)) ?? false;
|
|
155
|
+
}
|
|
156
|
+
function signaturesAreValid(psbt, index) {
|
|
157
|
+
try {
|
|
158
|
+
return psbt.validateSignaturesOfInput(index, verifyStrictSignature);
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function errorMessage(err) {
|
|
165
|
+
return err instanceof Error ? err.message : String(err);
|
|
31
166
|
}
|
|
32
167
|
//# sourceMappingURL=unsigned_utxo_transaction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unsigned_utxo_transaction.js","sourceRoot":"","sources":["../../../utxo/unsigned_utxo_transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"unsigned_utxo_transaction.js","sourceRoot":"","sources":["../../../utxo/unsigned_utxo_transaction.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/utxo/utxo.d.ts
CHANGED
|
@@ -9,6 +9,32 @@ export interface UnspentTransactionOutput {
|
|
|
9
9
|
confirmations: number;
|
|
10
10
|
ownerAddress: string;
|
|
11
11
|
}
|
|
12
|
+
export interface UtxoPsbtInput {
|
|
13
|
+
utxo: UnspentTransactionOutput;
|
|
14
|
+
parentTxHex: string;
|
|
15
|
+
}
|
|
16
|
+
export type UtxoPsbtOutput = {
|
|
17
|
+
kind: 'address';
|
|
18
|
+
address: string;
|
|
19
|
+
valueSats: number;
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'opReturn';
|
|
22
|
+
data: Uint8Array;
|
|
23
|
+
};
|
|
24
|
+
export interface AssembleUtxoTransactionRequest {
|
|
25
|
+
inputs: readonly UtxoPsbtInput[];
|
|
26
|
+
outputs: readonly UtxoPsbtOutput[];
|
|
27
|
+
rbfEnabled?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface UtxoSigner {
|
|
30
|
+
publicKey: Uint8Array;
|
|
31
|
+
sign(hash: Uint8Array): Uint8Array;
|
|
32
|
+
}
|
|
33
|
+
export interface FinalizedUtxoTransaction {
|
|
34
|
+
hex: string;
|
|
35
|
+
txid: string;
|
|
36
|
+
vsize: number;
|
|
37
|
+
}
|
|
12
38
|
export interface UtxoTransactionInput {
|
|
13
39
|
txid: string;
|
|
14
40
|
vout: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utxo.d.ts","sourceRoot":"","sources":["../../../utxo/utxo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,cAAc,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACxC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC1C,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,IAAI,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,MAAM,0BAA0B,GAAG,SAAS,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,cAAc,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,mBAAmB,EAAE,CAAC;IAC3B,IAAI,EAAE,qBAAqB,EAAE,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"utxo.d.ts","sourceRoot":"","sources":["../../../utxo/utxo.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,12 +5,13 @@ import { Token } from '../token.ts';
|
|
|
5
5
|
import { UtxoTransactionStatus } from './utxo_transaction_status.ts';
|
|
6
6
|
import './ecc.ts';
|
|
7
7
|
import { CoinSelectionParams, CoinSelectionResult } from './coin_selection.ts';
|
|
8
|
+
import { UtxoSingleKeyScriptType } from './script.ts';
|
|
8
9
|
import { UtxoBroadcaster } from './tools/broadcaster.ts';
|
|
9
10
|
import { UtxoChainTipProvider } from './tools/chain_tip_provider.ts';
|
|
10
11
|
import { UtxoFeeEstimator } from './tools/fee_estimator.ts';
|
|
11
12
|
import { UtxoRawTransactionProvider } from './tools/raw_transaction_provider.ts';
|
|
12
13
|
import { UtxoProvider } from './tools/utxo_provider.ts';
|
|
13
|
-
import { UnspentTransactionOutput } from './utxo.ts';
|
|
14
|
+
import { AssembleUtxoTransactionRequest, UnspentTransactionOutput } from './utxo.ts';
|
|
14
15
|
import { UtxoNetworkParams } from './utxo_network_params.ts';
|
|
15
16
|
import { UnsignedUtxoTransaction } from './unsigned_utxo_transaction.ts';
|
|
16
17
|
export interface UtxoChainInit {
|
|
@@ -89,6 +90,8 @@ export declare class UtxoChain extends Chain {
|
|
|
89
90
|
getTransactionStatus(txHashes: string[], opts?: import('../chain.base.ts').GetTransactionStatusOpts): Promise<UtxoTransactionStatus[]>;
|
|
90
91
|
private getUtxoStatusOnce;
|
|
91
92
|
createTransferUnsignedTransaction(req: CreateUtxoTransferOptions | CreateTransferRequest): Promise<UnsignedUtxoTransaction>;
|
|
93
|
+
assembleTransaction(request: AssembleUtxoTransactionRequest): UnsignedUtxoTransaction;
|
|
94
|
+
addressForPublicKey(publicKey: Uint8Array, scriptType?: UtxoSingleKeyScriptType): string;
|
|
92
95
|
broadcast(signed: string | Uint8Array, opts?: BroadcastOpts): Promise<string>;
|
|
93
96
|
private computeUtxoTxidLE;
|
|
94
97
|
protected buildTransfer(req: CreateUtxoTransferOptions, getUtxosOptions: GetUtxosOptions | undefined): Promise<UnsignedUtxoTransaction>;
|
|
@@ -98,6 +101,10 @@ export declare class UtxoChain extends Chain {
|
|
|
98
101
|
sequence: number;
|
|
99
102
|
parentTxHex: string;
|
|
100
103
|
}): void;
|
|
104
|
+
private checkPsbtInput;
|
|
105
|
+
private resolvePsbtOutput;
|
|
106
|
+
private outputScriptFor;
|
|
107
|
+
private invalidArgument;
|
|
101
108
|
protected resolveFeeRate(overrideRate: number | undefined, targetBlocks: number | undefined): Promise<number>;
|
|
102
109
|
static targetBlocksForPriority(priority: Priority): number;
|
|
103
110
|
suggestFeeRate(priority: Priority): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utxo_chain.d.ts","sourceRoot":"","sources":["../../../utxo/utxo_chain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAe,MAAM,eAAe,CAAC;AAalD,OAAO,EACL,aAAa,EACb,KAAK,EACL,qBAAqB,EACrB,6BAA6B,EAC9B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAMpC,OAAO,EAGL,qBAAqB,EACtB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,UAAU,CAAC;AAClB,OAAO,EAEL,mBAAmB,EACnB,mBAAmB,EAEpB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"utxo_chain.d.ts","sourceRoot":"","sources":["../../../utxo/utxo_chain.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,10 @@ import { UtxoTransactionFees, UtxoTransactionOutput, UtxoTransactionStatus, } fr
|
|
|
12
12
|
import "./ecc.js";
|
|
13
13
|
import { CoinSelectionOutcomes, selectCoins, } from "./coin_selection.js";
|
|
14
14
|
import { costOfChangeSats, estimateTxVBytes, outputVBytes } from "./fee.js";
|
|
15
|
-
import {
|
|
15
|
+
import { isByteArray, sameBytes } from "./bytes.js";
|
|
16
|
+
import { isCompressedPublicKey, singleKeyPayment } from "./keys.js";
|
|
17
|
+
import { decodeRawTransaction } from "./raw_transaction.js";
|
|
18
|
+
import { UtxoScriptTypes, addressToScriptPubKey, buildOpReturnScript, detectScriptType, scriptTypeForAddress, } from "./script.js";
|
|
16
19
|
import { FINAL_SEQUENCE, OP_RETURN_MAX_BYTES, RBF_SEQUENCE, } from "./utxo_network_params.js";
|
|
17
20
|
import { UnsignedUtxoTransaction } from "./unsigned_utxo_transaction.js";
|
|
18
21
|
const RESERVED_BTC_CHAIN_IDS = [
|
|
@@ -261,6 +264,72 @@ export class UtxoChain extends Chain {
|
|
|
261
264
|
async createTransferUnsignedTransaction(req) {
|
|
262
265
|
return this.buildTransfer(req, undefined);
|
|
263
266
|
}
|
|
267
|
+
assembleTransaction(request) {
|
|
268
|
+
const { inputs, outputs } = request;
|
|
269
|
+
if (inputs.length === 0) {
|
|
270
|
+
throw this.invalidArgument('assembleTransaction: at least one input is required');
|
|
271
|
+
}
|
|
272
|
+
if (outputs.length === 0) {
|
|
273
|
+
throw this.invalidArgument('assembleTransaction: at least one output is required');
|
|
274
|
+
}
|
|
275
|
+
const spentOutpoints = new Set();
|
|
276
|
+
const inputScriptTypes = inputs.map((input, index) => {
|
|
277
|
+
const scriptType = this.checkPsbtInput(input, index);
|
|
278
|
+
const outpoint = `${input.utxo.txid.toLowerCase()}:${input.utxo.vout}`;
|
|
279
|
+
if (spentOutpoints.has(outpoint)) {
|
|
280
|
+
throw this.invalidArgument(`assembleTransaction: inputs[${index}] spends ${outpoint} a second time`);
|
|
281
|
+
}
|
|
282
|
+
spentOutpoints.add(outpoint);
|
|
283
|
+
return scriptType;
|
|
284
|
+
});
|
|
285
|
+
const resolvedOutputs = outputs.map((output, index) => this.resolvePsbtOutput(output, index));
|
|
286
|
+
const opReturnDataLengths = resolvedOutputs.flatMap((o) => o.opReturnDataLength === null ? [] : [o.opReturnDataLength]);
|
|
287
|
+
if (opReturnDataLengths.length > 1) {
|
|
288
|
+
throw this.invalidArgument('assembleTransaction: at most one opReturn output is allowed');
|
|
289
|
+
}
|
|
290
|
+
const totalInputSats = inputs.reduce((sum, { utxo }) => sum + utxo.valueSats, 0);
|
|
291
|
+
const totalOutputSats = resolvedOutputs.reduce((sum, o) => sum + o.valueSats, 0);
|
|
292
|
+
if (totalOutputSats > totalInputSats) {
|
|
293
|
+
throw this.invalidArgument(`assembleTransaction: outputs total ${totalOutputSats} sats but inputs only ${totalInputSats} sats`);
|
|
294
|
+
}
|
|
295
|
+
const sequence = (request.rbfEnabled ?? this.rbfEnabled) ? RBF_SEQUENCE : FINAL_SEQUENCE;
|
|
296
|
+
const psbt = new Psbt({ network: this.params.networkInfo });
|
|
297
|
+
const inputsToSign = {};
|
|
298
|
+
inputs.forEach(({ utxo, parentTxHex }, index) => {
|
|
299
|
+
this.addInputToPsbt({ psbt, utxo, sequence, parentTxHex });
|
|
300
|
+
(inputsToSign[utxo.ownerAddress] ??= []).push(index);
|
|
301
|
+
});
|
|
302
|
+
for (const output of resolvedOutputs) {
|
|
303
|
+
psbt.addOutput({ script: output.script, value: BigInt(output.valueSats) });
|
|
304
|
+
}
|
|
305
|
+
const estimatedVBytes = estimateTxVBytes(inputScriptTypes, resolvedOutputs.flatMap((o) => (o.opReturnDataLength === null ? [detectScriptType(o.script)] : [])), opReturnDataLengths);
|
|
306
|
+
const feeSats = totalInputSats - totalOutputSats;
|
|
307
|
+
return new UnsignedUtxoTransaction({
|
|
308
|
+
chainId: this.chainId,
|
|
309
|
+
params: this.params,
|
|
310
|
+
psbtBase64: psbt.toBase64(),
|
|
311
|
+
selectedInputs: inputs.map(({ utxo }) => utxo),
|
|
312
|
+
feeSats,
|
|
313
|
+
feeRateSatsPerVByte: feeSats / estimatedVBytes,
|
|
314
|
+
estimatedVBytes,
|
|
315
|
+
totalInputSats,
|
|
316
|
+
totalOutputSats,
|
|
317
|
+
changeAddress: null,
|
|
318
|
+
inputsToSign,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
addressForPublicKey(publicKey, scriptType = UtxoScriptTypes.P2WPKH) {
|
|
322
|
+
if (!isCompressedPublicKey(publicKey)) {
|
|
323
|
+
throw this.invalidArgument('addressForPublicKey: publicKey must be a 33-byte compressed secp256k1 public key');
|
|
324
|
+
}
|
|
325
|
+
if (scriptType !== UtxoScriptTypes.P2WPKH && scriptType !== UtxoScriptTypes.P2PKH) {
|
|
326
|
+
throw this.invalidArgument(`addressForPublicKey: scriptType must be '${UtxoScriptTypes.P2WPKH}' or '${UtxoScriptTypes.P2PKH}', got ${String(scriptType)}`);
|
|
327
|
+
}
|
|
328
|
+
if (scriptType === UtxoScriptTypes.P2WPKH && !this.params.networkInfo.bech32) {
|
|
329
|
+
throw new ChainError(ChainErrorKinds.FeatureNotSupported, `${this.name}: the network has no segwit addresses; use scriptType '${UtxoScriptTypes.P2PKH}'`, { chainId: this.chainId });
|
|
330
|
+
}
|
|
331
|
+
return singleKeyPayment(publicKey, scriptType, this.params.networkInfo).address;
|
|
332
|
+
}
|
|
264
333
|
async broadcast(signed, opts) {
|
|
265
334
|
if (opts && opts.signal !== undefined) {
|
|
266
335
|
throw new ChainError(ChainErrorKinds.FeatureNotSupported, `UTXO broadcast: signal is not honored in 0.3.0 (silently ignoring would let a caller conclude 'not sent' while the tx still lands). Cancellation returns in 0.3.1.`, { chainId: this.chainId });
|
|
@@ -458,6 +527,66 @@ export class UtxoChain extends Chain {
|
|
|
458
527
|
}
|
|
459
528
|
psbt.addInput(input);
|
|
460
529
|
}
|
|
530
|
+
checkPsbtInput({ utxo, parentTxHex }, index) {
|
|
531
|
+
const field = `assembleTransaction: inputs[${index}]`;
|
|
532
|
+
const parent = decodeRawTransaction(parentTxHex);
|
|
533
|
+
if (parent === null) {
|
|
534
|
+
throw this.invalidArgument(`${field}.parentTxHex is not a valid transaction`);
|
|
535
|
+
}
|
|
536
|
+
const parentTxid = parent.getId();
|
|
537
|
+
if (typeof utxo.txid !== 'string' || utxo.txid.toLowerCase() !== parentTxid) {
|
|
538
|
+
throw this.invalidArgument(`${field}: parentTxHex is transaction ${parentTxid}, not utxo.txid ${String(utxo.txid)}`, { txHash: parentTxid });
|
|
539
|
+
}
|
|
540
|
+
const parentOutput = Number.isInteger(utxo.vout) && utxo.vout >= 0 ? parent.outs[utxo.vout] : undefined;
|
|
541
|
+
if (parentOutput === undefined) {
|
|
542
|
+
throw this.invalidArgument(`${field}: transaction ${parentTxid} has no output ${utxo.vout} (it has ${parent.outs.length})`, { txHash: parentTxid });
|
|
543
|
+
}
|
|
544
|
+
if (Number(parentOutput.value) !== utxo.valueSats) {
|
|
545
|
+
throw this.invalidArgument(`${field}: utxo.valueSats ${utxo.valueSats} does not match the parent output value ${parentOutput.value}`, { txHash: parentTxid });
|
|
546
|
+
}
|
|
547
|
+
const script = Buffer.from(parentOutput.script);
|
|
548
|
+
if (typeof utxo.scriptPubKeyHex !== 'string' || utxo.scriptPubKeyHex.toLowerCase() !== script.toString('hex')) {
|
|
549
|
+
throw this.invalidArgument(`${field}: utxo.scriptPubKeyHex does not match the parent output script`, { txHash: parentTxid });
|
|
550
|
+
}
|
|
551
|
+
const scriptType = detectScriptType(script);
|
|
552
|
+
if (scriptType === UtxoScriptTypes.OpReturn || scriptType === UtxoScriptTypes.NonStandard) {
|
|
553
|
+
throw this.invalidArgument(`${field}: cannot spend an output of script type ${scriptType}`, { txHash: parentTxid });
|
|
554
|
+
}
|
|
555
|
+
if (!sameBytes(this.outputScriptFor(utxo.ownerAddress, `${field}.utxo.ownerAddress`), script)) {
|
|
556
|
+
throw this.invalidArgument(`${field}: utxo.ownerAddress ${utxo.ownerAddress} does not own the output it spends`, { txHash: parentTxid, address: utxo.ownerAddress });
|
|
557
|
+
}
|
|
558
|
+
return scriptType;
|
|
559
|
+
}
|
|
560
|
+
resolvePsbtOutput(output, index) {
|
|
561
|
+
const field = `assembleTransaction: outputs[${index}]`;
|
|
562
|
+
if (output.kind === 'address') {
|
|
563
|
+
const script = this.outputScriptFor(output.address, `${field}.address`);
|
|
564
|
+
if (!Number.isSafeInteger(output.valueSats) || output.valueSats < this.params.dustValueSats) {
|
|
565
|
+
throw this.invalidArgument(`${field}.valueSats must be an integer of at least ${this.params.dustValueSats} sats (dust), got ${output.valueSats}`);
|
|
566
|
+
}
|
|
567
|
+
return { script, valueSats: output.valueSats, opReturnDataLength: null };
|
|
568
|
+
}
|
|
569
|
+
if (output.kind === 'opReturn') {
|
|
570
|
+
if (!isByteArray(output.data) || output.data.length > OP_RETURN_MAX_BYTES) {
|
|
571
|
+
throw this.invalidArgument(`${field}.data must be a byte array of at most ${OP_RETURN_MAX_BYTES} bytes`);
|
|
572
|
+
}
|
|
573
|
+
return { script: buildOpReturnScript(output.data), valueSats: 0, opReturnDataLength: output.data.length };
|
|
574
|
+
}
|
|
575
|
+
throw this.invalidArgument(`${field}.kind must be 'address' or 'opReturn', got ${String(output.kind)}`);
|
|
576
|
+
}
|
|
577
|
+
outputScriptFor(address, field) {
|
|
578
|
+
const script = this.validateAddress(address) ? tryOutputScript(address, this.params.networkInfo) : null;
|
|
579
|
+
if (script === null) {
|
|
580
|
+
throw new ChainError(ChainErrorKinds.InvalidAddress, `${this.name}: ${field} is not a valid address: ${String(address)}`, { chainId: this.chainId, address });
|
|
581
|
+
}
|
|
582
|
+
return script;
|
|
583
|
+
}
|
|
584
|
+
invalidArgument(message, meta = {}) {
|
|
585
|
+
return new ChainError(ChainErrorKinds.InvalidArgument, `${this.name}: ${message}`, {
|
|
586
|
+
chainId: this.chainId,
|
|
587
|
+
...meta,
|
|
588
|
+
});
|
|
589
|
+
}
|
|
461
590
|
async resolveFeeRate(overrideRate, targetBlocks) {
|
|
462
591
|
if (overrideRate !== undefined) {
|
|
463
592
|
if (overrideRate < 1) {
|
|
@@ -494,6 +623,14 @@ export class UtxoChain extends Chain {
|
|
|
494
623
|
return selectCoins(params);
|
|
495
624
|
}
|
|
496
625
|
}
|
|
626
|
+
function tryOutputScript(address, network) {
|
|
627
|
+
try {
|
|
628
|
+
return addressToScriptPubKey(address, network);
|
|
629
|
+
}
|
|
630
|
+
catch {
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
497
634
|
function bigintToNumber(value) {
|
|
498
635
|
if (value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
499
636
|
throw new ChainError(ChainErrorKinds.InvalidArgument, `UTXO amount ${value} exceeds Number.MAX_SAFE_INTEGER`);
|