CLI
Escrow & transaction verification
The CLI's escrow is a durable local ledger — not an on-chain contract — and its verification commands report exactly what a lookup proves and what it does not. This page is the honest contract for both.
Escrow — a local state machine
A deterministic escrow state machine persisted across invocations in ~/.furlpay/escrows.json (atomic writes, 0600 on POSIX, symlink refusal). States: CREATED → FUNDED → PROOF_SUBMITTED → RELEASED, with DISPUTED and refund paths. Every transition is appended to an immutable audit log (furlpay escrow status --verbose).
# Create with a pre-agreed SHA-256 delivery proof commitment
furlpay escrow create \
--seller 0x... --arbiter 0x... \
--amount 5000 --timeout-days 7 \
--proof-hash 0x<sha256 of the deliverable>
# Fund — requires the REAL funding transaction hash; the CLI never fabricates one
furlpay escrow fund --escrow-id escrow_<id> --tx-hash 0x<your funding tx>
# Seller submits the cryptographic delivery proof
furlpay escrow proof --escrow-id escrow_<id> --hash 0x<sha256> --signature <sig>
# Release (buyer approval; auto-release timer also supported)
furlpay escrow release --escrow-id escrow_<id> --tx-hash 0x<settlement tx>
# Dispute for arbiter resolution
furlpay escrow dispute --escrow-id escrow_<id> --reason "delivery did not match spec"- No on-chain escrow contract is deployed and no funds move except the transactions you reference via
--tx-hash— which are never fabricated by the CLI. - Unauthorized actors, malformed proof hashes and tx-hash-less fund/release attempts fail closed.
- The escrow ledger lives in
~/.furlpay; deleting that directory deletes every escrow record irreversibly.
Transaction verification — what a lookup proves
furlpay tx verify <64-hex-hash> [--network mainnet|testnet] [--output json]Performs GET /transactions/{hash} against the documented Horizon endpoint for the selected network and reports one of five outcomes:
| Outcome | Exit | Meaning |
|---|---|---|
CONFIRMED_SUCCESS | 0 | Real transaction, found in finalized ledger history, successful on-chain. |
CONFIRMED_FAILED | 1 | Real transaction, found, but it failed on-chain. This is evidence about the past, not a promise about a retry. |
NOT_FOUND | 1 | No transaction at that hash. Explicitly NOT proof that a transaction never existed. |
INVALID_HASH | 1 | The argument is not a valid 64-character hash. |
UNAVAILABLE | 1 | Horizon could not be reached. An outage is never evidence about the transaction. |
An API lookup is not cryptographic re-verification
404 is explicitly not reported as "does not exist". Treat CONFIRMED_SUCCESS as strong evidence from the network's own history API — and treat everything else as "unknown", not as a negative proof.Testnet faucet — real funding, mainnet refused
furlpay faucet --address G... --network testnet # or --network futurenetUses the official Stellar Friendbot on testnet/futurenet only; mainnet is refused outright because real XLM cannot be fabricated. FUNDED is reported only on the Friendbot's own successful response, together with the funding transaction hash and an independent Horizon balance check.
Diagnostics — validate config, check the doctor
furlpay config validate [--output json]
furlpay doctor [--output json]config validateLOCAL checks the local config structurally: canonical network passphrases, https endpoints, slippage/risk bounds, and agent-trust cap consistency. No network calls; non-zero exit on any error.doctorLIVE runs real install-method, registry and connectivity checks. In JSON mode it exits non-zero when the API connectivity check fails, so scripts can rely on the exit code.
Distribution security
- npm installs are integrity-checked by the registry; the package publishes with npm provenance (sigstore, OIDC-bound to the release repo and workflow).
- GitHub release assets (tarball,
checksums.txt, CycloneDX SBOM) carry build-provenance attestations:gh attestation verify --repo FurlPay/furlpay-cli <file>. - Release builds are gated on tag/version consistency, full typecheck and tests, and a three-OS smoke install (CLI boot + MCP stdio handshake) of the packed tarball before anything is published.
- No postinstall scripts; no secrets in the package; CI actions are SHA-pinned.
