@rango-dev/provider-trezor 0.28.1-next.2 → 0.29.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/chunk-DRNBRMLU.js +2 -0
- package/dist/chunk-DRNBRMLU.js.map +7 -0
- package/dist/ethereum-AWO7VVVT.js +2 -0
- package/dist/ethereum-AWO7VVVT.js.map +7 -0
- package/dist/{utils.d.ts → legacy/helpers.d.ts} +2 -2
- package/dist/legacy/index.d.ts +18 -0
- package/dist/mod.d.ts +1 -1
- package/dist/mod.js +1 -1
- package/dist/mod.js.map +4 -4
- package/dist/provider-trezor.build.json +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/state.d.ts +0 -2
- package/package.json +4 -9
- package/readme.md +0 -15
- package/src/constants.ts +1 -23
- package/src/{utils.ts → legacy/helpers.ts} +14 -13
- package/src/legacy/index.ts +151 -0
- package/src/mod.ts +5 -1
- package/src/namespaces/evm.ts +14 -4
- package/src/provider.ts +0 -2
- package/src/signer.ts +0 -4
- package/src/signers/ethereum.ts +8 -8
- package/src/state.ts +0 -15
- package/dist/actions/utxo.d.ts +0 -12
- package/dist/chunk-4A5SID3U.js +0 -2
- package/dist/chunk-4A5SID3U.js.map +0 -7
- package/dist/chunk-KQD4IRQZ.js +0 -2
- package/dist/chunk-KQD4IRQZ.js.map +0 -7
- package/dist/ethereum-CRCQQH34.js +0 -2
- package/dist/ethereum-CRCQQH34.js.map +0 -7
- package/dist/init.d.ts +0 -1
- package/dist/namespaces/utxo.d.ts +0 -3
- package/dist/signers/utxo.d.ts +0 -8
- package/dist/utxo/config.d.ts +0 -17
- package/dist/utxo/psbt.d.ts +0 -29
- package/dist/utxo/psbt.test.d.ts +0 -1
- package/dist/utxo-BVUYSP2M.js +0 -2
- package/dist/utxo-BVUYSP2M.js.map +0 -7
- package/src/actions/utxo.ts +0 -56
- package/src/init.ts +0 -20
- package/src/namespaces/utxo.ts +0 -24
- package/src/signers/utxo.ts +0 -90
- package/src/utxo/config.ts +0 -67
- package/src/utxo/psbt.test.ts +0 -162
- package/src/utxo/psbt.ts +0 -96
package/src/signers/utxo.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import type { GenericSigner, Transfer } from 'rango-types';
|
|
2
|
-
|
|
3
|
-
import { Networks } from '@rango-dev/wallets-shared';
|
|
4
|
-
import { SignerError } from 'rango-types';
|
|
5
|
-
|
|
6
|
-
import { getBitcoinDerivationPath } from '../state.js';
|
|
7
|
-
import { getTrezorModule } from '../utils.js';
|
|
8
|
-
import { BITCOIN_COIN_NAME } from '../utxo/config.js';
|
|
9
|
-
import { buildTrezorBitcoinTransaction } from '../utxo/psbt.js';
|
|
10
|
-
|
|
11
|
-
function getTrezorErrorMessage(payload: { error: string; code?: string }) {
|
|
12
|
-
return new Error(
|
|
13
|
-
payload.code ? `${payload.error} (${payload.code})` : payload.error
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class BTCSigner implements GenericSigner<Transfer> {
|
|
18
|
-
async signMessage(): Promise<string> {
|
|
19
|
-
throw SignerError.UnimplementedError('signMessage');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async signAndSendTx(tx: Transfer): Promise<{ hash: string }> {
|
|
23
|
-
const { blockchain } = tx.asset;
|
|
24
|
-
if (blockchain !== Networks.BTC) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`Signing ${blockchain} transactions is not supported by Trezor.`
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const { psbt } = tx;
|
|
31
|
-
if (!psbt) {
|
|
32
|
-
throw new Error(
|
|
33
|
-
'No PSBT found to sign. Ensure a valid PSBT is provided.'
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const path = getBitcoinDerivationPath();
|
|
38
|
-
if (!path) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
'No connected Bitcoin account found. Please connect the wallet first.'
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const TrezorConnect = await getTrezorModule();
|
|
45
|
-
const { inputs, outputs, version, locktime } =
|
|
46
|
-
buildTrezorBitcoinTransaction(psbt.unsignedPsbtBase64, path);
|
|
47
|
-
|
|
48
|
-
// `push: true` signs and broadcasts via Trezor's Blockbook backend.
|
|
49
|
-
const result = await TrezorConnect.signTransaction({
|
|
50
|
-
coin: BITCOIN_COIN_NAME,
|
|
51
|
-
inputs,
|
|
52
|
-
outputs,
|
|
53
|
-
version,
|
|
54
|
-
locktime,
|
|
55
|
-
push: true,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (!result.success) {
|
|
59
|
-
throw getTrezorErrorMessage(result.payload);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return { hash: await this.#resolveHash(result.payload) };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* `push: true` usually returns the txid directly. If it isn't present (older
|
|
67
|
-
* firmware/connect), push the serialized transaction explicitly as a fallback.
|
|
68
|
-
*/
|
|
69
|
-
async #resolveHash(payload: {
|
|
70
|
-
txid?: string;
|
|
71
|
-
serializedTx?: string;
|
|
72
|
-
}): Promise<string> {
|
|
73
|
-
if (payload.txid) {
|
|
74
|
-
return payload.txid;
|
|
75
|
-
}
|
|
76
|
-
if (!payload.serializedTx) {
|
|
77
|
-
throw new Error('Trezor did not return a transaction id.');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const TrezorConnect = await getTrezorModule();
|
|
81
|
-
const pushResult = await TrezorConnect.pushTransaction({
|
|
82
|
-
tx: payload.serializedTx,
|
|
83
|
-
coin: BITCOIN_COIN_NAME,
|
|
84
|
-
});
|
|
85
|
-
if (!pushResult.success) {
|
|
86
|
-
throw getTrezorErrorMessage(pushResult.payload);
|
|
87
|
-
}
|
|
88
|
-
return pushResult.payload.txid;
|
|
89
|
-
}
|
|
90
|
-
}
|
package/src/utxo/config.ts
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Trezor needs the input `script_type` to sign a Bitcoin input. It is determined by the
|
|
3
|
-
* BIP-43 `purpose` of the derivation path the address was derived from, so we expose the
|
|
4
|
-
* four common address types and let the user connect whichever one they hold funds on.
|
|
5
|
-
*/
|
|
6
|
-
export type TrezorInputScriptType =
|
|
7
|
-
| 'SPENDADDRESS'
|
|
8
|
-
| 'SPENDP2SHWITNESS'
|
|
9
|
-
| 'SPENDWITNESS'
|
|
10
|
-
| 'SPENDTAPROOT';
|
|
11
|
-
|
|
12
|
-
export interface BitcoinAddressType {
|
|
13
|
-
/** Stable id used in the derivationPath metadata entries. */
|
|
14
|
-
id: 'legacy' | 'nested-segwit' | 'native-segwit' | 'taproot';
|
|
15
|
-
label: string;
|
|
16
|
-
/** BIP-43 purpose: 44 legacy, 49 nested segwit, 84 native segwit, 86 taproot. */
|
|
17
|
-
purpose: number;
|
|
18
|
-
inputScriptType: TrezorInputScriptType;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const BITCOIN_COIN_NAME = 'btc';
|
|
22
|
-
|
|
23
|
-
export const BITCOIN_ADDRESS_TYPES: readonly BitcoinAddressType[] = [
|
|
24
|
-
{
|
|
25
|
-
id: 'native-segwit',
|
|
26
|
-
label: 'Native SegWit',
|
|
27
|
-
purpose: 84,
|
|
28
|
-
inputScriptType: 'SPENDWITNESS',
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: 'nested-segwit',
|
|
32
|
-
label: 'Nested SegWit',
|
|
33
|
-
purpose: 49,
|
|
34
|
-
inputScriptType: 'SPENDP2SHWITNESS',
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: 'legacy',
|
|
38
|
-
label: 'Legacy',
|
|
39
|
-
purpose: 44,
|
|
40
|
-
inputScriptType: 'SPENDADDRESS',
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
id: 'taproot',
|
|
44
|
-
label: 'Taproot',
|
|
45
|
-
purpose: 86,
|
|
46
|
-
inputScriptType: 'SPENDTAPROOT',
|
|
47
|
-
},
|
|
48
|
-
] as const;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Resolve the Trezor input script type for a derivation path by reading its BIP-43
|
|
52
|
-
* purpose (the first hardened level). The path always comes from one of our own
|
|
53
|
-
* derivation templates, so an unknown purpose is a programming error.
|
|
54
|
-
*/
|
|
55
|
-
export function resolveBitcoinScriptType(path: string): TrezorInputScriptType {
|
|
56
|
-
const purpose = Number.parseInt(
|
|
57
|
-
path.replace(/^m\//, '').split('/')[0]?.replace(/['h]$/, '') ?? '',
|
|
58
|
-
10
|
|
59
|
-
);
|
|
60
|
-
const addressType = BITCOIN_ADDRESS_TYPES.find(
|
|
61
|
-
(type) => type.purpose === purpose
|
|
62
|
-
);
|
|
63
|
-
if (!addressType) {
|
|
64
|
-
throw new Error(`Unsupported Bitcoin derivation path: ${path}`);
|
|
65
|
-
}
|
|
66
|
-
return addressType.inputScriptType;
|
|
67
|
-
}
|
package/src/utxo/psbt.test.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-magic-numbers */
|
|
2
|
-
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
3
|
-
import * as bitcoin from 'bitcoinjs-lib';
|
|
4
|
-
import { describe, expect, it } from 'vitest';
|
|
5
|
-
|
|
6
|
-
import { buildTrezorBitcoinTransaction } from './psbt.js';
|
|
7
|
-
|
|
8
|
-
bitcoin.initEccLib(ecc);
|
|
9
|
-
const NETWORK = bitcoin.networks.bitcoin;
|
|
10
|
-
|
|
11
|
-
const PRIVATE_KEY = Buffer.alloc(32, 7);
|
|
12
|
-
const PUBKEY = Buffer.from(
|
|
13
|
-
ecc.pointFromScalar(PRIVATE_KEY, true) as Uint8Array
|
|
14
|
-
);
|
|
15
|
-
const { address: OWN_ADDRESS } = bitcoin.payments.p2wpkh({
|
|
16
|
-
pubkey: PUBKEY,
|
|
17
|
-
network: NETWORK,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const NATIVE_SEGWIT_PATH = "m/84'/0'/0'/0/0";
|
|
21
|
-
|
|
22
|
-
// Non-palindromic on purpose, so the txid byte-reversal is actually exercised.
|
|
23
|
-
const FAKE_PREV_TXID =
|
|
24
|
-
'0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
|
|
25
|
-
const RECIPIENT = 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq';
|
|
26
|
-
|
|
27
|
-
function nativeSegwitInput() {
|
|
28
|
-
const witnessScript = bitcoin.payments.p2wpkh({
|
|
29
|
-
pubkey: PUBKEY,
|
|
30
|
-
network: NETWORK,
|
|
31
|
-
}).output as Buffer;
|
|
32
|
-
return {
|
|
33
|
-
hash: FAKE_PREV_TXID,
|
|
34
|
-
index: 0,
|
|
35
|
-
witnessUtxo: { script: witnessScript, value: 100_000 },
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
describe('buildTrezorBitcoinTransaction', () => {
|
|
40
|
-
it('maps each input to the connected path and its script type', () => {
|
|
41
|
-
const psbt = new bitcoin.Psbt({ network: NETWORK });
|
|
42
|
-
psbt.addInput(nativeSegwitInput());
|
|
43
|
-
psbt.addOutput({ address: RECIPIENT, value: 90_000 });
|
|
44
|
-
|
|
45
|
-
const { inputs } = buildTrezorBitcoinTransaction(
|
|
46
|
-
psbt.toBase64(),
|
|
47
|
-
NATIVE_SEGWIT_PATH,
|
|
48
|
-
NETWORK
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
expect(inputs).toHaveLength(1);
|
|
52
|
-
expect(inputs[0].address_n).toBe(NATIVE_SEGWIT_PATH);
|
|
53
|
-
expect(inputs[0].script_type).toBe('SPENDWITNESS');
|
|
54
|
-
expect(inputs[0].prev_hash).toBe(FAKE_PREV_TXID);
|
|
55
|
-
expect(inputs[0].prev_index).toBe(0);
|
|
56
|
-
expect(inputs[0].amount).toBe('100000');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('preserves version, locktime and per-input sequence from the PSBT', () => {
|
|
60
|
-
const psbt = new bitcoin.Psbt({ network: NETWORK });
|
|
61
|
-
psbt.setVersion(2);
|
|
62
|
-
psbt.setLocktime(800_000);
|
|
63
|
-
// RBF-signaling sequence.
|
|
64
|
-
psbt.addInput({ ...nativeSegwitInput(), sequence: 0xfffffffd });
|
|
65
|
-
psbt.addOutput({ address: RECIPIENT, value: 90_000 });
|
|
66
|
-
|
|
67
|
-
const { inputs, version, locktime } = buildTrezorBitcoinTransaction(
|
|
68
|
-
psbt.toBase64(),
|
|
69
|
-
NATIVE_SEGWIT_PATH,
|
|
70
|
-
NETWORK
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
expect(version).toBe(2);
|
|
74
|
-
expect(locktime).toBe(800_000);
|
|
75
|
-
expect(inputs[0].sequence).toBe(0xfffffffd);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('rejects an input with a non-SIGHASH_ALL sighash type', () => {
|
|
79
|
-
const psbt = new bitcoin.Psbt({ network: NETWORK });
|
|
80
|
-
psbt.addInput({
|
|
81
|
-
...nativeSegwitInput(),
|
|
82
|
-
sighashType: bitcoin.Transaction.SIGHASH_SINGLE,
|
|
83
|
-
});
|
|
84
|
-
psbt.addOutput({ address: RECIPIENT, value: 90_000 });
|
|
85
|
-
|
|
86
|
-
expect(() =>
|
|
87
|
-
buildTrezorBitcoinTransaction(
|
|
88
|
-
psbt.toBase64(),
|
|
89
|
-
NATIVE_SEGWIT_PATH,
|
|
90
|
-
NETWORK
|
|
91
|
-
)
|
|
92
|
-
).toThrow(/only SIGHASH_ALL is supported/);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('reconstructs outputs as address payments', () => {
|
|
96
|
-
const psbt = new bitcoin.Psbt({ network: NETWORK });
|
|
97
|
-
psbt.addInput(nativeSegwitInput());
|
|
98
|
-
psbt.addOutput({ address: RECIPIENT, value: 60_000 });
|
|
99
|
-
psbt.addOutput({ address: OWN_ADDRESS as string, value: 39_000 });
|
|
100
|
-
|
|
101
|
-
const { outputs } = buildTrezorBitcoinTransaction(
|
|
102
|
-
psbt.toBase64(),
|
|
103
|
-
NATIVE_SEGWIT_PATH,
|
|
104
|
-
NETWORK
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
expect(outputs).toEqual([
|
|
108
|
-
{ script_type: 'PAYTOADDRESS', address: RECIPIENT, amount: '60000' },
|
|
109
|
-
{ script_type: 'PAYTOADDRESS', address: OWN_ADDRESS, amount: '39000' },
|
|
110
|
-
]);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('derives the script type from the path purpose (legacy P2PKH)', () => {
|
|
114
|
-
const p2pkh = bitcoin.payments.p2pkh({ pubkey: PUBKEY, network: NETWORK });
|
|
115
|
-
|
|
116
|
-
// A previous transaction that funds the legacy address at vout 0.
|
|
117
|
-
const prevTx = new bitcoin.Transaction();
|
|
118
|
-
prevTx.version = 2;
|
|
119
|
-
prevTx.addInput(Buffer.alloc(32, 1), 0);
|
|
120
|
-
prevTx.addOutput(p2pkh.output as Buffer, 100_000);
|
|
121
|
-
|
|
122
|
-
const psbt = new bitcoin.Psbt({ network: NETWORK });
|
|
123
|
-
psbt.addInput({
|
|
124
|
-
hash: prevTx.getId(),
|
|
125
|
-
index: 0,
|
|
126
|
-
nonWitnessUtxo: prevTx.toBuffer(),
|
|
127
|
-
});
|
|
128
|
-
psbt.addOutput({ address: RECIPIENT, value: 90_000 });
|
|
129
|
-
|
|
130
|
-
const { inputs } = buildTrezorBitcoinTransaction(
|
|
131
|
-
psbt.toBase64(),
|
|
132
|
-
"m/44'/0'/0'/0/0",
|
|
133
|
-
NETWORK
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
expect(inputs[0].script_type).toBe('SPENDADDRESS');
|
|
137
|
-
expect(inputs[0].amount).toBe('100000');
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('encodes an OP_RETURN output as PAYTOOPRETURN', () => {
|
|
141
|
-
const memo = Buffer.from('rango', 'utf8');
|
|
142
|
-
const psbt = new bitcoin.Psbt({ network: NETWORK });
|
|
143
|
-
psbt.addInput(nativeSegwitInput());
|
|
144
|
-
psbt.addOutput({ address: RECIPIENT, value: 90_000 });
|
|
145
|
-
psbt.addOutput({
|
|
146
|
-
script: bitcoin.payments.embed({ data: [memo] }).output as Buffer,
|
|
147
|
-
value: 0,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
const { outputs } = buildTrezorBitcoinTransaction(
|
|
151
|
-
psbt.toBase64(),
|
|
152
|
-
NATIVE_SEGWIT_PATH,
|
|
153
|
-
NETWORK
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
expect(outputs[1]).toEqual({
|
|
157
|
-
script_type: 'PAYTOOPRETURN',
|
|
158
|
-
amount: '0',
|
|
159
|
-
op_return_data: memo.toString('hex'),
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
});
|
package/src/utxo/psbt.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { SignTransaction } from '@trezor/connect-web';
|
|
2
|
-
|
|
3
|
-
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
4
|
-
import * as bitcoin from 'bitcoinjs-lib';
|
|
5
|
-
|
|
6
|
-
import { resolveBitcoinScriptType } from './config.js';
|
|
7
|
-
|
|
8
|
-
// Lets bitcoinjs-lib decode taproot (witness v1) output addresses.
|
|
9
|
-
bitcoin.initEccLib(ecc);
|
|
10
|
-
|
|
11
|
-
type TrezorInput = SignTransaction['inputs'][number];
|
|
12
|
-
type TrezorOutput = SignTransaction['outputs'][number];
|
|
13
|
-
|
|
14
|
-
export interface TrezorBitcoinTransaction {
|
|
15
|
-
inputs: TrezorInput[];
|
|
16
|
-
outputs: TrezorOutput[];
|
|
17
|
-
/** Transaction version from the PSBT — preserved so the signed tx matches Rango's. */
|
|
18
|
-
version: number;
|
|
19
|
-
/** Transaction locktime from the PSBT (e.g. for CLTV) — preserved as-is. */
|
|
20
|
-
locktime: number;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const reverseTxid = (hash: Buffer) =>
|
|
24
|
-
Buffer.from(hash).reverse().toString('hex');
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Translate Rango's unsigned PSBT into the transaction Trezor's `signTransaction` expects
|
|
28
|
-
* (Trezor has no "sign this PSBT" call). Every field that affects the resulting bytes is
|
|
29
|
-
* preserved: `version`, `locktime`, and per-input `sequence` (RBF / locktime signaling),
|
|
30
|
-
* alongside each input's amount and script.
|
|
31
|
-
*
|
|
32
|
-
* Rango's PSBT carries no derivation data, so the connected `path` (and the script type
|
|
33
|
-
* from its BIP-43 purpose) is applied to every input — Rango funds the swap from that
|
|
34
|
-
* single address. `refTxs` are omitted: Trezor Connect fetches previous transactions from
|
|
35
|
-
* its Blockbook backend. Pure function -> unit testable.
|
|
36
|
-
*
|
|
37
|
-
* Only SIGHASH_ALL is supported: a non-default per-input sighash can't be honored through
|
|
38
|
-
* Trezor's signTransaction, so we reject it rather than sign the wrong thing. Multisig /
|
|
39
|
-
* script-path spends are out of scope (Rango funds from a single-key address).
|
|
40
|
-
*/
|
|
41
|
-
export function buildTrezorBitcoinTransaction(
|
|
42
|
-
unsignedPsbtBase64: string,
|
|
43
|
-
path: string,
|
|
44
|
-
network: bitcoin.Network = bitcoin.networks.bitcoin
|
|
45
|
-
): TrezorBitcoinTransaction {
|
|
46
|
-
const psbt = bitcoin.Psbt.fromBase64(unsignedPsbtBase64, { network });
|
|
47
|
-
const scriptType = resolveBitcoinScriptType(path);
|
|
48
|
-
|
|
49
|
-
const inputs = psbt.txInputs.map((input, index): TrezorInput => {
|
|
50
|
-
const data = psbt.data.inputs[index];
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
data.sighashType != null &&
|
|
54
|
-
data.sighashType !== bitcoin.Transaction.SIGHASH_ALL
|
|
55
|
-
) {
|
|
56
|
-
throw new Error(
|
|
57
|
-
`PSBT input #${index} uses sighash type ${data.sighashType}; only SIGHASH_ALL is supported.`
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const utxo =
|
|
62
|
-
data.witnessUtxo ??
|
|
63
|
-
bitcoin.Transaction.fromBuffer(data.nonWitnessUtxo as Buffer).outs[
|
|
64
|
-
input.index
|
|
65
|
-
];
|
|
66
|
-
return {
|
|
67
|
-
// Trezor Connect accepts the path string directly (like our EVM signer).
|
|
68
|
-
address_n: path,
|
|
69
|
-
prev_hash: reverseTxid(input.hash),
|
|
70
|
-
prev_index: input.index,
|
|
71
|
-
amount: utxo.value.toString(),
|
|
72
|
-
script_type: scriptType,
|
|
73
|
-
sequence: input.sequence,
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
const outputs = psbt.txOutputs.map(
|
|
78
|
-
(output): TrezorOutput =>
|
|
79
|
-
output.address
|
|
80
|
-
? {
|
|
81
|
-
script_type: 'PAYTOADDRESS',
|
|
82
|
-
address: output.address,
|
|
83
|
-
amount: output.value.toString(),
|
|
84
|
-
}
|
|
85
|
-
: {
|
|
86
|
-
script_type: 'PAYTOOPRETURN',
|
|
87
|
-
amount: '0',
|
|
88
|
-
op_return_data: (
|
|
89
|
-
bitcoin.script.decompile(output.script)?.find(Buffer.isBuffer) ??
|
|
90
|
-
Buffer.alloc(0)
|
|
91
|
-
).toString('hex'),
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
return { inputs, outputs, version: psbt.version, locktime: psbt.locktime };
|
|
96
|
-
}
|