-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathsignTransaction-p2sh.js
141 lines (113 loc) · 3.49 KB
/
signTransaction-p2sh.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
'use strict';
const Logger = require('blgr');
const {Amount, Address, Coin, MTX, Script} = require('hsd');
const rules = require('hsd/lib/covenants/rules');
const util = require('../test/utils/fund');
const {HID, LedgerHSD, LedgerInput} = require('../lib/hsd-ledger');
const {Device} = HID;
(async () => {
// Create logger.
const logger = new Logger({
console: true,
level: 'info'
});
// Get first device available and
// set optional properties.
const device = await Device.requestDevice();
device.set({
timeout: 1000 * 60 * 5, // optional (default is 5mins)
logger: logger // optional
});
// Create ledger client object.
const ledger = new LedgerHSD({
device: device,
network: 'regtest',
logger: logger // optional
});
// Open logger and device.
await logger.open();
await device.open();
const signers = [
{ acct: 0, path: 'm/44\'/5355\'/0\'/0/0' },
{ acct: 1, path: 'm/44\'/5355\'/1\'/0/0' },
{ acct: 2, path: 'm/44\'/5355\'/2\'/0/0' }
];
logger.info('Constructing multisig address.');
for (const signer of signers)
signer.pub = await ledger.getPublicKey(signer.path);
const [m, n] = [2, signers.length];
const redeem = Script.fromMultisig(m, n, [
signers[0].pub,
signers[1].pub,
signers[2].pub
]);
const address = Address.fromScript(redeem);
const changeAddress = Address.fromScript(redeem);
logger.info('Constructing spend transaction.');
const {coins, txs} = await util.fundAddress(address, 1);
const mtx = new MTX();
const value = Amount.fromCoins(1).toValue();
mtx.addOutput({ address, value });
await mtx.fund(coins, { changeAddress });
const ledgerInputs = [];
const coin = Coin.fromTX(txs[0], 0, -1);
ledgerInputs.push(new LedgerInput({
path: signers[0].path,
coin,
input: mtx.inputs[0],
index: 0,
publicKey: signers[0].pub,
redeem,
type: Script.hashType.ALL
}));
ledgerInputs.push(new LedgerInput({
path: signers[1].path,
coin,
input: mtx.inputs[0],
index: 0,
publicKey: signers[1].pub,
redeem,
type: Script.hashType.ALL
}));
let fees = 0;
for (let i = 0; i < mtx.inputs.length; i++) {
const input = mtx.inputs[i];
const coin = mtx.view.getCoinFor(input);
fees += coin.value;
}
logger.info(`Confirm details for TXID: ${mtx.txid()}`);
logger.info('');
for (let i = 0; i < mtx.outputs.length; i++) {
const output = mtx.outputs[i];
fees -= output.value;
logger.info(`Output #${i+1}`);
logger.info(`Covenant: ${rules.typesByVal[output.covenant.type]}`);
logger.info(`Value: ${output.value/1e6}`);
logger.info(`Address: ${output.address.toString('regtest')}`);
logger.info('');
}
logger.info(`Fees: ${fees / 1e6}`);
logger.info('');
const part = await ledger.signTransaction(mtx, {
inputs: [ledgerInputs[0]]
});
logger.info(`Confirm details for TXID: ${mtx.txid()}`);
for (let i = 0; i < mtx.outputs.length; i++) {
const output = mtx.outputs[i];
logger.info(`Output #${i+1}`);
logger.info(`Covenant: ${rules.typesByVal[output.covenant.type]}`);
logger.info(`Value: ${output.value/1e6}`);
logger.info(`Address: ${output.address.toString('regtest')}`);
logger.info('');
}
logger.info(`Fees: ${fees/1e6}`);
const full = await ledger.signTransaction(part, {
inputs: [ledgerInputs[1]]
});
logger.info(`Result of TX.verify(): ${full.verify()}.`);
await device.close();
await logger.close();
})().catch((e) => {
console.error(e);
process.exit(1);
});