Intent-based Transaction Request API

As an alternative of Transaction Request API, this allows direct access to the wallet's transaction building API which is powering most of the Transaction Request API under the hood.

Note This API is designed for power users only.

  • All identifier fields in the intent (network, address, asset, etc.) are blockchain network agnostic identifiers.
  • No Levain wallet context will be inferred, all transaction details have to be specified. For example, creating a transaction of SEND by specifying another wallet address as the source. The transaction will be signed accordingly but rejected upon broadcast, since the protocol will likely deem it as invalid.
  • Some transaction types are unique to particular blockchain archetypes or wallets. Initiating such transactions on an incompatible wallet is possible but will lead to execution failure in subsequent step(s).
  • New and/or experimental transaction-type will be first exposed through this API before its full compatibility with all Levain wallets.

Full Transaction Flow by Using Levain SDK

1. Instantiate an Authorized SDK client

initiate-transaction-controller.tsTypeScript
import { LevainGraphClient } from '@levain/wallet-sdk';

const client = new LevainGraphClient({
  // Get your personal access token from https://app.levain.tech/account/tokens
  accessToken: '<Your access token>',
});

const walletId = '<Your wallet ID>';

2. Initiate a Transaction

initiate-transaction-controller.tsTypeScript
const { requestId } = await client.createTransaction({
  walletId: walletId,
  intent: {
    '<transaction type>': {
      type: '<transaction type>',
      ...otherRelevantData,
    },
  },
});

All builder-supported Transaction Intent's data structure can be found in next section.

3. Follow-up with Usual Transaction Approving, Signing, and Executing

All Levain wallets are attached with transaction approval policy where it always requires one approval by default. If your wallet has escalated approval threshold, multiple parties (approver) have to approve the transaction before the request can proceed to the next step.

approve-transaction-controller.tsTypeScript
await client.approveTransactionRequest({ requestId });
create-digests-controller.tsTypeScript
const { digests } = await client.createTransactionDigests({ requestId });
execute-transaction-controller.tsTypeScript
const { transactionHash } = await client.executeTransaction({
  walletId: wallet.walletId,
  requestId: initiated.requestId,
  digests,
  walletPassword: loadFromEnvVar(`PASSWORD_${wallet.walletId}`),
});

Alternative API

For a server-operated hot wallet that do not involve any human intervention, you shall use this simplified SDK shortcut. This is also assuming your wallet has policy with approvalThreshold equals to ONE (default).

withdrawal-cron.tsTypeScript
/**
 * createTransaction -> approveTransactionRequest -> createTransactionDigests -> executeTransaction
 */
const executedWithdrawal = await client.createApproveExecute({
  input: {
    walletId: withdrawalHotWallet.walletId,
    intent: {
      '<transaction type>': {
        type: '<transaction type>',
        ...otherRelevantData,
      },
    },
  },
  approve: true,
  executeWithPassword: loadFromEnvVar(`PASSWORD_${wallet.walletId}`),
});

Transaction Intent

SEND

Supported wallet types

  • UtxoP2tr
  • UtxoP2wshMultiSig

Supported asset types

  • native asset
  • caip19:bip122:<caip2-reference>/dst:*>
SEND Transaction Parameterjson
{
  "walletId": "<your-source-wallet-id>",
  "intent": {
    "SEND": {
      "type": "SEND",
      "from": "<wallet main address CAIP-2 identifier>",
      "to": "<withdrawal destination>",
      "asset": "<withdrawn asset CAIP-19 identifier>",
      "amount": 1
    }
  }
}

CONSOLIDATE

Supported wallet types

  • EvmContractSimpleMultiSig
  • UtxoP2tr
  • UtxoP2wshMultiSig

Supported asset types

  • native utxo asset
  • caip19:eip155:<caip2-reference>/erc20:*>
  • caip19:bip122:<caip2-reference>/dst:*>
CONSOLIDATE Transaction Parameterjson
{
  "walletId": "<your-wallet-id>",
  "intent": {
    "CONSOLIDATE": {
      "type": "CONSOLIDATE",
      "from": [
        {
          "from": "<your-deposit-address-caip-10-id>",
          "asset": "<asset-to-be-consolidated-caip-19-id>"
        },
        {
          "from": "<your-deposit-address-caip-10-id>",
          "asset": "<asset-to-be-consolidated-caip-19-id>"
        }
        // , ... more source of assets to be consolidated
      ],
      "to": "<consolidate-destination-caip-10-id>"
    }
  }
}

SEND_TO_MANY

Supported wallet types

  • UtxoP2tr
  • UtxoP2wshMultiSig

Supported asset types

  • native asset
  • caip19:bip122:<caip2-reference>/dst:*>
SEND_TO_MANY Transaction Parameterjson
{
  "walletId": "<your-wallet-id>",
  "intent": {
    "SEND_TO_MANY": {
      "type": "SEND_TO_MANY",
      "from": ["<wallet main address CAIP-2 identifier>"],
      "to": [
        {
          "destination": "<destination-caip10-id>",
          "asset": "<asset-to-be-sent-caip-19-id>",
          "amount": 1
        },
        {
          "destination": "<another-destination-caip10-id>",
          "asset": "<asset-to-be-sent-caip-19-id>",
          "amount": 1
        }
        // , ... more beneficiaries details
      ]
    }
  }
}

UTXO_TO_ACCOUNT

A DeFiChain-specific transaction type.

Supported wallet types

  • UtxoP2wshMultiSig

Supported asset types

  • N/A
SEND_TO_MANY Transaction Parameterjson
{
  "walletId": "<your-wallet-id>",
  "intent": {
    "UTXO_TO_ACCOUNT": {
      "type": "UTXO_TO_ACCOUNT",
      "from": ["<main-address-caip2-id>"],
      "to": "<beneficiary-caip2-id>",
      "amount": 1
    }
  }
}

ACCOUNT_TO_UTXO

A DeFiChain specific transaction type.

Supported wallet types

  • UtxoP2wshMultiSig

Supported asset types

  • N/A
SEND_TO_MANY Transaction Parameterjson
{
  "walletId": "<your-wallet-id>",
  "intent": {
    "ACCOUNT_TO_UTXO": {
      "type": "ACCOUNT_TO_UTXO",
      "from": "<main-address-caip2-id>",
      "amount": 1
    }
  }
}