@@ -18,9 +18,32 @@ import * as bitcoin from 'bitcoinjs-lib';
18import BridgeForm from 'form/BridgeForm';
18import BridgeForm from 'form/BridgeForm';
19import { PsbtInput } from 'form/Inputs';
19import { PsbtInput } from 'form/Inputs';
21−import { Buffer } from 'buffer';
22import { composeValidator, buildPsbtValidator } from 'form/validators';
21import { composeValidator, buildPsbtValidator } from 'form/validators';
23+const BITCOIN_MAINNET_INFO = {
24+ messagePrefix: '\x18Bitcoin Signed Message:\n',
35+const BITCOIN_TESTNET_INFO = {
36+ messagePrefix: '\x18Bitcoin Signed Message:\n',
24export default function SignTransaction() {
47export default function SignTransaction() {
25 const { pop } = useLocalRouter();
48 const { pop } = useLocalRouter();
26 const { urbitWallet } = useWallet();
49 const { urbitWallet } = useWallet();
@@ -29,41 +52,44 @@ export default function SignTransaction() {
29 const [signedTx, setSignedTx] = useState('');
52 const [signedTx, setSignedTx] = useState('');
30 const [psbt, setPsbt] = useState({});
53 const [psbt, setPsbt] = useState({});
32− const { private: privKey, chain } = need.urbitWallet(
55+ const { xprv: zprv } = need.urbitWallet(urbitWallet).bitcoinMainnet.keys;
33− urbitWallet
56+ const { xprv: vprv } = need.urbitWallet(urbitWallet).bitcoinTestnet.keys;
36− const btcWallet = bitcoin.bip32.fromPrivateKey(
37− Buffer.from(privKey, 'hex'),
38− Buffer.from(chain, 'hex'),
39− bitcoin.networks.bitcoin
42 const validate = composeValidator({
58 const validate = composeValidator({
43− unsignedTransaction: buildPsbtValidator(btcWallet),
59+ unsignedTransaction: buildPsbtValidator(),
46− const onSubmit = values => {
62+ const onSubmit = (values, form) => {
47 const newPsbt = bitcoin.Psbt.fromBase64(values.unsignedTransaction);
63 const newPsbt = bitcoin.Psbt.fromBase64(values.unsignedTransaction);
65+ const isTestnet = newPsbt.data.inputs[0].bip32Derivation[0].path.startsWith(
69+ const derivationPrefix = isTestnet ? "m/84'/1'/0'/" : "m/84'/0'/0'/";
71+ const btcWallet = isTestnet
72+ ? bitcoin.bip32.fromBase58(vprv, BITCOIN_TESTNET_INFO)
73+ : bitcoin.bip32.fromBase58(zprv, BITCOIN_MAINNET_INFO);
48− const hex = newPsbt.data.inputs
76+ const hex = newPsbt.data.inputs
49− .reduce((psbt, input, idx) => {
77+ .reduce((psbt, input, idx) => {
50− // removing already derived part, eg m/84'/0'/0'/0/0 becomes 0/0
78+ // removing already derived part, eg m/84'/0'/0'/0/0 becomes 0/0
51− const path = input.bip32Derivation[0].path
79+ const path = input.bip32Derivation[0].path
52− .split("m/84'/0'/0'/")
80+ .split(derivationPrefix)
53− .join('');
81+ .join('');
54− const prv = btcWallet.derivePath(path).privateKey;
82+ const prv = btcWallet.derivePath(path).privateKey;
56 return psbt.signInput(idx, bitcoin.ECPair.fromPrivateKey(prv));
83 return psbt.signInput(idx, bitcoin.ECPair.fromPrivateKey(prv));
60− }, newPsbt)
84+ }, newPsbt)
61− .finalizeAllInputs()
85+ .finalizeAllInputs()
62− .extractTransaction()
86+ .extractTransaction()
63− .toHex();
87+ .toHex();
65− setPsbt(newPsbt);
88+ setPsbt(newPsbt);
66− setSignedTx(hex);
89+ setSignedTx(hex);
91+ return { unsignedTransaction: 'Can not sign transaction' };
69 const initialValues = {};
95 const initialValues = {};