Venue adapters
An adapter declares what it can do and implements only that.
type VenueAdapter = {
venue: string;
kind: AccountKind;
capabilities: { canReadBalances: boolean; canReadQuotes: boolean; canPlaceOrders: boolean };
readBalances(request: ReadBalancesRequest): Promise<AdapterBalance[]>;
readQuote(request: ReadQuoteRequest): Promise<AdapterQuote>;
placeOrder?(request: PlaceOrderRequest): Promise<OrderReceipt>;
};
What ships
| Adapter | Reads balances | Reads quotes | Key |
|---|---|---|---|
coingecko |
No, on purpose | Yes | None |
manual |
Yes, from a JSON file | No | None |
coingecko refuses balances rather than returning an empty list, because a price source does not
know what you hold and an empty list reads as "you hold nothing".
Adding a keyed broker
- Write a module in
packages/node/src/adapters/. - Take the credential from the worker's environment.
- Register it in
defaultRegistry().
Keep the credential in the worker process. The backend never sees it and neither does this repository. That is why no keyed adapter ships: the useful ones all need a secret, and a public tree is the wrong place to normalise putting one.
If you implement placeOrder
type PlaceOrderRequest = {
// ...
confirmation: OrderConfirmation; // { confirmedBy, confirmedAt }
};
OrderConfirmation has no default. An order that no human confirmed cannot be constructed, which
is a type error rather than a policy someone can forget.