This repository has been archived by the owner on Dec 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Stricten, test, and bugfix http-server (#170)
* Stricten, test, and bugfix http-server * PR comments * Update packages/http-server/tests/submit-close.spec.ts Co-authored-by: Jiyoon Koo <[email protected]> --------- Co-authored-by: Jiyoon Koo <[email protected]>
- Loading branch information
Showing
22 changed files
with
1,489 additions
and
378 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { Exchange } from '@tbdex/protocol' | ||
import { Message, Rfq, Quote, Order, OrderStatus, Close } from '@tbdex/protocol' | ||
import { ExchangesApi, GetExchangesFilter } from './main.js' | ||
|
||
/** | ||
* An in-memory implementation of {@link ExchangesApi} for example and default purposes. | ||
* InMemoryExchangesApi has additional methods {@link InMemoryExchangesApi.addMessage} | ||
* and {@link InMemoryExchangesApi.clearMessages} | ||
*/ | ||
export class InMemoryExchangesApi implements ExchangesApi { | ||
/** Map from exchange_id to Exchange */ | ||
exchangeMessagesMap: Map<string, Exchange> | ||
|
||
constructor() { | ||
this.exchangeMessagesMap = new Map<string, Exchange>() | ||
} | ||
|
||
async getExchanges(opts?: { filter: GetExchangesFilter }): Promise<Exchange[]> { | ||
if (opts === undefined || opts.filter === undefined) { | ||
// In production, this should probably return an empty list. | ||
// For example and testing purposes, we return all exchanges. | ||
|
||
return Array.from(this.exchangeMessagesMap.values()) | ||
} | ||
|
||
const exchanges: Exchange[] = [] | ||
if (opts.filter.id) { | ||
// filter has `id` and `from` | ||
|
||
for (const id of opts.filter.id) { | ||
const exchange = this.exchangeMessagesMap.get(id) | ||
if (exchange?.rfq?.from === opts.filter.from) { | ||
exchanges.push(exchange) | ||
} | ||
} | ||
} else { | ||
// filter only has `from` | ||
this.exchangeMessagesMap.forEach((exchange, _id) => { | ||
// You definitely shouldn't use InMemoryExchangesApi in production. | ||
// This will get really slow | ||
if (exchange?.rfq?.from === opts.filter.from) { | ||
exchanges.push(exchange) | ||
} | ||
}) | ||
} | ||
|
||
return exchanges | ||
} | ||
|
||
async getExchange(opts: { id: string} ): Promise<Exchange | undefined> { | ||
const exchange = this.exchangeMessagesMap.get(opts.id) | ||
return Promise.resolve(exchange) | ||
} | ||
|
||
async getRfq(opts: { exchangeId: string }): Promise<Rfq | undefined> { | ||
const exchange = this.exchangeMessagesMap.get(opts.exchangeId) | ||
return exchange?.rfq | ||
} | ||
|
||
async getQuote(opts: { exchangeId: string }): Promise<Quote | undefined> { | ||
const exchange = this.exchangeMessagesMap.get(opts.exchangeId) | ||
return Promise.resolve(exchange?.quote) | ||
} | ||
|
||
async getOrder(opts: { exchangeId: string }): Promise<Order | undefined> { | ||
const exchange = this.exchangeMessagesMap.get(opts.exchangeId) | ||
return exchange?.order | ||
} | ||
|
||
async getOrderStatuses(opts: { exchangeId: string }): Promise<OrderStatus[]> { | ||
const exchange = this.exchangeMessagesMap.get(opts.exchangeId) | ||
return exchange?.orderstatus ?? [] | ||
} | ||
|
||
async getClose(opts: { exchangeId: string }): Promise<Close | undefined> { | ||
const exchange = this.exchangeMessagesMap.get(opts.exchangeId) | ||
return exchange?.close | ||
} | ||
|
||
addMessage(message: Message): void { | ||
const exchange = this.exchangeMessagesMap.get(message.exchangeId) ?? new Exchange() | ||
exchange.addNextMessage(message) | ||
this.exchangeMessagesMap.set(message.exchangeId, exchange) | ||
} | ||
|
||
clearMessages(): void { | ||
this.exchangeMessagesMap = new Map<string, Exchange>() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { Offering } from '@tbdex/protocol' | ||
import { GetOfferingsFilter, OfferingsApi } from './types.js' | ||
|
||
/** | ||
* An in-memory implementation of {@link OfferingsApi} for example and default purposes. | ||
* InMemoryOfferingsApi has additional methods {@link InMemoryOfferingsApi.addOffering} | ||
* and {@link InMemoryOfferingsApi.clearOfferings} | ||
*/ | ||
export class InMemoryOfferingsApi implements OfferingsApi { | ||
/** Map from offering_id to Offering */ | ||
offeringsMap: Map<string, Offering> | ||
|
||
constructor() { | ||
this.offeringsMap = new Map<string, Offering>() | ||
} | ||
|
||
/** | ||
* Add a single offering | ||
* @param offering - Offering to be added to the {@link offeringsMap} | ||
*/ | ||
addOffering(offering: Offering): void { | ||
this.offeringsMap.set(offering.metadata.id, offering) | ||
} | ||
|
||
/** | ||
* Clear existing list offerings | ||
*/ | ||
clearOfferings(): void { | ||
this.offeringsMap.clear() | ||
} | ||
|
||
/** | ||
* Retrieve a single offering if found | ||
* @param opts - Filter with id used to select an offering | ||
* @returns An offering if one exists, else undefined | ||
*/ | ||
async getOffering(opts: { id: string }): Promise<Offering | undefined>{ | ||
return this.offeringsMap.get(opts.id) | ||
} | ||
|
||
/** | ||
* | ||
* @param opts - Filter used to select offerings | ||
* @returns A list of offerings matching the filter | ||
*/ | ||
async getOfferings(opts?: { filter: GetOfferingsFilter }): Promise<Offering[]> { | ||
const allOfferings = Array.from(this.offeringsMap.values()) | ||
|
||
if (opts?.filter === undefined || Object.values(opts.filter).every(v => v === undefined)) { | ||
// If no filter is provided, return all offerings | ||
return allOfferings | ||
} | ||
|
||
const { filter: { | ||
id, | ||
payinCurrency, | ||
payoutCurrency, | ||
payinMethodKind, | ||
payoutMethodKind, | ||
} } = opts | ||
|
||
return allOfferings.filter((offering) => { | ||
// If filter includes a field, make sure the returned offerings match | ||
return (!id || id === offering.metadata.id) && | ||
(!payinCurrency || payinCurrency === offering.data.payinCurrency.currencyCode) && | ||
(!payoutCurrency || payoutCurrency === offering.data.payoutCurrency.currencyCode) && | ||
(!payinMethodKind || offering.data.payinMethods.map(pm => pm.kind).includes(payinMethodKind)) && | ||
(!payoutMethodKind || offering.data.payoutMethods.map(pm => pm.kind).includes(payoutMethodKind)) | ||
}) | ||
} | ||
|
||
} |
Oops, something went wrong.