order new
command | order.new |
| Kind | Write |
| Needs | MOSTRO_PUBKEY, RELAYS, an existing identity, a writable store, --yes in JSON mode |
| Publishes | One new-order request signed with a fresh trade key |
| Local write | Reserves the next trade index; saves the order row with its trade key |
| Statuses | ok, error, uncertain |
| Schemas | schemas/order.new.input.json, schemas/order.new.output.json |
Creates an order as maker. A sell order sells sats for fiat; a buy order buys sats.
Invocation
mostro-cli --output json order new --side buy|sell --currency CODE --fiat-amount N
[--fiat-amount-max M] --payment-method TEXT [--sats N] [--premium N]
[--invoice INVOICE] [--expiration-days N] --yes
Replaces neworder and its short flags and the 100-200 range syntax.
Input
| Option | Required | Rule |
|---|---|---|
--side | yes | buy or sell, any letter case |
--currency | yes | 3 to 6 ASCII letters or digits; uppercased. The node decides which currencies it accepts |
--fiat-amount | yes | Integer > 0. With --fiat-amount-max it is the range minimum |
--fiat-amount-max | no | Integer > --fiat-amount. Makes a range order; then --sats must be 0 |
--payment-method | yes | Non-empty text, ≤ 200 bytes, no control characters. Comma-separate several methods |
--sats | no | Integer ≥ 0, default 0 = market price at take time |
--premium | no | Integer −100..100 percent over/under market, default 0 |
--invoice | no | ≤ 4096 bytes, no whitespace. A buyer’s invoice or Lightning address to be paid; which side may carry one is the node’s rule (normally a buy order) |
--expiration-days | no | 0..365, default 0 = the node’s default |
--yes | yes in JSON | Without it: invalid_arguments, exit 2, nothing done |
Local checks only catch what is cheap and certain. The node remains the authority
(currency list, amount limits, invoice amount); its refusals come back as node_refused.
Behavior
- Validate, read configuration and identity, check the store is writable.
- Reserve the next trade index and derive its key.
- Connect, probe the node (protocol, PoW), publish the request, wait for the reply (15 s).
- On acceptance, save the order row (with trade key and index) in one transaction.
The trade index is spent whenever the request was published and not provably refused, so a later attempt always uses a fresh key. The CLI never retries.
Success data: OrderNewData
| Field | Type | Meaning |
|---|---|---|
node_pubkey | hex64 | The node |
order | OrderRecord | The order as the node created it (status pending, or parked while a bond is due) |
next_step | wait_for_taker | pay_bond_invoice | What the maker does next |
payment_request | string or null | The bond invoice to pay; only with pay_bond_invoice |
trade_index | decimal string | Index of the order’s trade key |
trade_pubkey | hex64 | Public trade key of the order |
next_step | Meaning | Do |
|---|---|---|
wait_for_taker | The order is on the book | Watch message list for a taker |
pay_bond_invoice | The node requires a maker bond before publishing the order | Pay payment_request with a Lightning wallet; the node publishes the order once paid |
Outcomes
| Case | status | code | Stages (publication / daemon / persistence) |
|---|---|---|---|
| Created and saved | ok | published / accepted / applied | |
| Bond asked first | ok (pay_bond_invoice) | published / accepted / applied | |
Local failure, --yes missing | error | its code | not_attempted / unknown / not_attempted |
| Every relay refused the event | error | request_rejected | not_attempted / unknown / not_attempted |
| Refused by the node | error | node_refused + reason | published / rejected / not_attempted |
| Created, row not saved | uncertain | order_not_saved (data present) | published / accepted / failed |
| No reply / unusable reply / relay dropped wait | uncertain | reply_timeout, reply_malformed, relay_read_failed | published / unknown / applied or failed |
| PoW discovered too late | uncertain | pow_required | published / unknown / applied or failed |
| Relays answered ambiguously | uncertain | request_rejected | unknown / unknown / applied or failed |
On uncertain with daemon_acceptance: unknown, persistence refers to the reserved
trade index (spent: applied; could not be recorded: failed).
After uncertain, do not send order new again blindly: the node may already hold a
live order. Look for it first (message list, order list with your terms, or
order info if you have the id). See Recovering.
Errors
invalid_arguments, configuration_missing, configuration_invalid,
relay_connection_failed, relay_read_failed, internal_error, identity_missing,
identity_unreadable, protocol_unsupported, pow_required, request_rejected,
node_refused, order_declined (human prompt only), store_unwritable; uncertain:
reply_timeout, reply_malformed, request_rejected, relay_read_failed,
pow_required, order_not_saved.
Warnings
invalid_order_timestamp, invalid_event_timestamp, cleanup_incomplete.
Examples
A bonded node asks the maker to pay a bond first
order.new/bond_to_pay · status ok · exit 0 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer' --premium 2 --yes
{
"schema_version": "1",
"command": "order.new",
"status": "ok",
"data": {
"next_step": "pay_bond_invoice",
"node_pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"order": {
"buyer_trade_pubkey": null,
"created_at": "2026-10-16T00:00:00Z",
"created_at_unix": "1792108800",
"expires_at": "2026-10-17T00:00:00Z",
"expires_at_unix": "1792195200",
"fiat_amount": "100",
"fiat_amount_max": null,
"fiat_amount_min": null,
"fiat_currency": "USD",
"id": "00000000-0000-0000-0000-000000000007",
"payment_method": "bank transfer",
"premium_percent": "2",
"sats_amount": "0",
"seller_trade_pubkey": null,
"side": "sell",
"status": "pending"
},
"payment_request": "lnbcrt1bondinvoice",
"trade_index": "3",
"trade_pubkey": "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
},
"error": null,
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "accepted",
"persistence": "applied",
"snapshot": null
}
}
A market-price sell order created and saved
order.new/created · status ok · exit 0 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer' --premium 2 --yes
{
"schema_version": "1",
"command": "order.new",
"status": "ok",
"data": {
"next_step": "wait_for_taker",
"node_pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"order": {
"buyer_trade_pubkey": null,
"created_at": "2026-10-16T00:00:00Z",
"created_at_unix": "1792108800",
"expires_at": "2026-10-17T00:00:00Z",
"expires_at_unix": "1792195200",
"fiat_amount": "100",
"fiat_amount_max": null,
"fiat_amount_min": null,
"fiat_currency": "USD",
"id": "00000000-0000-0000-0000-000000000007",
"payment_method": "bank transfer",
"premium_percent": "2",
"sats_amount": "0",
"seller_trade_pubkey": null,
"side": "sell",
"status": "pending"
},
"payment_request": null,
"trade_index": "3",
"trade_pubkey": "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
},
"error": null,
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "accepted",
"persistence": "applied",
"snapshot": null
}
}
A fixed-price buy order with the buyer’s invoice attached
order.new/fixed_buy_with_invoice · status ok · exit 0 · authored
mostro-cli --output json order new --side buy --currency EUR --fiat-amount 50 --sats 60000 --payment-method SEPA --invoice lnbc600u1p... --yes
{
"schema_version": "1",
"command": "order.new",
"status": "ok",
"data": {
"node_pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"order": {
"id": "00000000-0000-0000-0000-000000000021",
"side": "buy",
"status": "pending",
"sats_amount": "60000",
"fiat_currency": "EUR",
"fiat_amount": "50",
"fiat_amount_min": null,
"fiat_amount_max": null,
"payment_method": "SEPA",
"premium_percent": "0",
"buyer_trade_pubkey": null,
"seller_trade_pubkey": null,
"created_at": "2026-11-02T09:00:00Z",
"created_at_unix": "1793610000",
"expires_at": "2026-11-03T09:00:00Z",
"expires_at_unix": "1793696400"
},
"next_step": "wait_for_taker",
"payment_request": null,
"trade_index": "7",
"trade_pubkey": "f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9"
},
"error": null,
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "accepted",
"persistence": "applied",
"snapshot": null
}
}
A range order 100-300 USD
order.new/range_created · status ok · exit 0 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --fiat-amount-max 300 --payment-method 'bank transfer' --premium 2 --yes
{
"schema_version": "1",
"command": "order.new",
"status": "ok",
"data": {
"next_step": "wait_for_taker",
"node_pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"order": {
"buyer_trade_pubkey": null,
"created_at": "2026-10-16T00:00:00Z",
"created_at_unix": "1792108800",
"expires_at": "2026-10-17T00:00:00Z",
"expires_at_unix": "1792195200",
"fiat_amount": "0",
"fiat_amount_max": "300",
"fiat_amount_min": "100",
"fiat_currency": "USD",
"id": "00000000-0000-0000-0000-000000000007",
"payment_method": "bank transfer",
"premium_percent": "2",
"sats_amount": "0",
"seller_trade_pubkey": null,
"side": "sell",
"status": "pending"
},
"payment_request": null,
"trade_index": "3",
"trade_pubkey": "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
},
"error": null,
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "accepted",
"persistence": "applied",
"snapshot": null
}
}
The node created the order but the local row could not be written; data is present
order.new/order_not_saved_uncertain · status uncertain · order_not_saved · exit 1 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer' --premium 2 --yes
{
"schema_version": "1",
"command": "order.new",
"status": "uncertain",
"data": {
"next_step": "wait_for_taker",
"node_pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
"order": {
"buyer_trade_pubkey": null,
"created_at": "2026-10-16T00:00:00Z",
"created_at_unix": "1792108800",
"expires_at": "2026-10-17T00:00:00Z",
"expires_at_unix": "1792195200",
"fiat_amount": "100",
"fiat_amount_max": null,
"fiat_amount_min": null,
"fiat_currency": "USD",
"id": "00000000-0000-0000-0000-000000000007",
"payment_method": "bank transfer",
"premium_percent": "2",
"sats_amount": "0",
"seller_trade_pubkey": null,
"side": "sell",
"status": "pending"
},
"payment_request": null,
"trade_index": "3",
"trade_pubkey": "c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5"
},
"error": {
"code": "order_not_saved",
"message": "The node created the order but it could not be saved locally."
},
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "accepted",
"persistence": "failed",
"snapshot": null
}
}
Published, then the relays dropped the wait; recording the spent index also failed
order.new/relay_read_failed_uncertain · status uncertain · relay_read_failed · exit 1 · authored
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method Zelle --yes
{
"schema_version": "1",
"command": "order.new",
"status": "uncertain",
"data": null,
"error": {
"code": "relay_read_failed",
"message": "A configured relay failed during the public order read."
},
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "unknown",
"persistence": "failed",
"snapshot": null
}
}
Published, no answer: the order may exist; the trade index was spent
order.new/reply_timeout_uncertain · status uncertain · reply_timeout · exit 1 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer' --yes
{
"schema_version": "1",
"command": "order.new",
"status": "uncertain",
"data": null,
"error": {
"code": "reply_timeout",
"message": "The node did not answer before the deadline."
},
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "unknown",
"persistence": "applied",
"snapshot": null
}
}
Relays answered ambiguously: the event may be out there; the index was spent
order.new/request_rejected_uncertain · status uncertain · request_rejected · exit 1 · authored
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method Zelle --yes
{
"schema_version": "1",
"command": "order.new",
"status": "uncertain",
"data": null,
"error": {
"code": "request_rejected",
"message": "No relay confirmed accepting the request."
},
"warnings": [],
"meta": {
"publication": "unknown",
"daemon_acceptance": "unknown",
"persistence": "applied",
"snapshot": null
}
}
No local identity: nothing was sent
order.new/identity_missing · status error · identity_missing · exit 1 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer' --yes
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "identity_missing",
"message": "No local identity exists."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
Write-command stages on a local failure
order.new/identity_missing_captured · status error · identity_missing · exit 1 · captured
mostro-cli --output json --mostro-pubkey 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 --relays ws://127.0.0.1:1 order new --side sell --currency USD --fiat-amount 10 --payment-method SEPA --yes
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "identity_missing",
"message": "No local identity exists."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
The node refused with reason invalid_amount
order.new/node_refused · status error · node_refused · exit 1 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 1 --payment-method 'bank transfer' --yes
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "node_refused",
"message": "The node refused the request.",
"reason": "invalid_amount"
},
"warnings": [],
"meta": {
"publication": "published",
"daemon_acceptance": "rejected",
"persistence": "not_attempted",
"snapshot": null
}
}
The outcome of answering n at the human prompt; a JSON caller never sees it because JSON requires –yes
order.new/order_declined · status error · order_declined · exit 1 · fixture
mostro-cli order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer'
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "order_declined",
"message": "The order was not confirmed, so nothing was sent."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
Not enough proof of work configured: nothing sent
order.new/pow_required · status error · pow_required · exit 1 · authored
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method Zelle --yes
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "pow_required",
"message": "The node requires more proof of work than is configured."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
Every relay explicitly rejected the event: provably nothing sent, a plain error
order.new/request_rejected_error · status error · request_rejected · exit 1 · authored
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method Zelle --yes
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "request_rejected",
"message": "No relay confirmed accepting the request."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
The database is read-only, so the index cannot be reserved: nothing sent
order.new/store_unwritable · status error · store_unwritable · exit 1 · authored
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method Zelle --yes
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "store_unwritable",
"message": "The local store cannot be written, so nothing was sent."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
The removed neworder spelling
order.new/removed_spelling · status error · invalid_arguments · exit 2 · fixture
mostro-cli --output json neworder -k sell -c USD -f 100 -m bank
{
"schema_version": "1",
"command": null,
"status": "error",
"data": null,
"error": {
"code": "invalid_arguments",
"message": "The command arguments are invalid."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}
JSON mode without –yes is an argument error; nothing is done
order.new/yes_required · status error · invalid_arguments · exit 2 · fixture
mostro-cli --output json order new --side sell --currency USD --fiat-amount 100 --payment-method 'bank transfer'
{
"schema_version": "1",
"command": "order.new",
"status": "error",
"data": null,
"error": {
"code": "invalid_arguments",
"message": "The command arguments are invalid."
},
"warnings": [],
"meta": {
"publication": "not_attempted",
"daemon_acceptance": "unknown",
"persistence": "not_attempted",
"snapshot": null
}
}