Dump wallet transactions with cardano-cli

Is there a way to do this?

I took a quick look at the reference docs on github, but it didn’t seem like there was anything relevant.

I want to send my accountant a list of all my transactions.

Hello, there is an open ticket on Daedalus to do this: input-output-hk/daedalus#642

If you have a deadline, there is a CLI way, but it’s not exactly simple. What OS do you run Daedalus on, and how comfortable are you with the command line?

Oh nice!

I’m using Linux. I’m very comfortable with the command line.

OK very good! Here are the instructions for Linux. It requires bash shell, lsof, curl and jq, and for Daedalus to be running. Note: These steps are unlikely to damage your wallet, but are fairly advanced, so congrats if you get past step 1.

  1. Get TCP port number of running cardano-wallet backend. This changes every time you run Daedalus. The port is in the NAME column.

    lsof -Pan -iTCP -sTCP:LISTEN -p `pidof cardano-wallet`
    
  2. Define a shortcut function, using the port you got in the previous step:

    server=127.0.0.1:PORT
    api() { curl --silent --cert ~/.local/share/Daedalus/mainnet/tls/client/client.crt --cacert ~/.local/share/Daedalus/mainnet/tls/client/ca.crt --key ~/.local/share/Daedalus/mainnet/tls/client/client.key https://$server/v2$1 }
    
  3. List the wallet IDs of your wallets in Daedalus:

    api /wallets | jq '.[] | {name: .name, id: .id, state:.state.status}'
    
  4. List the transactions of your chosen wallet ID and convert to CSV format:

    api /wallets/1d438950c643558e910d39da363fa1887bfc007f/transactions | jq -r '.[] | [.id,.inserted_at.time,.status, .amount.quantity,.direction] | @csv'
    

    Note that times are in UTC and amounts are in lovelace. You can obviously change the jq command as needed for your report.

Reference: cardano-wallet API Documentation

4 Likes

Thanks @rodney! That worked perfectly.

Note to others that if you want to list transactions for byron wallets, you’ll have to change “wallets” in steps 3&4 to “byron-wallets”.

IOG should develop a discord plugin that allows for ada tipping!

1 Like

I have turned @rodney’s CLI foo into a bash script, with a usage message and checks for the curl and jq executables and also lists the amounts in Ada rather than Lovelace.

#!/bin/bash -eu

progname=$(basename "$0")

curl --version > /dev/null 2>&1 || { echo "${progname}: 'curl' program is missing." >&2 ; exit 1 ; }
jq --version > /dev/null 2>&1 || { echo "${progname}: 'jq' program is missing." >&2 ; exit 1 ; }

wallet_pid=$(pidof cardano-wallet)
http_port=$(lsof -Pan -iTCP -sTCP:LISTEN -p "${wallet_pid}" | tail -1 | sed 's/.*://;s/ .*//')


function api () {
  curl --silent --cert ~/.local/share/Daedalus/mainnet/tls/client/client.crt \
    --cacert ~/.local/share/Daedalus/mainnet/tls/client/ca.crt \
    --key ~/.local/share/Daedalus/mainnet/tls/client/client.key \
    "https://localhost:${http_port}/v2/$1"
}

function wallets () {
  api wallets | jq '.[] | {name: .name, id: .id, state:.state.status}'
}

function transactions () {
  echo "TransactionId,Timestamp,Direction,AmountAda"
  api "wallets/$1/transactions" \
    | jq -r '.[] | [.id, .inserted_at.time, .direction, .amount.quantity / 1000000] | @csv' \
    | sort --field-separator=',' --key 2
}

function usage_exit {
  echo
  echo "Usage:"
  echo "  $progname wallets                   - List the known wallets."
  echo "  $progname transactions <wallet>     - List all transactions for a given wallet."
  echo
  exit 0
}

case "${1:-""}" in
  wallets)
    wallets
    ;;
  transactions)
    shift
    if test $# -eq 1 ; then
      transactions "$1"
    else
      echo
      echo "Error: A wallet needs to be specified."
      usage_exit
      fi
    ;;
  *)
    usage_exit
  esac

2 Likes

The above script (that I have been using since I posted it) stopped working when I upgraded to Daedalus 6.0.0 just recently. Debugging it turned up that the pidof command was erroring out (I suspect because the command line of the cardano-wallet was too long).

Anyway, I found a workaround, and here is the new version:

#!/bin/bash -u

# https://input-output-hk.github.io/cardano-wallet/api/edge/

progname=$(basename "$0")

curl --version > /dev/null 2>&1 || { echo "${progname}: 'curl' program is missing." >&2 ; exit 1 ; }
jq --version > /dev/null 2>&1 || { echo "${progname}: 'jq' program is missing." >&2 ; exit 1 ; }

# pidof should just work, but sometimes it does not.
wallet_pid=$(pidof cardano-wallet)
if test -z "${wallet_pid}" ; then
  wallet_pid=$(ps x | grep exe/cardano-wallet | grep Daedalus | sed 's/^ *//;s/ .*//')
  fi

http_port=$(lsof -Pan -iTCP -sTCP:LISTEN -p "${wallet_pid}" | tail -1 | sed 's/.*://;s/ .*//')


function addresses () {
  echo "TransactionId,Timestamp,Direction,AmountAda"
  api "wallets/$1/addresses" \
      | jq -r '.[] | [.id, .state] | @csv' \
      | sort --field-separator=',' --key 2
}

function api () {
  curl --silent --cert ~/.local/share/Daedalus/mainnet/tls/client/client.crt \
    --cacert ~/.local/share/Daedalus/mainnet/tls/client/ca.crt \
    --key ~/.local/share/Daedalus/mainnet/tls/client/client.key \
    "https://localhost:${http_port}/v2/$1"
}

function transactions () {
  echo "TransactionId,Timestamp,Direction,AmountAda"
  api "wallets/$1/transactions" \
    | jq -r '.[] | [.id, .inserted_at.time, .direction, .amount.quantity / 1000000] | @csv' \
    | sort --field-separator=',' --key 2
}

function wallets () {
  api wallets | jq '.[] | {name: .name, id: .id, state:.state.status, pool:.delegation.active.target, balance: (.balance.total.quantity / 1000000) }'
}


function usage_exit {
  echo
  echo "Usage:"
  echo "  $progname wallets                   - List the known wallets."
  echo "  $progname addresses <wallet>        - List all addresses for a given wallet."
  echo "  $progname transactions <wallet>     - List all transactions for a given wallet."
  echo
  exit 0
}

case "${1:-""}" in
  wallets)
    wallets
    ;;
  addresses)
    shift
    if test $# -eq 1 ; then
      addresses "$1"
    else
      echo
      echo "Error: A wallet needs to be specified."
      usage_exit
      fi
    ;;
  transactions)
    shift
    if test $# -eq 1 ; then
      transactions "$1"
    else
      echo
      echo "Error: A wallet needs to be specified."
      usage_exit
      fi
    ;;
  *)
    usage_exit
  esac