Before diving into this example, it's essential to have a grasp of the fundamentals such as authentication and querying our GraphQL API, as outlined in the basic example. This guide will take you through the process of making a transaction request and tracking its progression from pending to signing, broadcasting, and finally, completion.

Submitting a Transaction Request

Submitting a transaction request in io.finnet involves orchestration based on Multi-Party Computation (MPC) and Threshold Signature Schemes (TSS) cryptography. For a transaction to occur and be broadcasted, the current active members of the signing party must approve the request and participate in the signing process. To initiate a transaction request, we use the createTransactionRequest mutation:

const txRequest = await fetch('https://api.iofinnet.com/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${bearerToken}`,
  },
  body: JSON.stringify({
    query: `
      mutation CreateTransactionRequest {
        createTransactionRequest(
          vaultId: "${vaultId}",
          assetId: "ETH.0x89f23744154936124707b726afdbd3fef9626a8b",
          sendAmount: 1000,
          receivingAddress: "0xadf9234bc5d54165021948c5337d895470510035",
          sendingAddress: "0x89f23744154936124707b726afdbd3fef9626a8b",
        ) {
          id
        }
      }
    `,
  }),
});

In this mutation, key parameters include:

  • vaultId: Your vault's unique identifier. This can be obtained through the vaults query or directly from the vault's URL in your browser.
  • assetId: A unique identifier for an asset, typically comprising a network identifier and, for ERC20 tokens, the contract address. For example, USDT on Ethereum is used in the provided example. The list of assets can be explored using the assets query.
  • receivingAddress: The crypto address designated to receive the assets.

Tracking a Transaction Request

After creating a transaction request, it's crucial to monitor its progression through various stages, including the signing process and eventual broadcast on the blockchain. Upon successful mining by the blockchain, the transaction request will then be associated with a 'Transaction' entity. This represents the actual transaction on the blockchain.

const getTransactionRequest = async () => {
  return fetch('https://api.iofinnet.com/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${bearerToken}`,
    },
    body: JSON.stringify({
      query: `
        query {
          transactionRequest(id: "${txRequest.data.createTransactionRequest.id}") {
            id
            status
            transaction {
              parentTransactionId
              status
            }
          }
        }
      `,
    }),
  });
}

setInterval(async () => {
  const transactionRequest = await getTransactionRequest();
  if (transactionRequest.data.status === 'PENDING') {
    console.log('Waiting for the signing party to approve the transaction');
  }
  if (transactionRequest.data.status === 'SIGNING') {
    console.log('MPC TSS Signing party are signing the transaction');
  }
  if (transactionRequest.data.transaction !== null && transactionRequest.data.transaction.status === 'COMPLETED') {
    console.log(`Transaction broadcasted ${transactionRequest.data.transaction.parentTransactionId} - go check etherscan!`);
    clearInterval(this);
  }
}, 300000);

The txRequest.data.createTransactionRequest.id used in the query is sourced from the transaction request creation code snippet above. For a deeper understanding of the transaction statuses and vault operations, refer to our Vault Introduction page.