mirror of
https://github.com/hanzo-fi/payments.git
synced 2026-10-30 20:31:20 +00:00
* feat(orders,conversions): add read-only orders & conversions support
Extract read-only orders and conversions capabilities from the
exchange-connectivity feature branch. This includes GET API endpoints,
sync workflows from exchanges, and storage layer — without any
write operations (create, cancel, update status).
Scope:
- Models: Order, Conversion types with enums and IDs
- Migration: tables orders, order_adjustments, conversions
- Storage: Upsert, Get, List, DeleteFromConnectorID
- API: GET /orders, GET /orders/{id}, GET /conversions, GET /conversions/{id}
- Workflows: FetchNextOrders, FetchNextConversions, FetchExchangeData
- Activities: PluginFetchNextOrders/Conversions, StorageOrdersUpsert/Get, StorageConversionsUpsert
- Plugin: coinbaseprime fetch orders/conversions support
- OpenAPI: schemas and GET endpoints for orders/conversions
* fix(orders,conversions): address review findings from code review
- Add TASK_FETCH_ORDERS/CONVERSIONS cases in runNextTasksV3_1 (was blocking connector install)
- Format assets with currency.FormatAsset (BTC -> BTC/8) to pass validation
- Fix BUY/SELL source/target asset semantics
- Add Raw to OrderAdjustment/Conversion MarshalJSON/UnmarshalJSON
- Add Adjustments to OrderExpanded.MarshalJSON
- Protect enum Value() against writing UNKNOWN to DB
- Add missing index on order_adjustments(order_id)
- Fix createdAt idempotency (error instead of time.Now fallback)
- Fix PARTIALLY_FILLED detection with numeric comparison
- Propagate conversion errors instead of silently skipping
- Qualify columns in conversionsQueryContext
- Remove dead code StorageOrdersGet activity
- Remove empty CAPABILITY_FETCH_CONVERSIONS from coinbaseprime
- Remove unnecessary transaction in ConversionsUpsert
- Fix walletId -> walletID for naming consistency
- Fix %v -> %w in workflow error wrapping
- Add raw field to V3OrderAdjustment OpenAPI schema
* feat: generated
* feat(coinbaseprime): network-scoped symbols, thread-safe currencies & gross amount docs
Add network-scoped symbol resolution (e.g. BASEUSDC → USDC) to handle
Coinbase Prime assets that expose network aliases. Introduce thread-safe
lazy loading of currencies via sync.Mutex with double-checked locking
pattern (ensureCurrencies). Document gross amount convention across
models and connector template.
* feat: pre-commit
* test(coinbaseprime): add unit tests for orders fetching
Cover all order conversion paths: BUY/SELL direction, status mapping
(including PARTIALLY_FILLED detection), order types, time-in-force
variants, error cases, pagination, and edge cases for empty fields.
* feat(workbench): add orders & conversions support with Exchange plugin type
Integrate Orders and Conversions into the workbench tool so connectors
declaring TASK_FETCH_ORDERS or TASK_FETCH_CONVERSIONS are fully exercised
during local development.
Backend: task recognition, response types, in-memory storage, engine
fetch loops, HTTP endpoints, and baseline capture.
Frontend: Order/Conversion types and API methods, dedicated tabs with
table views and detail panels, dashboard buttons and stat cards.
Also adds PluginTypeExchange enum value and reclassifies CoinbasePrime
from PSP to Exchange with distinct UI badge styling.
* feat(coinbaseprime): implement conversions support and update capabilities
- Replace capability for fetching exchange data with fetching conversions in the Coinbase Prime plugin.
- Introduce new functionality to fetch conversions, including error handling and state management.
- Add comprehensive unit tests for conversions, covering various scenarios and edge cases.
- Update the plugin to handle wallet mappings and ensure thread safety for currency operations.
- Enhance event handling for order-related activities, including sending events for order adjustments.
* fix: address CodeRabbit review findings
- Fix data race in ensureCurrencies (always take lock before reading)
- Fix JSON round-trip on UNKNOWN enums (accept "UNKNOWN" in FromString)
- Add missing sort_id to conversion storage struct
- Remove IF NOT EXISTS from versioned migration SQL
- Use direct enum comparison in Value() methods
Made-with: Cursor
* feat(conversions): add EventsSendConversion activity and event handling
- Introduced EventsSendConversion activity to publish conversion events.
- Updated workflow to send conversion events when the event outbox pattern is disabled.
- Enhanced event message structure for conversions, including new fields and JSON marshaling.
- Added event type for saved conversions in the events package.
This update improves the handling of conversion events, ensuring they are properly published and managed within the workflow.
* feat(api): enhance OpenAPI schema with new connector type and conversion fields
- Added `connectorType` field to the V3Connector schema, referencing the new V3ConnectorTypeEnum.
- Updated conversion-related schemas to replace `targetAsset` with `destinationAsset` and added new fields: `quoteAmount`, `quoteAsset`, `priceAsset`, `sourceAccountID`, and `destinationAccountID`.
- Introduced V3ConnectorTypeEnum with enumerated values: PSP, OPEN_BANKING, BOTH, and EXCHANGE.
- Updated documentation to reflect changes in API responses and models.
This update improves the clarity and functionality of the API, ensuring better integration and usage of connector types and conversion details.
* Update connector capabilities JSON to reflect new and modified connectors
- Replaced the "coinbaseprime" capability for fetching exchange data with fetching conversions.
- Added "bankingbridge" connector with its associated capabilities.
- Updated "coinbaseprime" to include fetching conversions and removed fetching exchange data.
- Ensured consistency in connector capabilities across the document.
This change enhances the accuracy of connector capabilities and supports the latest integration requirements.
* fix: ensure connectors are enriched only when cursor is not nil
- Added a nil check for the cursor before enriching connectors with type.
- This change prevents potential nil pointer dereference errors and improves the robustness of the ConnectorsList function.
* test: add unit tests for conversion and order message payloads
- Introduced comprehensive tests for `ConversionMessagePayload` and `OrderMessagePayload` to validate JSON marshaling and unmarshaling.
- Added scenarios to check handling of all fields, including optional and nil values, ensuring robust serialization and deserialization.
- Implemented round-trip tests to confirm data integrity during JSON conversion.
- Enhanced coverage for conversion statuses and order directions with dedicated tests for their string representations and JSON handling.
This update improves the reliability of message payloads and ensures adherence to expected behaviors in various scenarios.
* refactor: remove deprecated order and conversion event handling
- Deleted the EventsSendOrder and EventsSendConversion activities as they are no longer used in the workflow.
- Updated the workflow to handle order and conversion events using a new outbox pattern, improving event management.
- Enhanced the fetchOrders and fetchConversions functions to marshal event payloads and insert them into the outbox.
- Added unit tests for new event structures to ensure proper functionality and data integrity.
This update streamlines event handling and prepares the codebase for future enhancements.
* feat(connectors): add connectorType field and enhance JSON handling
- Introduced `connectorType` field in the ConnectorBase and Connector structs to support new connector types.
- Updated JSON marshaling and unmarshaling methods to include the new field, ensuring proper serialization.
- Enhanced the PluginTypeFromString function to map string values to the new PluginType enum.
- Modified BaselineDiff and BaselineManager to include order and conversion comparisons, improving data integrity checks.
This update enhances the connector model and improves the handling of orders and conversions in the workbench tool.
* fix(coinbaseprime): Enhance transaction handling
- Modified transaction handling in the Coinbase Prime plugin to improve conversion processing and metadata management.
- Refactored transaction and order methods to utilize the new currency library for precision handling.
- Enhanced metadata handling by introducing a prefix for Coinbase-specific fields, ensuring consistency across transaction types.
This update improves the development environment and enhances the robustness of transaction processing in the Coinbase Prime plugin.
* refactor(connectors): remove connectorType field and related references
- Eliminated the `connectorType` field from the ConnectorBase and Connector structs, simplifying the connector model.
- Updated JSON marshaling and unmarshaling methods to reflect the removal of the `connectorType` field.
- Removed the V3ConnectorTypeEnum and its associated documentation, as it is no longer needed.
- Adjusted the ConnectorsList service to enhance error handling and streamline connector processing.
This update cleans up the connector model and improves the overall codebase by removing unnecessary complexity.
* fix: migration ordering
* fix: wrong usage of outbox event and ensure we create adjustments on important changes
* fix: pre-existing test failures
* fix: make conversion use transactions for outbox events
* fix: improve comment on ClientOrderID field
* fix: added a bunch of missing tests
* fix: nitpicks on indentation & openAPI field names
* fix: review assets & wallet loading. IMHO a controversial commit, I don't like it much
* feat: added account_lookup capability for plugins
* feat: added boostraping workflows
* feat: add boostraping to the install workflow
* feat: enable the new feature to ensure Coinbase loads wallets correctly
* refactor: merge 2 migrations
* fix: move non dependant tasks non children of fetch accounts
* fix: avoid refetching everything all the time; also introduce walletType as it's a mandatory parameter for fetchAccounts
* fix: ensure we start sub tasks as required
* doc: quick improvement on docs
* fix: rename field to be consistent with api
* fix: reset source adn dest account ids on conversions & orders during unmarshalling
* fix: render a valid PSPOrder when calling toPSPOrder
* fix: remove the misleading idempotency key on order model
* fix: use the new feature to generate account id from ID & ref even in payments
* feat: enable health monitoring for the new capabilities
* fix: ensure wallets/currency map is getting only one account
* doc: mention the new interface capabilities for plugins
* doc: improve openapi doc
* doc: add to contributing.md
* fix: make it clear only fetchNExtAccount is available in bootstrap right now
* fix: make sure we tests all capabilities in the healthcheck test
* fix: generate sdk
* feat: use schedule for surfacing bootstraping/install issues in the UI
* fix: ensure we're loading the currencies at the right time
* fix: simplify claude.md
* doc: improve openapi docs
* fix: regenerate pkg
* fix: update .codecov setting to ignore all generated files
* test: added extra coverage of base models
---------
Co-authored-by: thierrycoopman <[email protected]>
Co-authored-by: fabrice guery <[email protected]>
52 KiB
52 KiB
V3Order
A trade order submitted to an exchange-style PSP. Orders are read-only
in the Formance API: they are fetched from the underlying connector.
Status transitions are captured via the adjustments array; each
adjustment is a point-in-time snapshot from the PSP.
Fields
| Field | Type | Required | Description |
|---|---|---|---|
ID |
string | ✔️ | Formance-assigned unique order ID (composed from the PSP reference and connector ID). |
ConnectorID |
string | ✔️ | ID of the Formance connector this order was fetched from. |
Provider |
string | ✔️ | Provider name of the connector (e.g. coinbaseprime). |
Reference |
string | ✔️ | PSP-assigned order reference. Unique within the connector; used as the storage dedup key. |
ClientOrderID |
*string | ➖ | Client-assigned ID supplied to the PSP for placement idempotency (e.g. Coinbase client_order_id, Kraken cl_ord_id, BinanceclientOrderId). Stored for traceability only — Formance doesNOT dedup on this field. |
CreatedAt |
time.Time | ✔️ | When the order was created on the PSP. |
UpdatedAt |
time.Time | ✔️ | When Formance last observed a state change on the order. Equivalent to the latest adjustment's createdAt. |
Direction |
components.V3OrderDirectionEnum | ✔️ | Whether an order buys or sells the base asset. |
SourceAsset |
string | ✔️ | Asset being spent, in SYMBOL/precision form (e.g. USD/2,BTC/8). For BUY: the quote currency. For SELL: the basecurrency. |
DestinationAsset |
string | ✔️ | Asset being received, in SYMBOL/precision form.For BUY: the base currency. For SELL: the quote currency. |
Type |
components.V3OrderTypeEnum | ✔️ | Exchange order type. Determines which price fields are meaningful onV3Order: LIMIT-family types use limitPrice; STOP-family types usestopPrice; TWAP/VWAP are time-weighted execution algorithms. |
Status |
components.V3OrderStatusEnum | ✔️ | Lifecycle of an order on the exchange.PENDING — accepted by the exchange, not yet working.OPEN — live on the book, no fills yet.PARTIALLY_FILLED — live on the book, some base quantity filled.FILLED — fully filled, terminal.CANCELLED — cancelled by the user or system, terminal.FAILED — rejected by the exchange, terminal. See error for details.EXPIRED — timeInForce elapsed before full fill, terminal. |
BaseQuantityOrdered |
*big.Int | ✔️ | Amount of base asset the order was placed for, as an integer at the base asset's precision. |
BaseQuantityFilled |
*big.Int | ➖ | Amount of base asset filled so far, as an integer at the base asset's precision. Null before any fill. |
LimitPrice |
*big.Int | ➖ | Maximum price (for BUY) or minimum price (for SELL) at which the order may execute, in priceAsset precision. Required for LIMIT-family order types; null otherwise. |
StopPrice |
*big.Int | ➖ | Trigger price at which a STOP / STOP_LIMIT order activates, in priceAsset precision. Null for non-stop order types. |
TimeInForce |
components.V3TimeInForceEnum | ✔️ | How long an order is valid on the exchange.GOOD_UNTIL_CANCELLED — rests until explicitly cancelled.GOOD_UNTIL_DATE_TIME — rests until expiresAt.IMMEDIATE_OR_CANCEL — fill immediately, cancel any unfilled portion.FILL_OR_KILL — fill fully and immediately, or cancel entirely. |
ExpiresAt |
*time.Time | ➖ | Expiration instant for GOOD_UNTIL_DATE_TIME orders. Null for other time-in-force values. |
Fee |
*big.Int | ➖ | Commission charged by the PSP for the order, as an integer in feeAsset precision. |
FeeAsset |
*string | ➖ | Currency the fee is denominated in, in SYMBOL/precision form. Typically the quote asset. |
AverageFillPrice |
*big.Int | ➖ | Volume-weighted average price across all fills so far, in priceAsset precision. Analytics field — may be absent if the PSP does not report it. |
QuoteAmount |
*big.Int | ➖ | Total amount of quote currency exchanged so far, as reported by the PSP (e.g. Coinbase filled_value), at quoteAssetprecision. For BUY: amount spent. For SELL: amount received. |
QuoteAsset |
*string | ➖ | Quote currency with precision (e.g. USD/2). Null when the order has no quote-side amounts reported yet. |
PriceAsset |
*string | ➖ | Currency + precision under which limitPrice, stopPrice, andaverageFillPrice should be interpreted. Separate fromquoteAsset because some PSPs return price strings with moredecimal digits than the quote currency's natural precision. |
SourceAccountID |
*string | ➖ | Formance account ID of the wallet the source asset was debited from. Null if the PSP did not return enough information to resolve it at ingestion time. |
DestinationAccountID |
*string | ➖ | Formance account ID of the wallet the destination asset was credited to. Null if unresolvable. |
Metadata |
map[string]string | ➖ | N/A |
Adjustments |
[]components.V3OrderAdjustment | ➖ | Ordered history of state snapshots for this order. The most recent element reflects the current status. |
Error |
*string | ➖ | Human-readable error from the PSP (e.g. rejection reason) when status is FAILED. Null otherwise. |