Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Shell and jq

For scripts and quick automation. wrappers/shell/mostro.sh defines a few functions:

#!/usr/bin/env bash
# Shell helpers for the mostro-cli JSON interface. Needs bash and jq.
#
#   source wrappers/shell/mostro.sh
#   out=$(mostro_json order list --side sell) ; rc=$?
#   mostro_status "$out"            # ok | error | uncertain | transport
#   jq -r '.data.orders[].id' <<<"$out"

MOSTRO_CLI="${MOSTRO_CLI:-mostro-cli}"

# Runs one command in JSON mode and prints its envelope. Returns the CLI's exit
# code. stdin is closed; stderr is passed through.
mostro_json() {
  "$MOSTRO_CLI" --output json "$@" </dev/null
}

# Prints ok, error, uncertain, or transport when $1 is not one JSON envelope.
mostro_status() {
  jq -er 'select(.schema_version == "1") | .status' <<<"$1" 2>/dev/null || echo transport
}

# Prints the error code, or nothing.
mostro_code() {
  jq -r '.error.code // empty' <<<"$1" 2>/dev/null
}

# Example: list pending sell orders in a currency, one line each.
mostro_book() {
  local out
  out=$(mostro_json order list --side sell --currency "${1:-USD}") || true
  case "$(mostro_status "$out")" in
    ok) jq -r '.data.orders[] |
          [.id, .fiat_currency,
           (if .fiat_amount_min then "\(.fiat_amount_min)-\(.fiat_amount_max)" else .fiat_amount end),
           (if .sats_amount == "0" then "market" else .sats_amount end),
           "\(.premium_percent)%", .payment_method] | @tsv' <<<"$out" ;;
    transport) echo "no envelope" >&2; return 1 ;;
    *) echo "failed: $(mostro_code "$out")" >&2; return 1 ;;
  esac
}

Recipes

# ids of pending USD sell orders, cheapest premium first
mostro-cli --output json order list --side sell --currency USD |
  jq -r '.data.orders | sort_by(.premium_percent | tonumber) | .[].id'

# fixed orders between 50 and 200 fiat units
mostro-cli --output json order list |
  jq '.data.orders[] | select(.fiat_amount_min == null and (.fiat_amount | tonumber) >= 50 and (.fiat_amount | tonumber) <= 200)'

# the status of one order
mostro-cli --output json order info --order "$ID" | jq -r '.data.orders[0].status // "not returned"'

# invoices the node is waiting for me to pay
mostro-cli --output json message list --since 120 |
  jq -r '.data.messages[] | select(.next_step == "pay_hold_invoice" or .next_step == "pay_bond_invoice")
         | "\(.order_id) \(.next_step) \(.payload.invoice)"'

# every requested action, newest last
mostro-cli --output json message list --since 1440 |
  jq -r '.data.messages[] | select(.next_step) | [.created_at, .order_id, .next_step] | @tsv'

# branch on the outcome of a write
out=$(mostro-cli --output json order cancel --order "$ID" --yes </dev/null)
case $(jq -r .status <<<"$out") in
  ok)        jq -r '.data.result' <<<"$out" ;;
  uncertain) echo "check with: mostro-cli --output json order info --order $ID" ;;
  error)     jq -r '"\(.error.code) \(.error.reason // "")"' <<<"$out" ;;
esac

# which commands does this binary support in JSON?
mostro-cli --output json schema | jq -r '.data.commands[] | select(.output_modes | index("json")) | .name'

jq’s tonumber is fine for filtering small values like premiums and fiat amounts, but it uses doubles: never use it to compute with sats_amount.