OpenPoly logo
Wallet Adapter

Overview

Overview of the operator wallet adapter contract.

Overview

Wallet adapter is operator-owned server-to-server API used by OpenPoly to read balances and execute wallet mutations.

Ownership split

OpenPoly owns:

  • Mini App UI
  • quote and execution pipeline
  • trade and redemption state
  • webhook dispatch

Operator owns:

  • wallet balances
  • debit and credit execution
  • wallet auth secret
  • wallet operation observability

Required contract paths

  • GET /balance
  • POST /debit
  • POST /credit
  • POST /debit-reversal

REST v1 has path-based mutation direction. OpenPoly selects the endpoint from the operation type; the JSON request body does not include a direction field.

The shared adapter config also has a credit_reversal_path field for compatibility with the internal direction enum, but the current Mini App trade/redemption processor does not call POST /credit-reversal in production flows.

Mutation request body

All mutation endpoints use the same JSON body shape:

{
  "external_user_id": "operator-user-123",
  "amount_minor": 10000,
  "currency_code": "IDR",
  "idempotency_key": "mini_app_order:1:debit",
  "reason": "mini_app_buy_order",
  "metadata": {}
}

OpenPoly sends every field below on every mutation request.

FieldTypeRequirementNotes
external_user_idstringRequiredStable operator-side user ID.
amount_minorintegerRequiredAmount in the currency's minor unit. Current REST v1 operators use IDR.
currency_codestringRequiredCurrent production value: IDR.
idempotency_keystringRequiredDurable deduplication key.
reasonstringRequiredBusiness reason such as mini_app_buy_order, mini_app_sell_order, mini_app_redemption, or mini_app_buy_compensation.
metadataobjectRequiredAlways sent; may be empty. Fields vary by flow and must be treated as additive.

external_user_id is required for debit, credit, and reversal paths. OpenPoly resolves it from the Mini App launch/session user and sends it again on each wallet mutation.

Required metadata by flow

Metadata is part of the production contract. Operators must accept additional fields without rejecting the request.

FlowReasonRequired metadataOptional additive metadata
Buy debitmini_app_buy_orderorderId, marketIdoutcome
Buy compensationmini_app_buy_compensationorderId, marketIdbalanceOperationId
Sell creditmini_app_sell_orderorderId, marketIdoutcome
Redemption creditmini_app_redemptionredemptionItemId, marketIdNone currently

The full-contract adapter test uses mini_app_wallet_adapter_test with test-only metadata. It is not a market trade or redemption and is exempt from this production matrix.

Core rules

  • Every mutation must be idempotent.
  • Direct mutation response status is required and must be succeeded, failed, or pending. Other response fields are optional unless an endpoint page says otherwise.
  • A timeout, network failure, pending, HTTP 408, HTTP 429, or HTTP 5xx leaves the primary mutation outcome ambiguous and sends the order to manual review.
  • Do not retry an ambiguous primary debit or credit automatically. An operator may already have applied it.
  • Buy compensation may retry with its original idempotency key because the repeated request must return the original effective result.
  • Unknown wallet state must not be reported as success.
  • OpenPoly order state and wallet state are not one atomic transaction.
  • Manual review may be required when remote wallet result is unknown.
Authorization: Bearer {opera...ken}
X-Polynion-Request-Id: req_...
X-Polynion-Timestamp: 2026-06-18T00:00:00.000Z

Optional request signing may also be enabled with X-Polynion-Signature.

Dashboard setup

Operator admins configure the adapter in Operator Dashboard → Integrations → Wallet Adapter.

The dashboard stores:

  • base URL;
  • bearer token;
  • optional signing secret;
  • timeout and path overrides.

Bearer and signing secrets are encrypted before storage. After saving, OpenPoly only shows whether a secret is configured; plaintext and encrypted payloads are never returned by the API.

Validation tests

The dashboard exposes two validation modes:

  1. Connection test — calls only GET /balance for a supplied external user ID. It does not mutate wallet state.
  2. Full contract test — performs real wallet mutations against a dedicated test user and small amount. It validates balance, debit, debit reversal, credit, a second debit, and final balance. The final balance must equal the initial balance.

Full contract tests require explicit confirmation because compensation can fail or become unknown. If a compensation step fails, OpenPoly reports requires_manual_review so the operator can inspect and reconcile the remote wallet manually.

Copyright © 2026