Skip to content

trader create-intent: accept human-friendly floats, convert to bigint via token-registry decimals #47

Description

@vrogojin

Why

Today the sphere trader create-intent CLI declares --rate-min <bigint> / --rate-max <bigint> / --volume-min <bigint> / --volume-max <bigint> and forwards the literal strings through to the trader's ACP CREATE_INTENT payload without conversion (see src/trader/trader-commands.ts:386-389 + :224-231). Operators must type fully-scaled smallest-unit integers — for example 80000000000000000 for 0.08 ETH per UCT given UCT is 18-decimal.

Per project owner UX guidance, the intended CLI surface is human-friendly floats: --rate-min 0.08, --volume-min 50. The CLI converts to bigint smallest-units internally via a token-registry decimals lookup before sending the ACP payload. The ACP wire format stays bigint-string (canonical JSON preserves precision); only the CLI surface changes.

This is the third leg of the three-way drift documented in sphere-sdk/blob/main/docs/uxf/PROTOCOL-SPEC-DRIFT-474.md finding D-NEW:

  • Design intent: float at CLI surface, bigint at ACP wire (convert at CLI boundary).
  • Spec (trader-service docs/protocol-spec.md §2.4 / §4.2): number end-to-end.
  • Implementation today: bigint-string end-to-end including the CLI.

The implementation side will stay on bigint (the ACP wire shouldn't change), the spec side is tracked separately in trader-service. This issue is the CLI side.

Scope

sphere trader create-intent is the primary surface. Same UX should apply to anywhere else in sphere trader (and sphere swap) that touches amounts or rates.

Behavior

  1. Default: accept floats. --rate-min 0.08 --rate-max 0.12 --volume-min 50 --volume-max 50. Convert via BigInt(Math.round(value × 10**decimals)) using each asset's decimals from the token registry. Send the bigint-string on the ACP wire.
  2. Power-user fallback: --rate-min-bigint <int> / --volume-min-bigint <int> etc. for operators who want to type the smallest-unit form explicitly. The two flag families are mutually exclusive per axis.
  3. Validation, pre-flight (CLI-side, before any DM):
    • Reject non-finite floats (NaN, Infinity).
    • Reject negatives / zero.
    • Reject more decimal digits than the asset supports (e.g. --rate-min 0.123456789012345678999 against an 18-decimal asset).
    • Reject --rate-min > --rate-max and --volume-min > --volume-max.
    • Report the resulting bigint in the CLI's confirmation log line so operators can sanity-check.
  4. Decimals source: token registry (@unicitylabs/sphere-sdk TokenRegistry.decimalsFor(coinId) or equivalent). If the registry has no entry for the asset, fall back to a reasonable default (18) and warn loudly. Do NOT silently assume 18 decimals — the warning is critical because UCT-on-mainnet may differ from UCT-on-testnet in some future revision.
  5. Help text: clarify the units. --rate-min <float> "Minimum acceptable rate (quote per base unit, decimal; e.g. 0.08 for 0.08 ETH per UCT)". --volume-min <float> "Minimum volume per match (in whole base-asset units; e.g. 50 for 50 UCT)".

Acceptance

  • sphere trader create-intent --tenant @x --direction sell --base UCT --quote ETH --rate-min 0.08 --rate-max 0.12 --volume-min 50 --volume-max 50 --expiry-ms 3600000 --json succeeds against a v0.1+ trader-agent image and the ACP payload's rate_min/rate_max/volume_min/volume_max are bigint strings of the right magnitude.
  • All four CLI float-validation guardrails reject malformed input with a clear local message (no DM round-trip).
  • sphere trader create-intent --help documents the float UX.
  • Unit tests cover the float→bigint conversion in buildCreateIntentParams.
  • Cross-check: when the sphere-sdk soak manual-test-trader-roundtrip.sh is re-run after this lands, the bigint-shim fallback (create_intent_with_shim second branch) is never taken — the first-attempt float form succeeds.

Out of scope

  • The trader-service spec patch (D1 in the drift audit) — tracked separately against vrogojin/trader-service.
  • The trader-agent image rebuild — tracked separately against vrogojin/agentic_hosting.
  • The ACP wire format — stays bigint-string.

Related

  • sphere-sdk#474 — trader-roundtrip soak (PR #475) — writes the float form already, with a bigint-shim fallback that this issue eliminates.
  • sphere-sdk PR #475 — manual-test-trader-roundtrip.sh exercises this UX.
  • sphere-sdk PROTOCOL-SPEC-DRIFT-474.md (in PR #475) — Finding D-NEW for the full three-way drift discussion.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions