@@ -6,12 +6,12 @@ import { useWallet } from 'store/wallet';
7import * as bitcoin from 'bitcoinjs-lib';
7import * as bitcoin from 'bitcoinjs-lib';
8import { useLocalRouter } from 'lib/LocalRouter';
8import { useLocalRouter } from 'lib/LocalRouter';
9−import { COMMANDS, useFlowCommand } from 'lib/flowCommand';
9+import { COMMANDS, FlowType, useFlowCommand } from 'lib/flowCommand';
10import * as need from 'lib/need';
10import * as need from 'lib/need';
11import useCopiable from 'lib/useCopiable';
11import useCopiable from 'lib/useCopiable';
13import View from 'components/View';
13import View from 'components/View';
14−import L2BackHeader from 'components/L2/Headers/L2BackHeader';
14+import L2BackHeader from 'components/L2/Headers/L2BackHeader';
15import Window from 'components/L2/Window/Window';
15import Window from 'components/L2/Window/Window';
16import HeaderPane from 'components/L2/Window/HeaderPane';
16import HeaderPane from 'components/L2/Window/HeaderPane';
17import BodyPane from 'components/L2/Window/BodyPane';
17import BodyPane from 'components/L2/Window/BodyPane';
@@ -52,10 +52,12 @@ const BITCOIN_TESTNET_INFO = {
52export default function Bitcoin() {
52export default function Bitcoin() {
53 const { pop }: any = useLocalRouter();
53 const { pop }: any = useLocalRouter();
54 const { urbitWallet }: any = useWallet();
54 const { urbitWallet }: any = useWallet();
55− const flow = useFlowCommand();
55+ const flow: FlowType = useFlowCommand();
57 const [signedTx, setSignedTx] = useState('');
57 const [signedTx, setSignedTx] = useState('');
58− const [psbt, setPsbt] = useState({});
58+ const [psbt, setPsbt] = useState<ReturnType<
59+ typeof bitcoin.Psbt.fromBase64
60 // set to false for BTC testnet
62 // set to false for BTC testnet
61 const isMainnet = true;
63 const isMainnet = true;
@@ -77,13 +79,14 @@ export default function Bitcoin() {
78 const [doCopy, didCopy] = useCopiable(xpub);
80 const [doCopy, didCopy] = useCopiable(xpub);
80− const onSubmit = (values: any) => {
82+ const onSubmit = (values: { unsignedTransaction: string }) => {
81 const newPsbt = bitcoin.Psbt.fromBase64(values.unsignedTransaction);
83 const newPsbt = bitcoin.Psbt.fromBase64(values.unsignedTransaction);
83− const isTestnet = newPsbt.data.inputs[0].bip32Derivation[0].path.startsWith(
84+ const derivations = newPsbt.data.inputs[0]?.bip32Derivation;
84− "m/84'/1'/0'/"
85+ const firstDerivation =
85− );
86+ derivations && derivations.length > 0 ? derivations[0] : null;
86−
87+ const firstDerivationPath = firstDerivation ? firstDerivation.path : null;
89+ firstDerivationPath && firstDerivationPath.startsWith("m/84'/1'/0'/");
87 const derivationPrefix = isTestnet ? "m/84'/1'/0'/" : "m/84'/0'/0'/";
90 const derivationPrefix = isTestnet ? "m/84'/1'/0'/" : "m/84'/0'/0'/";
89 const btcWallet = isTestnet
92 const btcWallet = isTestnet
@@ -91,13 +94,17 @@ export default function Bitcoin() {
91 : bitcoin.bip32.fromBase58(zprv, BITCOIN_MAINNET_INFO);
94 : bitcoin.bip32.fromBase58(zprv, BITCOIN_MAINNET_INFO);
97+ if (!firstDerivationPath) {
98+ throw new Error('No derivation path available');
94 const hex = newPsbt.data.inputs
100 const hex = newPsbt.data.inputs
95 .reduce((psbt, input, idx) => {
101 .reduce((psbt, input, idx) => {
96 // removing already derived part, eg m/84'/0'/0'/0/0 becomes 0/0
102 // removing already derived part, eg m/84'/0'/0'/0/0 becomes 0/0
97− const path = input.bip32Derivation[0].path
98− .split(derivationPrefix)
103+ const path = firstDerivationPath.split(derivationPrefix).join('');
100 const prv = btcWallet.derivePath(path).privateKey;
104 const prv = btcWallet.derivePath(path).privateKey;
106+ throw new Error('Private key unavailable');
101 return psbt.signInput(idx, bitcoin.ECPair.fromPrivateKey(prv));
108 return psbt.signInput(idx, bitcoin.ECPair.fromPrivateKey(prv));
102 }, newPsbt)
109 }, newPsbt)
103 .finalizeAllInputs()
110 .finalizeAllInputs()
@@ -112,9 +119,11 @@ export default function Bitcoin() {
115− const initialValues = {};
122+ let initialValues = {
123+ unsignedTransaction: '',
116 if (flow && COMMANDS.BITCOIN === flow.kind) {
125 if (flow && COMMANDS.BITCOIN === flow.kind) {
117− initialValues.unsignedTransaction = flow.utx;
126+ initialValues.unsignedTransaction = flow.utx as string;
@@ -177,6 +186,7 @@ export default function Bitcoin() {
177 </Grid.Item>
186 </Grid.Item>
179 {signedTx &&
188 {signedTx &&
180 psbt.txOutputs.map(e => (
190 psbt.txOutputs.map(e => (
181 <Grid.Item full className="mt4" key={e.address}>
191 <Grid.Item full className="mt4" key={e.address}>
182 <span>{e.address}</span>
192 <span>{e.address}</span>