openportfolio

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

  1. Write a module in packages/node/src/adapters/.
  2. Take the credential from the worker's environment.
  3. 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.