@chainvue/verus-sdk 0.9.0 → 0.11.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/README.md +6 -0
- package/dist/VerusSDK.d.ts +28 -0
- package/dist/VerusSDK.d.ts.map +1 -1
- package/dist/VerusSDK.js +47 -0
- package/dist/VerusSDK.js.map +1 -1
- package/dist/assemble/assembler.d.ts +66 -0
- package/dist/assemble/assembler.d.ts.map +1 -0
- package/dist/assemble/assembler.js +155 -0
- package/dist/assemble/assembler.js.map +1 -0
- package/dist/assemble/fundedIdentityUpdate.d.ts +35 -0
- package/dist/assemble/fundedIdentityUpdate.d.ts.map +1 -0
- package/dist/assemble/fundedIdentityUpdate.js +114 -0
- package/dist/assemble/fundedIdentityUpdate.js.map +1 -0
- package/dist/bundle.js +29599 -29208
- package/dist/currency/index.d.ts.map +1 -1
- package/dist/currency/index.js +32 -66
- package/dist/currency/index.js.map +1 -1
- package/dist/fork/boundary.d.ts +19 -0
- package/dist/fork/boundary.d.ts.map +1 -0
- package/dist/fork/boundary.js +54 -0
- package/dist/fork/boundary.js.map +1 -0
- package/dist/fork-shims.d.ts +7 -0
- package/dist/identity/index.d.ts +12 -2
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +211 -296
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/public.d.ts +21 -0
- package/dist/identity/public.d.ts.map +1 -0
- package/dist/identity/public.js +38 -0
- package/dist/identity/public.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/message/index.js +7 -7
- package/dist/message/index.js.map +1 -1
- package/dist/offers/identity.d.ts +193 -0
- package/dist/offers/identity.d.ts.map +1 -0
- package/dist/offers/identity.js +314 -0
- package/dist/offers/identity.js.map +1 -0
- package/dist/offers/maker.d.ts +67 -0
- package/dist/offers/maker.d.ts.map +1 -0
- package/dist/offers/maker.js +132 -0
- package/dist/offers/maker.js.map +1 -0
- package/dist/offers/public.d.ts +30 -0
- package/dist/offers/public.d.ts.map +1 -0
- package/dist/offers/public.js +42 -0
- package/dist/offers/public.js.map +1 -0
- package/dist/offers/sign.d.ts +42 -0
- package/dist/offers/sign.d.ts.map +1 -0
- package/dist/offers/sign.js +98 -0
- package/dist/offers/sign.js.map +1 -0
- package/dist/offers/taker.d.ts +33 -0
- package/dist/offers/taker.d.ts.map +1 -0
- package/dist/offers/taker.js +113 -0
- package/dist/offers/taker.js.map +1 -0
- package/dist/signing/index.d.ts +1 -1
- package/dist/signing/index.d.ts.map +1 -1
- package/dist/signing/index.js +10 -10
- package/dist/signing/index.js.map +1 -1
- package/dist/transfer/index.d.ts.map +1 -1
- package/dist/transfer/index.js +40 -62
- package/dist/transfer/index.js.map +1 -1
- package/dist/types/index.d.ts +0 -47
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +6 -11
- package/dist/utils/index.js.map +1 -1
- package/dist/utxo/index.d.ts +7 -0
- package/dist/utxo/index.d.ts.map +1 -1
- package/dist/utxo/index.js +5 -4
- package/dist/utxo/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Network } from '../constants/index.js';
|
|
2
|
+
/** The sighash every offer input is signed with: single output, others open. */
|
|
3
|
+
export declare const SIGHASH_OFFER: number;
|
|
4
|
+
/**
|
|
5
|
+
* Sign one input of an offer transaction with SIGHASH_SINGLE|ANYONECANPAY and
|
|
6
|
+
* install the CryptoCondition fulfillment, leaving the rest of the tx open for a
|
|
7
|
+
* taker to complete.
|
|
8
|
+
*
|
|
9
|
+
* @param unsignedHex the offer tx (input spending the offered CC output, plus
|
|
10
|
+
* the single wanted output at the same index) with an empty
|
|
11
|
+
* scriptSig on `inputIndex`
|
|
12
|
+
* @param prevOutScript the funding output's scriptPubKey (the CC holding the offered asset)
|
|
13
|
+
* @param prevOutValue the funding output's native satoshis (for the sighash)
|
|
14
|
+
*/
|
|
15
|
+
export declare function signOfferInput(unsignedHex: string, inputIndex: number, prevOutScript: Buffer, prevOutValue: bigint, wif: string, network: Network): {
|
|
16
|
+
signedTx: string;
|
|
17
|
+
txid: string;
|
|
18
|
+
};
|
|
19
|
+
/** One input the taker contributes to an offer completion. */
|
|
20
|
+
export interface TakerInput {
|
|
21
|
+
index: number;
|
|
22
|
+
/** The scriptPubKey of the UTXO being spent (P2PKH or a CC reserve output). */
|
|
23
|
+
prevOutScript: Buffer;
|
|
24
|
+
value: bigint;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sign the taker's inputs of an offer completion with SIGHASH_ALL, leaving the
|
|
28
|
+
* maker's SIGHASH_SINGLE|ANYONECANPAY input untouched.
|
|
29
|
+
*
|
|
30
|
+
* Each input is signed manually and its scriptSig set directly: the fork's
|
|
31
|
+
* `TransactionBuilder.build()` rebuilds ALL inputs and cannot preserve a
|
|
32
|
+
* pre-signed CryptoCondition input (it throws "Not enough signatures provided"),
|
|
33
|
+
* so the taker side is assembled at the transaction level. Both plain (P2PKH) and
|
|
34
|
+
* CC (reserve) taker inputs are handled. Because the taker signs the whole
|
|
35
|
+
* transaction (ALL), the maker's already-committed input + output stay valid —
|
|
36
|
+
* SINGLE|ANYONECANPAY does not commit to the inputs and outputs the taker added.
|
|
37
|
+
*/
|
|
38
|
+
export declare function signTakerInputs(txHex: string, takerInputs: TakerInput[], wif: string, network: Network): {
|
|
39
|
+
signedTx: string;
|
|
40
|
+
txid: string;
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=sign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign.d.ts","sourceRoot":"","sources":["../../src/offers/sign.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAIrD,gFAAgF;AAChF,eAAO,MAAM,aAAa,QAAwC,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,GACf;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA6BpC;AAED,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,UAAU,EAAE,EACzB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,GACf;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA4BpC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SIGHASH_OFFER = void 0;
|
|
4
|
+
exports.signOfferInput = signOfferInput;
|
|
5
|
+
exports.signTakerInputs = signTakerInputs;
|
|
6
|
+
/**
|
|
7
|
+
* Signing an offer input.
|
|
8
|
+
*
|
|
9
|
+
* A Verus marketplace offer is one half of an atomic swap: the maker spends the
|
|
10
|
+
* output holding the OFFERED asset and, in the same input, commits with
|
|
11
|
+
* SIGHASH_SINGLE | SIGHASH_ANYONECANPAY (0x83) to exactly one output — the WANTED
|
|
12
|
+
* asset paid to the maker. That sighash lets a taker later ADD their own inputs
|
|
13
|
+
* (the wanted asset) and outputs (receiving the offered asset) and sign their
|
|
14
|
+
* side, without invalidating the maker's signature. The two halves merge into one
|
|
15
|
+
* atomic transaction.
|
|
16
|
+
*
|
|
17
|
+
* The offered asset sits in a CryptoCondition output, so the fulfillment is a
|
|
18
|
+
* smart-transaction signature. The fork's `TransactionBuilder.sign` can sign a CC
|
|
19
|
+
* input but HARDCODES the fulfillment's embedded hashType to SIGHASH_ALL, so it
|
|
20
|
+
* can't emit an offer fulfillment. We build the fulfillment explicitly from the
|
|
21
|
+
* fork's exported primitives instead — byte-identical to the daemon's `makeoffer`
|
|
22
|
+
* (verified: `SmartTransactionSignatures(1, 0x83, …).toChunk()` → `018301…`).
|
|
23
|
+
*/
|
|
24
|
+
const boundary_js_1 = require("../fork/boundary.js");
|
|
25
|
+
const index_js_1 = require("../signing/index.js");
|
|
26
|
+
const index_js_2 = require("../utils/index.js");
|
|
27
|
+
const index_js_3 = require("../utxo/index.js");
|
|
28
|
+
const errors_js_1 = require("../errors.js");
|
|
29
|
+
const SIGHASH_SINGLE = 0x03;
|
|
30
|
+
const SIGHASH_ANYONECANPAY = 0x80;
|
|
31
|
+
/** The sighash every offer input is signed with: single output, others open. */
|
|
32
|
+
exports.SIGHASH_OFFER = SIGHASH_SINGLE | SIGHASH_ANYONECANPAY; // 0x83
|
|
33
|
+
/**
|
|
34
|
+
* Sign one input of an offer transaction with SIGHASH_SINGLE|ANYONECANPAY and
|
|
35
|
+
* install the CryptoCondition fulfillment, leaving the rest of the tx open for a
|
|
36
|
+
* taker to complete.
|
|
37
|
+
*
|
|
38
|
+
* @param unsignedHex the offer tx (input spending the offered CC output, plus
|
|
39
|
+
* the single wanted output at the same index) with an empty
|
|
40
|
+
* scriptSig on `inputIndex`
|
|
41
|
+
* @param prevOutScript the funding output's scriptPubKey (the CC holding the offered asset)
|
|
42
|
+
* @param prevOutValue the funding output's native satoshis (for the sighash)
|
|
43
|
+
*/
|
|
44
|
+
function signOfferInput(unsignedHex, inputIndex, prevOutScript, prevOutValue, wif, network) {
|
|
45
|
+
const verusNetwork = (0, index_js_1.getNetwork)(network === 'testnet');
|
|
46
|
+
const tx = boundary_js_1.Transaction.fromHex(unsignedHex, verusNetwork);
|
|
47
|
+
const input = tx.ins[inputIndex];
|
|
48
|
+
if (!input) {
|
|
49
|
+
throw new errors_js_1.TransactionBuildError(`signOfferInput: no input at index ${inputIndex}`);
|
|
50
|
+
}
|
|
51
|
+
const keyPair = boundary_js_1.ECPair.fromWIF(wif, verusNetwork);
|
|
52
|
+
// isWitness = false: Verus CC inputs are not segwit.
|
|
53
|
+
const sighash = tx.hashForSignatureByNetwork(inputIndex, prevOutScript, (0, index_js_2.toSafeNumber)(prevOutValue), exports.SIGHASH_OFFER, false);
|
|
54
|
+
const signature = keyPair.sign(sighash);
|
|
55
|
+
// The compact signature is [recovery-byte, r(32), s(32)]; the CC fulfillment
|
|
56
|
+
// carries the 64-byte r||s (the recovery byte is dropped).
|
|
57
|
+
const fulfillment = new boundary_js_1.SmartTransactionSignatures(1, exports.SIGHASH_OFFER, [
|
|
58
|
+
new boundary_js_1.SmartTransactionSignature(1, 1, keyPair.getPublicKeyBuffer(), signature.toCompact().slice(1)),
|
|
59
|
+
]).toChunk();
|
|
60
|
+
// The scriptSig pushes the fulfillment as one data element (OP_PUSHDATA1 …),
|
|
61
|
+
// matching the daemon's `4c67 0183…` — toChunk() is the raw bytes, not the push.
|
|
62
|
+
input.script = boundary_js_1.script.compile([fulfillment]);
|
|
63
|
+
return { signedTx: tx.toHex(), txid: tx.getId() };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Sign the taker's inputs of an offer completion with SIGHASH_ALL, leaving the
|
|
67
|
+
* maker's SIGHASH_SINGLE|ANYONECANPAY input untouched.
|
|
68
|
+
*
|
|
69
|
+
* Each input is signed manually and its scriptSig set directly: the fork's
|
|
70
|
+
* `TransactionBuilder.build()` rebuilds ALL inputs and cannot preserve a
|
|
71
|
+
* pre-signed CryptoCondition input (it throws "Not enough signatures provided"),
|
|
72
|
+
* so the taker side is assembled at the transaction level. Both plain (P2PKH) and
|
|
73
|
+
* CC (reserve) taker inputs are handled. Because the taker signs the whole
|
|
74
|
+
* transaction (ALL), the maker's already-committed input + output stay valid —
|
|
75
|
+
* SINGLE|ANYONECANPAY does not commit to the inputs and outputs the taker added.
|
|
76
|
+
*/
|
|
77
|
+
function signTakerInputs(txHex, takerInputs, wif, network) {
|
|
78
|
+
const verusNetwork = (0, index_js_1.getNetwork)(network === 'testnet');
|
|
79
|
+
const tx = boundary_js_1.Transaction.fromHex(txHex, verusNetwork);
|
|
80
|
+
const keyPair = boundary_js_1.ECPair.fromWIF(wif, verusNetwork);
|
|
81
|
+
for (const { index, prevOutScript, value } of takerInputs) {
|
|
82
|
+
const input = tx.ins[index];
|
|
83
|
+
if (!input) {
|
|
84
|
+
throw new errors_js_1.TransactionBuildError(`signTakerInputs: no input at index ${index}`);
|
|
85
|
+
}
|
|
86
|
+
const sighash = tx.hashForSignatureByNetwork(index, prevOutScript, (0, index_js_2.toSafeNumber)(value), boundary_js_1.Transaction.SIGHASH_ALL, false);
|
|
87
|
+
const signature = keyPair.sign(sighash);
|
|
88
|
+
input.script = (0, index_js_3.isSmartTransactionScript)(prevOutScript)
|
|
89
|
+
? boundary_js_1.script.compile([
|
|
90
|
+
new boundary_js_1.SmartTransactionSignatures(1, boundary_js_1.Transaction.SIGHASH_ALL, [
|
|
91
|
+
new boundary_js_1.SmartTransactionSignature(1, 1, keyPair.getPublicKeyBuffer(), signature.toCompact().slice(1)),
|
|
92
|
+
]).toChunk(),
|
|
93
|
+
])
|
|
94
|
+
: boundary_js_1.script.compile([signature.toScriptSignature(boundary_js_1.Transaction.SIGHASH_ALL), keyPair.getPublicKeyBuffer()]);
|
|
95
|
+
}
|
|
96
|
+
return { signedTx: tx.toHex(), txid: tx.getId() };
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=sign.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sign.js","sourceRoot":"","sources":["../../src/offers/sign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Network } from '../constants/index.js';
|
|
2
|
+
import type { Utxo } from '../types/index.js';
|
|
3
|
+
export interface CompleteOfferParams {
|
|
4
|
+
/** The maker's half-signed offer transaction (from buildOffer). */
|
|
5
|
+
offerTx: string;
|
|
6
|
+
/** What the maker offers (the value in the commitment input 0), native or token. */
|
|
7
|
+
offered: {
|
|
8
|
+
currency: string;
|
|
9
|
+
amount: bigint;
|
|
10
|
+
};
|
|
11
|
+
/** What the taker must pay (the maker's wanted output 0), native or token. */
|
|
12
|
+
want: {
|
|
13
|
+
currency: string;
|
|
14
|
+
amount: bigint;
|
|
15
|
+
};
|
|
16
|
+
/** The taker's UTXOs — must hold the wanted currency + native for the fee. */
|
|
17
|
+
takerUtxos: Utxo[];
|
|
18
|
+
/** Where the taker receives the offered asset. */
|
|
19
|
+
takerAddress: string;
|
|
20
|
+
changeAddress: string;
|
|
21
|
+
wif: string;
|
|
22
|
+
}
|
|
23
|
+
export interface CompleteOfferResult {
|
|
24
|
+
swapTx: string;
|
|
25
|
+
txid: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Complete an offer: take the maker's half-signed offer, pay the wanted asset,
|
|
29
|
+
* receive the offered asset, and sign the taker's side. The offered and wanted
|
|
30
|
+
* assets may each be the native coin or a token (all four combinations).
|
|
31
|
+
*/
|
|
32
|
+
export declare function completeOffer(params: CompleteOfferParams, network: Network): CompleteOfferResult;
|
|
33
|
+
//# sourceMappingURL=taker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taker.d.ts","sourceRoot":"","sources":["../../src/offers/taker.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,8EAA8E;IAC9E,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,8EAA8E;IAC9E,UAAU,EAAE,IAAI,EAAE,CAAC;IACnB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AASD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,GAAG,mBAAmB,CA4FhG"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.completeOffer = completeOffer;
|
|
4
|
+
/**
|
|
5
|
+
* Completing (taking) a marketplace offer, offline.
|
|
6
|
+
*
|
|
7
|
+
* The taker receives the maker's half-signed offer (`buildOffer` output): input 0
|
|
8
|
+
* spends the offered asset's commitment and output 0 is the WANTED asset paid to
|
|
9
|
+
* the maker, both committed under the maker's SIGHASH_SINGLE|ANYONECANPAY. The
|
|
10
|
+
* taker adds their side and signs it, and the two halves become one atomic swap:
|
|
11
|
+
*
|
|
12
|
+
* - keep the maker's input 0 and output 0 untouched (index 0);
|
|
13
|
+
* - append output 1: the OFFERED asset paid to the taker;
|
|
14
|
+
* - append the taker's inputs (the wanted currency to pay output 0, plus native
|
|
15
|
+
* for the miner fee) and output 2: the taker's change;
|
|
16
|
+
* - sign only the taker's inputs (SIGHASH_ALL) — the maker's 0x83 stays valid.
|
|
17
|
+
*
|
|
18
|
+
* The taker tx does NOT byte-match the daemon (each wallet selects its own UTXOs);
|
|
19
|
+
* correctness is enforced by value conservation and proven by the live round-trip.
|
|
20
|
+
*
|
|
21
|
+
* This covers all four currency combinations: the offered and wanted assets may
|
|
22
|
+
* each be the native coin or a token. The offered asset flows self-contained from
|
|
23
|
+
* input 0 (the commitment) to output 1 (the taker); the taker's own UTXOs fund
|
|
24
|
+
* only the wanted asset (paid to output 0) plus the miner fee.
|
|
25
|
+
*/
|
|
26
|
+
const boundary_js_1 = require("../fork/boundary.js");
|
|
27
|
+
const index_js_1 = require("../utxo/index.js");
|
|
28
|
+
const index_js_2 = require("../signing/index.js");
|
|
29
|
+
const index_js_3 = require("../identity/index.js");
|
|
30
|
+
const sign_js_1 = require("./sign.js");
|
|
31
|
+
const index_js_4 = require("../utils/index.js");
|
|
32
|
+
const brands_js_1 = require("../core/brands.js");
|
|
33
|
+
const index_js_5 = require("../constants/index.js");
|
|
34
|
+
const errors_js_1 = require("../errors.js");
|
|
35
|
+
/** A native payment script to an R-address (P2PKH) or i-address (pay-to-identity). */
|
|
36
|
+
function nativePaymentScript(address) {
|
|
37
|
+
return address.startsWith('i')
|
|
38
|
+
? (0, index_js_3.identityPaymentScript)((0, brands_js_1.parseIAddress)(address, 'address'))
|
|
39
|
+
: (0, index_js_4.addressToScriptPubKey)(address);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Complete an offer: take the maker's half-signed offer, pay the wanted asset,
|
|
43
|
+
* receive the offered asset, and sign the taker's side. The offered and wanted
|
|
44
|
+
* assets may each be the native coin or a token (all four combinations).
|
|
45
|
+
*/
|
|
46
|
+
function completeOffer(params, network) {
|
|
47
|
+
const verusNetwork = (0, index_js_2.getNetwork)(network === 'testnet');
|
|
48
|
+
const systemId = index_js_5.NETWORK_CONFIG[network].chainId;
|
|
49
|
+
const offeringNative = params.offered.currency === systemId;
|
|
50
|
+
const wantingNative = params.want.currency === systemId;
|
|
51
|
+
if (params.offered.amount <= 0n || params.want.amount <= 0n) {
|
|
52
|
+
throw new errors_js_1.TransactionBuildError('completeOffer: offered.amount and want.amount must be positive');
|
|
53
|
+
}
|
|
54
|
+
const tx = boundary_js_1.Transaction.fromHex(params.offerTx, verusNetwork);
|
|
55
|
+
if (tx.ins.length !== 1 || tx.outs.length !== 1) {
|
|
56
|
+
throw new errors_js_1.TransactionBuildError('completeOffer: expected a maker offer partial (1 input, 1 output)');
|
|
57
|
+
}
|
|
58
|
+
// The native value on the maker's commitment input (input 0): the offered
|
|
59
|
+
// amount if the offer is native, else 0 (a token commitment carries 0 native).
|
|
60
|
+
const commitmentNative = offeringNative ? params.offered.amount : 0n;
|
|
61
|
+
// Output 1: the OFFERED asset paid to the taker — a plain payment for the
|
|
62
|
+
// native coin, a reserve output (0 native) for a token. The offered asset
|
|
63
|
+
// flows from input 0 to here, self-contained.
|
|
64
|
+
if (offeringNative) {
|
|
65
|
+
tx.addOutput(nativePaymentScript(params.takerAddress), (0, index_js_4.toSafeNumber)(params.offered.amount));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const offeredOut = (0, index_js_3.buildTokenChangeOutput)((0, brands_js_1.parseAddress)(params.takerAddress, 'takerAddress'), new Map([[params.offered.currency, params.offered.amount]]));
|
|
69
|
+
tx.addOutput(offeredOut.script, 0);
|
|
70
|
+
}
|
|
71
|
+
// The taker's own UTXOs fund only the WANTED asset (paid to output 0) plus the
|
|
72
|
+
// miner fee. When the wanted asset is a token it is a required currency; when
|
|
73
|
+
// native it is required native on top of the fee. numOutputs=3 (wanted, offered,
|
|
74
|
+
// change); +150 bytes accounts for the maker's input, which selectUtxos can't see.
|
|
75
|
+
const wantedTokenReq = wantingNative
|
|
76
|
+
? new Map()
|
|
77
|
+
: new Map([[params.want.currency, params.want.amount]]);
|
|
78
|
+
const requiredNative = wantingNative ? params.want.amount : 0n;
|
|
79
|
+
const selection = (0, index_js_1.selectUtxos)(params.takerUtxos, requiredNative, wantedTokenReq, 3, systemId, undefined, true, 150);
|
|
80
|
+
const takerInputs = [];
|
|
81
|
+
for (const u of selection.selected) {
|
|
82
|
+
const idx = tx.addInput(Buffer.from(u.txid, 'hex').reverse(), u.outputIndex, 0xffffffff);
|
|
83
|
+
takerInputs.push({ index: idx, prevOutScript: Buffer.from(u.script, 'hex'), value: u.satoshis });
|
|
84
|
+
}
|
|
85
|
+
// Output 2: taker change — the wanted-currency change (with native change
|
|
86
|
+
// bundled onto the reserve output), or plain native change if no token remains.
|
|
87
|
+
const hasTokenChange = selection.currencyChanges.size > 0;
|
|
88
|
+
if (hasTokenChange || selection.nativeChange > 0n) {
|
|
89
|
+
if (hasTokenChange) {
|
|
90
|
+
const change = (0, index_js_3.buildTokenChangeOutput)((0, brands_js_1.parseAddress)(params.changeAddress, 'changeAddress'), selection.currencyChanges);
|
|
91
|
+
tx.addOutput(change.script, (0, index_js_4.toSafeNumber)(selection.nativeChange));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
tx.addOutput(nativePaymentScript(params.changeAddress), (0, index_js_4.toSafeNumber)(selection.nativeChange));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Token conservation over the taker's own inputs: they provide the wanted token
|
|
98
|
+
// (paid to output 0) plus change. The offered token (input 0 → output 1) does
|
|
99
|
+
// not pass through taker inputs, so it is not asserted here — it is balanced by
|
|
100
|
+
// construction (the commitment carries exactly `offered.amount`).
|
|
101
|
+
(0, index_js_1.assertTokenConservation)(selection.selected, wantedTokenReq, selection.currencyChanges, systemId, 'takeOffer');
|
|
102
|
+
// Native conservation across the whole swap. allNativeIn = the commitment's
|
|
103
|
+
// native (funds the offered-native output when offering native, else 0) + the
|
|
104
|
+
// taker's native inputs (fund the wanted-native output when wanting native, the
|
|
105
|
+
// fee, and native change). This identity reduces to exactly `fee` in every
|
|
106
|
+
// combination.
|
|
107
|
+
const takerNativeIn = selection.selected.reduce((s, u) => s + u.satoshis, 0n);
|
|
108
|
+
const allInputsNative = commitmentNative + takerNativeIn;
|
|
109
|
+
(0, index_js_2.assertNativeConservation)([{ satoshis: allInputsNative }], tx.outs, selection.fee, 'takeOffer');
|
|
110
|
+
const { signedTx, txid } = (0, sign_js_1.signTakerInputs)(tx.toHex(), takerInputs, params.wif, network);
|
|
111
|
+
return { swapTx: signedTx, txid };
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=taker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taker.js","sourceRoot":"","sources":["../../src/offers/taker.ts"],"names":[],"mappings":"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"}
|
package/dist/signing/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - Smart transaction signing (CryptoConditions/OptCCParams)
|
|
7
7
|
* - Mixed transactions (P2PKH inputs + smart tx inputs)
|
|
8
8
|
*/
|
|
9
|
-
import { TransactionBuilder, networks } from '
|
|
9
|
+
import { TransactionBuilder, networks } from '../fork/boundary.js';
|
|
10
10
|
import type { Utxo } from '../types/index.js';
|
|
11
11
|
/** Network to use for signing */
|
|
12
12
|
export type VerusNetwork = typeof networks.verus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,kBAAkB,EAClB,QAAQ,EAET,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAGL,kBAAkB,EAClB,QAAQ,EAET,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAO9C,iCAAiC;AACjC,MAAM,MAAM,YAAY,GAAG,OAAO,QAAQ,CAAC,KAAK,CAAC;AAEjD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAsB5E;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,aAAa,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,MAAM,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EACxC,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,MAAM,GACZ,IAAI,CASN;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,OAAe,GAAG,YAAY,CAEjE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,GAAE,YAA6B,EACtC,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA4BpC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EAAE,EAAE,EAChB,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,GAAE,YAA6B,GACrC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAoBpC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,MAAU,EACnB,cAAc,GAAE,MAAyB,GACxC,YAAY,CAAC,OAAO,kBAAkB,CAAC,CASzC;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,IAAI,EAAE,GACf;IACD,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IAKjB,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,CAiBA"}
|
package/dist/signing/index.js
CHANGED
|
@@ -15,11 +15,11 @@ exports.signTransactionSmart = signTransactionSmart;
|
|
|
15
15
|
exports.signTransactionMultiKey = signTransactionMultiKey;
|
|
16
16
|
exports.createTransactionBuilder = createTransactionBuilder;
|
|
17
17
|
exports.validateFundedTransaction = validateFundedTransaction;
|
|
18
|
-
const
|
|
18
|
+
const boundary_js_1 = require("../fork/boundary.js");
|
|
19
19
|
const index_js_1 = require("../constants/index.js");
|
|
20
20
|
const index_js_2 = require("../utils/index.js");
|
|
21
21
|
const errors_js_1 = require("../errors.js");
|
|
22
|
-
const { getFundedTxBuilder, validateFundedCurrencyTransfer } =
|
|
22
|
+
const { getFundedTxBuilder, validateFundedCurrencyTransfer } = boundary_js_1.smarttxs;
|
|
23
23
|
/**
|
|
24
24
|
* Resolve the transaction expiry height, requiring an explicit choice.
|
|
25
25
|
*
|
|
@@ -66,7 +66,7 @@ function assertNativeConservation(inputUtxos, txOuts, expectedFeeSats, label) {
|
|
|
66
66
|
* Get the Verus network config
|
|
67
67
|
*/
|
|
68
68
|
function getNetwork(testnet = false) {
|
|
69
|
-
return testnet ?
|
|
69
|
+
return testnet ? boundary_js_1.networks.verustest : boundary_js_1.networks.verus;
|
|
70
70
|
}
|
|
71
71
|
/**
|
|
72
72
|
* Sign a pre-built transaction hex with a single WIF key
|
|
@@ -86,8 +86,8 @@ function getNetwork(testnet = false) {
|
|
|
86
86
|
* bigint conservation itself (assertNativeConservation) BEFORE calling this;
|
|
87
87
|
* this cap is only a coarse secondary sanity bound on small-input transactions.
|
|
88
88
|
*/
|
|
89
|
-
function signTransactionSmart(txHex, wif, utxos, network =
|
|
90
|
-
const keyPair =
|
|
89
|
+
function signTransactionSmart(txHex, wif, utxos, network = boundary_js_1.networks.verus, maxFeeSats) {
|
|
90
|
+
const keyPair = boundary_js_1.ECPair.fromWIF(wif, network);
|
|
91
91
|
const prevOutScripts = utxos.map((u) => Buffer.from(u.script, 'hex'));
|
|
92
92
|
const txb = getFundedTxBuilder(txHex, network, prevOutScripts);
|
|
93
93
|
if (maxFeeSats !== undefined) {
|
|
@@ -103,7 +103,7 @@ function signTransactionSmart(txHex, wif, utxos, network = utxo_lib_1.networks.v
|
|
|
103
103
|
// value to Bitcoin's SATOSHI_MAX (21e6 * 1e8). A single input above ~21M
|
|
104
104
|
// native coins would throw inside the fork; this is far above any realistic
|
|
105
105
|
// VRSC UTXO value, and toSafeNumber already caps at 2^53-1 before this point.
|
|
106
|
-
txb.sign(i, keyPair, null,
|
|
106
|
+
txb.sign(i, keyPair, null, boundary_js_1.Transaction.SIGHASH_ALL, (0, index_js_2.toSafeNumber)(utxo.satoshis));
|
|
107
107
|
}
|
|
108
108
|
const signedTx = txb.build();
|
|
109
109
|
return {
|
|
@@ -114,7 +114,7 @@ function signTransactionSmart(txHex, wif, utxos, network = utxo_lib_1.networks.v
|
|
|
114
114
|
/**
|
|
115
115
|
* Sign a transaction with multiple keys (for multi-signature or mixed-authority inputs)
|
|
116
116
|
*/
|
|
117
|
-
function signTransactionMultiKey(txHex, keys, utxos, network =
|
|
117
|
+
function signTransactionMultiKey(txHex, keys, utxos, network = boundary_js_1.networks.verus) {
|
|
118
118
|
const prevOutScripts = utxos.map((u) => Buffer.from(u.script, 'hex'));
|
|
119
119
|
const txb = getFundedTxBuilder(txHex, network, prevOutScripts);
|
|
120
120
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -125,8 +125,8 @@ function signTransactionMultiKey(txHex, keys, utxos, network = utxo_lib_1.networ
|
|
|
125
125
|
for (const wif of inputKeys) {
|
|
126
126
|
if (!wif)
|
|
127
127
|
continue;
|
|
128
|
-
const keyPair =
|
|
129
|
-
txb.sign(i, keyPair, null,
|
|
128
|
+
const keyPair = boundary_js_1.ECPair.fromWIF(wif, network);
|
|
129
|
+
txb.sign(i, keyPair, null, boundary_js_1.Transaction.SIGHASH_ALL, (0, index_js_2.toSafeNumber)(utxo.satoshis));
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
const signedTx = txb.build();
|
|
@@ -139,7 +139,7 @@ function signTransactionMultiKey(txHex, keys, utxos, network = utxo_lib_1.networ
|
|
|
139
139
|
* Create a new TransactionBuilder for manual transaction construction
|
|
140
140
|
*/
|
|
141
141
|
function createTransactionBuilder(network, expiryHeight, version = 4, versionGroupId = index_js_1.VERSION_GROUP_ID) {
|
|
142
|
-
const txb = new
|
|
142
|
+
const txb = new boundary_js_1.TransactionBuilder(network);
|
|
143
143
|
txb.setVersion(version);
|
|
144
144
|
// Route through resolveExpiryHeight so this low-level builder can't silently
|
|
145
145
|
// produce a never-expiring transaction: expiryHeight is required (0 must be an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signing/index.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AA6BH,kDAsBC;AASD,4DAcC;AAKD,gCAEC;AAoBD,oDAkCC;AAKD,0DAyBC;AAKD,4DAcC;AAKD,8DAoCC;AA/ND,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/signing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transfer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transfer/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAYH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAOrD,OAAO,KAAK,EAEV,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAkG3B;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,OAAO,GACf,kBAAkB,CA4GpB;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,GACf,kBAAkB,CAepB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,OAAO,GACf,kBAAkB,CAcpB;AAED;;GAEG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,OAAO,GACf,kBAAkB,CAgBpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE,OAAO,GACf,cAAc,CAwEhB"}
|
package/dist/transfer/index.js
CHANGED
|
@@ -19,25 +19,23 @@ exports.transfer = transfer;
|
|
|
19
19
|
exports.transferToken = transferToken;
|
|
20
20
|
exports.convert = convert;
|
|
21
21
|
exports.buildAndSign = buildAndSign;
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const boundary_js_1 = require("../fork/boundary.js");
|
|
23
|
+
const boundary_js_2 = require("../fork/boundary.js");
|
|
24
24
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
25
25
|
const bs58check_1 = __importDefault(require("bs58check"));
|
|
26
26
|
const index_js_1 = require("../constants/index.js");
|
|
27
27
|
const index_js_2 = require("../signing/index.js");
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const brands_js_1 = require("../core/brands.js");
|
|
31
|
-
const index_js_5 = require("../utils/index.js");
|
|
28
|
+
const assembler_js_1 = require("../assemble/assembler.js");
|
|
29
|
+
const index_js_3 = require("../utils/index.js");
|
|
32
30
|
const errors_js_1 = require("../errors.js");
|
|
33
|
-
const
|
|
34
|
-
const { createUnfundedCurrencyTransfer } =
|
|
31
|
+
const index_js_4 = require("../keys/index.js");
|
|
32
|
+
const { createUnfundedCurrencyTransfer } = boundary_js_1.smarttxs;
|
|
35
33
|
/** Validate common transfer parameters */
|
|
36
34
|
function validateTransferInputs(wif, utxos) {
|
|
37
35
|
if (!wif || typeof wif !== 'string') {
|
|
38
36
|
throw new errors_js_1.InvalidWifError('WIF is required');
|
|
39
37
|
}
|
|
40
|
-
const wifCheck = (0,
|
|
38
|
+
const wifCheck = (0, index_js_4.validateWif)(wif);
|
|
41
39
|
if (!wifCheck.valid) {
|
|
42
40
|
throw new errors_js_1.InvalidWifError(wifCheck.error);
|
|
43
41
|
}
|
|
@@ -68,7 +66,7 @@ function parseAddress(address, addressType) {
|
|
|
68
66
|
let destinationBytes;
|
|
69
67
|
switch (addressType) {
|
|
70
68
|
case 'PKH': {
|
|
71
|
-
type =
|
|
69
|
+
type = boundary_js_2.DEST_PKH;
|
|
72
70
|
const decoded = decodeBase58Address(address);
|
|
73
71
|
// Fail closed: the version byte must be the R-address (P2PKH) prefix.
|
|
74
72
|
// Without this check an i-address (0x66) passed on the PKH path would be
|
|
@@ -81,7 +79,7 @@ function parseAddress(address, addressType) {
|
|
|
81
79
|
break;
|
|
82
80
|
}
|
|
83
81
|
case 'ID': {
|
|
84
|
-
type =
|
|
82
|
+
type = boundary_js_2.DEST_ID;
|
|
85
83
|
const decoded = decodeBase58Address(address);
|
|
86
84
|
// Fail closed: the version byte must be the identity i-address prefix, so
|
|
87
85
|
// an R-address can never be misrouted onto the identity-destination path.
|
|
@@ -92,7 +90,7 @@ function parseAddress(address, addressType) {
|
|
|
92
90
|
break;
|
|
93
91
|
}
|
|
94
92
|
case 'ETH': {
|
|
95
|
-
type =
|
|
93
|
+
type = boundary_js_2.DEST_ETH;
|
|
96
94
|
const addr = address.startsWith('0x') ? address.substring(2) : address;
|
|
97
95
|
// Validate the hex explicitly: Buffer.from(_, 'hex') truncates at the
|
|
98
96
|
// first non-hex character, so a malformed address could otherwise pass the
|
|
@@ -109,7 +107,7 @@ function parseAddress(address, addressType) {
|
|
|
109
107
|
default:
|
|
110
108
|
throw new errors_js_1.InvalidAddressError(address, `Unsupported address type: ${addressType}`);
|
|
111
109
|
}
|
|
112
|
-
return new
|
|
110
|
+
return new boundary_js_2.TransferDestination({
|
|
113
111
|
type,
|
|
114
112
|
destination_bytes: destinationBytes,
|
|
115
113
|
fees: new bn_js_1.default(0, 10),
|
|
@@ -152,11 +150,7 @@ function sendCurrency(params, network) {
|
|
|
152
150
|
...(out.preconvert !== undefined ? { preconvert: out.preconvert } : {}),
|
|
153
151
|
}));
|
|
154
152
|
const unfundedTxHex = createUnfundedCurrencyTransfer(systemId, txOutputs, verusNetwork, expiryHeight);
|
|
155
|
-
const unfundedTx =
|
|
156
|
-
let requiredNative = 0n;
|
|
157
|
-
for (const out of unfundedTx.outs) {
|
|
158
|
-
requiredNative += BigInt(out.value);
|
|
159
|
-
}
|
|
153
|
+
const unfundedTx = boundary_js_1.Transaction.fromHex(unfundedTxHex, verusNetwork);
|
|
160
154
|
const hasSmartOutputs = params.outputs.some((o) => o.convertTo || o.exportTo || o.via || o.currency !== systemId);
|
|
161
155
|
const requiredCurrencies = new Map();
|
|
162
156
|
for (const out of params.outputs) {
|
|
@@ -170,54 +164,38 @@ function sendCurrency(params, network) {
|
|
|
170
164
|
requiredCurrencies.set(out.feeCurrency, (requiredCurrencies.get(out.feeCurrency) || 0n) + out.feeSatoshis);
|
|
171
165
|
}
|
|
172
166
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// byte-identical to the chain's own pay-to-identity outputs.
|
|
192
|
-
if (params.changeAddress.startsWith('i')) {
|
|
193
|
-
txb.addOutput((0, index_js_4.identityPaymentScript)((0, brands_js_1.parseIAddress)(params.changeAddress, 'changeAddress')), (0, index_js_5.toSafeNumber)(selection.nativeChange));
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
txb.addOutput(params.changeAddress, (0, index_js_5.toSafeNumber)(selection.nativeChange));
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
const unsignedTx = txb.buildIncomplete();
|
|
200
|
-
// Independent native value conservation: assembled native fee (inputs minus
|
|
201
|
-
// outputs) must equal the intended selection fee. validateFundedTransaction
|
|
202
|
-
// below reports fees but never bounds them, and the fork's absurd-fee guard is
|
|
203
|
-
// blind for inputs > 2^32 sats — so this bigint check is the only enforced
|
|
204
|
-
// backstop against a change-accounting slip silently burning native value.
|
|
205
|
-
(0, index_js_2.assertNativeConservation)(selection.selected, unsignedTx.outs, selection.fee, 'sendCurrency');
|
|
206
|
-
const { signedTx, txid } = (0, index_js_2.signTransactionSmart)(unsignedTx.toHex(), params.wif, selection.selected, verusNetwork);
|
|
167
|
+
// The fork built the output scripts (createUnfundedCurrencyTransfer); the
|
|
168
|
+
// assembler funds them (native summed from the outputs, tokens from the
|
|
169
|
+
// explicit requiredCurrencies since the opaque scripts can't be read back),
|
|
170
|
+
// emits change the fork's way (a token-change output plus a distinct native
|
|
171
|
+
// one), and enforces native + token conservation.
|
|
172
|
+
const assembled = (0, assembler_js_1.assembleAndSign)({
|
|
173
|
+
network,
|
|
174
|
+
wif: params.wif,
|
|
175
|
+
expiryHeight: params.expiryHeight,
|
|
176
|
+
funding: params.utxos,
|
|
177
|
+
outputs: unfundedTx.outs.map((o) => ({ script: o.script, nativeSat: BigInt(o.value) })),
|
|
178
|
+
changeAddress: params.changeAddress,
|
|
179
|
+
hasSmartOutputs,
|
|
180
|
+
requiredCurrencies,
|
|
181
|
+
changeStrategy: 'separate',
|
|
182
|
+
fee: { policy: 'estimate' },
|
|
183
|
+
label: 'sendCurrency',
|
|
184
|
+
});
|
|
207
185
|
// Defense in depth: utxo-lib's own funded-transfer validator re-checks the
|
|
208
186
|
// assembled tx against the unfunded intent (value conservation per
|
|
209
187
|
// currency, change to the declared change address, fee sanity). A
|
|
210
188
|
// selection/change bug here means money — refuse to hand out the hex.
|
|
211
|
-
const validation = (0, index_js_2.validateFundedTransaction)(systemId, signedTx, unfundedTxHex, params.changeAddress, verusNetwork,
|
|
189
|
+
const validation = (0, index_js_2.validateFundedTransaction)(systemId, assembled.signedTx, unfundedTxHex, params.changeAddress, verusNetwork, assembled.selected);
|
|
212
190
|
if (!validation.valid) {
|
|
213
191
|
throw new errors_js_1.TransactionBuildError(`funded transaction failed validation: ${validation.message ?? 'no reason given'}`);
|
|
214
192
|
}
|
|
215
193
|
return {
|
|
216
|
-
signedTx,
|
|
217
|
-
txid,
|
|
218
|
-
fee:
|
|
219
|
-
inputsUsed:
|
|
220
|
-
nativeChange:
|
|
194
|
+
signedTx: assembled.signedTx,
|
|
195
|
+
txid: assembled.txid,
|
|
196
|
+
fee: assembled.fee,
|
|
197
|
+
inputsUsed: assembled.inputsUsed,
|
|
198
|
+
nativeChange: assembled.nativeChange,
|
|
221
199
|
};
|
|
222
200
|
}
|
|
223
201
|
/**
|
|
@@ -284,7 +262,7 @@ function buildAndSign(params, network) {
|
|
|
284
262
|
if (!params.wif || typeof params.wif !== 'string') {
|
|
285
263
|
throw new errors_js_1.InvalidWifError('WIF is required');
|
|
286
264
|
}
|
|
287
|
-
const wifCheck = (0,
|
|
265
|
+
const wifCheck = (0, index_js_4.validateWif)(params.wif);
|
|
288
266
|
if (!wifCheck.valid) {
|
|
289
267
|
throw new errors_js_1.InvalidWifError(wifCheck.error);
|
|
290
268
|
}
|
|
@@ -308,7 +286,7 @@ function buildAndSign(params, network) {
|
|
|
308
286
|
if (fee !== impliedFee) {
|
|
309
287
|
throw new errors_js_1.TransactionBuildError(`declared fee ${fee} does not match inputs minus outputs (${impliedFee}) — the difference would be burned`);
|
|
310
288
|
}
|
|
311
|
-
const txb = new
|
|
289
|
+
const txb = new boundary_js_1.TransactionBuilder(verusNetwork);
|
|
312
290
|
txb.setVersion(4);
|
|
313
291
|
txb.setExpiryHeight((0, index_js_2.resolveExpiryHeight)(params.expiryHeight));
|
|
314
292
|
txb.setVersionGroupId(index_js_1.VERSION_GROUP_ID);
|
|
@@ -316,8 +294,8 @@ function buildAndSign(params, network) {
|
|
|
316
294
|
txb.addInput(Buffer.from(inp.txid, 'hex').reverse(), inp.vout, 0xffffffff, Buffer.from(inp.scriptPubKey, 'hex'));
|
|
317
295
|
}
|
|
318
296
|
for (const out of params.outputs) {
|
|
319
|
-
const script = (0,
|
|
320
|
-
txb.addOutput(script, (0,
|
|
297
|
+
const script = (0, index_js_3.addressToScriptPubKey)(out.address);
|
|
298
|
+
txb.addOutput(script, (0, index_js_3.toSafeNumber)(out.amount));
|
|
321
299
|
}
|
|
322
300
|
const unsignedTx = txb.buildIncomplete();
|
|
323
301
|
const utxos = params.inputs.map((i) => ({
|