minotaur-ergo/minotaur-wallet

2of2 Multisig Bug: invalid transaction

Opened this issue · 0 comments

c8e4 commented

OS: latest macOS
node: v21.2.0
minotaur-wallet: latest

Expected behaviour:

A fully signed 2of2 tx passes https://gql.ergoplatform.com/ -> checkTransaction

Actual behaviour

Transaction fails to pass checkTransaction
Please note that publishing such a transaction over https://api.ergoplatform.com/api/v1/mempool/transactions/submit returns a txId, but the transaction never reaches the mempool.

Steps to reproduce

Setup Wallets
BrowserAlice: Create Alice Wallet
BrowserBob: Create Bob Wallet

BrowserAlice: Create Multisig Wallet with 2of2: Alice Wallet, Bob xpub
BrowserBob: Create Multisig Wallet with 2of2: Bob Wallet, Alice xpub

Send funds to Multisig Wallet address.

Create Multisig Spending Tx
MultisigWalletBob:

  1. Create a Tx that sends some funds to Bob.
  2. Sign Commitment
  3. Copy to Clipboard

MultisigWalletAlice:

  1. Paste in Multi-sig Communication
  2. Sign Commitment
  3. Sign Transaction
  4. Copy to Clipboard

MultisigWalletBob:

  1. DELETE Transaction <- THIS STEP TRIGGERS THE BUG
  2. Paste in Multi-sig Communication
  3. Sign Transaction
  4. Publish Transaction <- ui will show you a tx id, but the tx will never enter mempool

Reliable way of checking if tx is valid in javascript

// signedTransaction  - wasm.Transaction.to_js_eip12()
async function txHasErrors(signedTransaction: string): Promise<false |string> {
    const endpoint = "https://gql.ergoplatform.com/";
    const query = `
      mutation CheckTransaction($signedTransaction: SignedTransaction!) {
        checkTransaction(signedTransaction: $signedTransaction)
      }
    `;

    const variables = {
        signedTransaction: signedTransaction
    };

    const response = await fetch(endpoint, {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            query: query,
            variables: variables
        })
    });

    if (!response.ok) {
        throw new Error("Network response was not ok: " + response.statusText);
    }

    const jsonResp =  await response.json();
    if(jsonResp.data?.checkTransaction){
        return false;
    }else{
        return jsonResp.errors
    }
}