Help, I'm a noob with node.js -> bitcoinlib.js

I want to improve my project with self custody wallet.
I’m understanding the logic but I have no experience with node.js or browserify. I could need some help at this point.

My main problem is how to sign a raw transaction on the client side.

Everything else is clear like adding only the public key to the user database entry and verify it with a small payment (to your self/ the given address) and submit the signed raw transaction to the mempool is no problem too.

But sign it client side makes me headache right now :sweat_smile:

2 Likes

Apologies for the late reply. Bitcoinjs now uses the psbt system for building transactions, and signing them. If you still need help, let me know how I can help.

FYI here are the litecoin mainnet constants you need to add to bitcoinjs:

export const LITECOIN = {
  messagePrefix: '\x19Litecoin Signed Message:\n',
  bech32: 'ltc',
  bip32: {
    public: 0x019da462,
    private: 0x019d9cfe,
  },
  pubKeyHash: 0x30,
  scriptHash: 0x32,
  wif: 0xb0,
};

It’s used like this:

import {LITECOIN} from './litecoin';
import {payments, Psbt} from 'bitcoinjs-lib';

      // construct psbt tx
      const psbt = new Psbt({network: LITECOIN});
      const unspents = data.txs;
      let totalBalance = 0;

      // loops through all utxos
      for (let utxo = 0; utxo < unspents.length; utxo++) {
        // calculate total unspents
        // loops through all outputs to look for address associated to WIF
        for (let output = 0; output < unspents[utxo].outputs.length; output++) {
          if (unspents[utxo].outputs[output].addresses.includes(address)) {
            totalBalance += unspents[utxo].outputs[output].value;
          }
        }

        const outputIndex = unspents[utxo].outputs.findIndex(
          (output: {addresses: string | string[]}) =>
            output.addresses.includes(address),
        );

        // multiple inputs
        psbt.addInput({
          hash: unspents[utxo].hash,
          index: outputIndex,
          nonWitnessUtxo: Buffer.from(unspents[utxo].hex, 'hex'),
        });
      }

      // single output
      psbt.addOutput({
        address: receiveAddress,
        value: Math.floor(
          totalBalance -
            Math.ceil(estimateTxSize(inputScript, unspents.length) * 18.8),
        ),
      });

      console.log(estimateTxSize('P2PKH', unspents.length));

      psbt.signInput(0, keyPair);
      psbt.finalizeAllInputs();

      const finalTx = psbt.extractTransaction(false);

      console.log(finalTx.toHex());
      resolve(finalTx.toHex());

In the example above I’m constructing a transaction to sweep utxos from an address to a single new output.

1 Like

Hey friend :slight_smile:

Meanwhile I found a solution with a litecoinjs-lib.js

This script works with derived multisignature addresses. It also offers a psbt version which is called psmst, but not tryed yet.

First I found a solution with classic nested segwit address type, but adding a omnilite payload leaded into an error on submit to mempool.

Using a 2of2 multisig address solved that problem but makes it harder to restore that address.

Meanwhile I made an extension wallet which is able to handle omnilite C-class actions
(send and receive token, no create/mint)
and also coin control works which allows ordinals as well :+1:

As always the front-end design is a nightmare for me :sweat_smile:

You are welcome to test it out if you like.
It’s not published yet and I could need some critical feedback.

Most curious Im about the dedicated exchange which is build in omnilite.
I successfully tested the access to it via my extension :call_me_hand:

1 Like

Do you have a link to the repo? Would be cool to take a look. Assuming it’s a fork of bitcoinjs, but with more litecoin specific things added?