Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/lib/api/orders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ async function collectProcessedOrderPages({
* request stream and converts them to ProcessedQuotes.
*/
export async function fetchAndQuotePaymentTokenOrders(
networkId: number = 8453,
networkId: number,
overridePaymentToken?: Token,
signal?: AbortSignal,
fetchOrders: OrdersQueryFetcher = apiQueryOrders
Expand Down Expand Up @@ -361,13 +361,14 @@ export async function fetchAndQuoteOwnerOrders(
): Promise<ProcessedQuote[]> {
const { paymentToken, allTokens } = resolveNetworkTokens(networkId, overridePaymentToken);
const chainId = networks.find((n) => n.id === networkId)?.chainId;
if (chainId === undefined) throw new Error(`Unknown network ${networkId}`);

const processedQuotes: ProcessedQuote[] = [];
const seen = new Set<string>();
let page = 1;
let hasMore = true;
while (hasMore && page <= MAX_ORDER_PAGES) {
const response = await apiGetOrdersByOwner(ownerAddress, { page, pageSize: 50 });
const response = await apiGetOrdersByOwner(ownerAddress, chainId, { page, pageSize: 50 });
for (const order of response.orders) {
if (chainId !== undefined && order.chainId !== chainId) continue;
if (seen.has(order.orderHash)) continue;
Expand Down Expand Up @@ -402,9 +403,11 @@ export async function fetchAndQuoteTokenOrders(
overridePaymentToken?: Token
) {
const { paymentToken, allTokens } = resolveNetworkTokens(networkId, overridePaymentToken);
const chainId = networks.find((network) => network.id === networkId)?.chainId;
if (chainId === undefined) throw new Error(`Unknown network ${networkId}`);

return collectProcessedOrderPages({
fetchPage: (page) => apiGetOrdersByToken(tokenAddress, { page, pageSize: 50 }),
fetchPage: (page) => apiGetOrdersByToken(tokenAddress, chainId, { page, pageSize: 50 }),
paymentToken,
allTokens,
networkId,
Expand Down
95 changes: 69 additions & 26 deletions src/lib/api/st0xApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ export interface ApiToken extends ApiTokenRef {
// ============================================================================

export interface ApiSwapQuoteRequest {
chainId: number;
inputToken: string;
outputToken: string;
outputAmount: string;
}

export interface ApiSwapQuoteResponse {
chainId: number;
inputToken: string;
outputToken: string;
outputAmount: string;
Expand All @@ -60,6 +62,7 @@ export interface ApiApproval {
}

export interface ApiSwapCalldataResponse {
chainId: number;
to: string;
data: string;
value: string;
Expand All @@ -70,6 +73,7 @@ export interface ApiSwapCalldataResponse {
export type ApiSwapCalldataMode = 'buyUpTo' | 'spendExact' | 'spendUpTo';

export interface ApiSwapV2RequestCommon {
chainId: number;
inputToken: string;
outputToken: string;
mode: ApiSwapCalldataMode;
Expand Down Expand Up @@ -156,6 +160,7 @@ export interface ApiOrdersQueryRequest {
// ============================================================================

export interface ApiTradeByAddress {
chainId: number;
txHash: string;
inputAmount: string;
outputAmount: string;
Expand All @@ -180,6 +185,7 @@ export interface ApiTradesByAddressResponse {
}

export interface ApiTradeByTxEntry {
chainId: number;
orderHash: string;
orderOwner: string;
request: {
Expand All @@ -196,6 +202,7 @@ export interface ApiTradeByTxEntry {
}

export interface ApiTradesByTxResponse {
chainId: number;
txHash: string;
blockNumber: number;
timestamp: number;
Expand Down Expand Up @@ -225,7 +232,7 @@ export interface ApiTradesBatchResponse {
export interface ApiTradesOrderHashesQueryRequest {
orderHashes: string[];
tokenAddresses?: string[];
chainId?: number;
chainId: number;
startTime?: number;
endTime?: number;
denomination?: 'wrapped' | 'unwrapped';
Expand Down Expand Up @@ -268,6 +275,7 @@ export interface ApiTokenProofReceipt {
}

export interface ApiTokenProofsResponse {
chainId: number;
address: string;
metadata: MetaV1S[];
schemas: ApiTokenProofSchema[];
Expand All @@ -279,11 +287,13 @@ export interface ApiTokenProofsResponse {
// ============================================================================

export interface ApiTokenDetailsError {
chainId: number;
address: string;
message: string;
}

export interface ApiTokenDetailsSummary {
chainId: number;
address: string;
deployTimestamp?: number;
receiptContractAddress?: string | null;
Expand Down Expand Up @@ -329,6 +339,7 @@ export interface ApiTokenDetailsListResponse {
// ============================================================================

export interface ApiWrapRatio {
chainId: number;
shareAddress: string;
assetAddress: string;
assetsPerShare: string;
Expand All @@ -338,6 +349,7 @@ export interface ApiWrapRatio {
}

export interface ApiWrapRatioError {
chainId: number;
shareAddress: string;
message: string;
}
Expand All @@ -356,6 +368,7 @@ export interface ApiWrapRatioHistoryEvent {
}

export interface ApiWrapRatioHistoryResponse {
chainId: number;
shareAddress: string;
assetAddress: string;
events: ApiWrapRatioHistoryEvent[];
Expand Down Expand Up @@ -440,6 +453,7 @@ function apiUrl(path: string, params?: Record<string, string | number | undefine
*/
export async function apiGetOrdersByToken(
tokenAddress: string,
chainId: number,
options?: {
page?: number;
pageSize?: number;
Expand All @@ -448,7 +462,8 @@ export async function apiGetOrdersByToken(
}
): Promise<ApiOrdersListResponse> {
assertBrowser('apiGetOrdersByToken');
const url = apiUrl(`/v1/orders/token/${tokenAddress}`, {
const url = apiUrl(`/v2/orders/token/${tokenAddress}`, {
chainId,
page: options?.page,
pageSize: options?.pageSize,
side: options?.side,
Expand All @@ -465,7 +480,7 @@ export async function apiQueryOrders(
signal?: AbortSignal
): Promise<ApiOrdersListResponse> {
assertBrowser('apiQueryOrders');
return fetchJson<ApiOrdersListResponse>(apiUrl('/v1/orders/query'), {
return fetchJson<ApiOrdersListResponse>(apiUrl('/v2/orders/query'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
Expand All @@ -476,37 +491,42 @@ export async function apiQueryOrders(
/**
* Fetch the canonical supported token list from the REST API.
*/
export async function apiGetTokens(): Promise<ApiToken[]> {
export async function apiGetTokens(chainId?: number): Promise<ApiToken[]> {
assertBrowser('apiGetTokens');
return fetchJson<ApiToken[]>(apiUrl('/v1/tokens'));
return fetchJson<ApiToken[]>(apiUrl('/v2/tokens', { chainId }));
}

/**
* Fetch raw proof/attestation metadata for a tokenized asset.
*/
export async function apiGetTokenProofs(address: string): Promise<ApiTokenProofsResponse> {
export async function apiGetTokenProofs(
address: string,
chainId: number
): Promise<ApiTokenProofsResponse> {
assertBrowser('apiGetTokenProofs');
return fetchJson<ApiTokenProofsResponse>(apiUrl(`/v1/tokens/${address}/proofs`));
return fetchJson<ApiTokenProofsResponse>(apiUrl(`/v2/tokens/${address}/proofs`, { chainId }));
}

/**
* Fetch ST0x token detail summaries from the REST API.
*/
export async function apiGetTokenDetails(): Promise<ApiTokenDetailsListResponse> {
export async function apiGetTokenDetails(chainId?: number): Promise<ApiTokenDetailsListResponse> {
assertBrowser('apiGetTokenDetails');
return fetchJson<ApiTokenDetailsListResponse>(apiUrl('/v1/tokens/details'));
return fetchJson<ApiTokenDetailsListResponse>(apiUrl('/v2/tokens/details', { chainId }));
}

/**
* Fetch ST0x token details and recent activity for a single token.
*/
export async function apiGetTokenDetailsByAddress(
address: string,
chainId: number,
options?: { activityLimit?: number }
): Promise<ApiTokenDetails> {
assertBrowser('apiGetTokenDetailsByAddress');
return fetchJson<ApiTokenDetails>(
apiUrl(`/v1/tokens/${address}/details`, {
apiUrl(`/v2/tokens/${address}/details`, {
chainId,
activityLimit: options?.activityLimit
})
);
Expand All @@ -515,29 +535,36 @@ export async function apiGetTokenDetailsByAddress(
/**
* Fetch current wrap ratios for supported wrapped tokens.
*/
export async function apiGetWrapRatios(): Promise<ApiWrapRatiosResponse> {
export async function apiGetWrapRatios(chainId?: number): Promise<ApiWrapRatiosResponse> {
assertBrowser('apiGetWrapRatios');
return fetchJson<ApiWrapRatiosResponse>(apiUrl('/v1/tokens/wrap-ratio'));
return fetchJson<ApiWrapRatiosResponse>(apiUrl('/v2/tokens/wrap-ratio', { chainId }));
}

/**
* Fetch current wrap ratio for a single wrapped token.
*/
export async function apiGetWrapRatio(wrappedTokenAddress: string): Promise<ApiWrapRatio> {
export async function apiGetWrapRatio(
wrappedTokenAddress: string,
chainId: number
): Promise<ApiWrapRatio> {
assertBrowser('apiGetWrapRatio');
return fetchJson<ApiWrapRatio>(apiUrl(`/v1/tokens/wrap-ratio/${wrappedTokenAddress}`));
return fetchJson<ApiWrapRatio>(
apiUrl(`/v2/tokens/wrap-ratio/${wrappedTokenAddress}`, { chainId })
);
}

/**
* Fetch snapshot history for a wrapped token's wrap ratio.
*/
export async function apiGetWrapRatioHistory(
wrappedTokenAddress: string,
chainId: number,
options?: { page?: number; pageSize?: number }
): Promise<ApiWrapRatioHistoryResponse> {
assertBrowser('apiGetWrapRatioHistory');
return fetchJson<ApiWrapRatioHistoryResponse>(
apiUrl(`/v1/tokens/wrap-ratio/${wrappedTokenAddress}/history`, {
apiUrl(`/v2/tokens/wrap-ratio/${wrappedTokenAddress}/history`, {
chainId,
page: options?.page,
pageSize: options?.pageSize
})
Expand All @@ -549,7 +576,7 @@ export async function apiGetWrapRatioHistory(
*/
export async function apiGetSwapQuote(request: ApiSwapQuoteRequest): Promise<ApiSwapQuoteResponse> {
assertBrowser('apiGetSwapQuote');
return fetchJson<ApiSwapQuoteResponse>(apiUrl('/v1/swap/quote'), {
return fetchJson<ApiSwapQuoteResponse>(apiUrl('/v2/swap/quote'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request)
Expand Down Expand Up @@ -578,7 +605,7 @@ export async function apiGetSwapCalldata(
request: ApiSwapCalldataRequest
): Promise<ApiSwapCalldataResponse> {
assertBrowser('apiGetSwapCalldata');
return fetchJson<ApiSwapCalldataResponse>(apiUrl('/v1/swap/calldata'), {
return fetchJson<ApiSwapCalldataResponse>(apiUrl('/v2/swap/calldata'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request)
Expand All @@ -605,10 +632,12 @@ export async function apiGetSwapCalldataV2(
*/
export async function apiGetTradesByAddress(
address: string,
chainId: number,
options?: { page?: number; pageSize?: number; startTime?: number; endTime?: number }
): Promise<ApiTradesByAddressResponse> {
assertBrowser('apiGetTradesByAddress');
const url = apiUrl(`/v1/trades/${address}`, {
const url = apiUrl(`/v2/trades/${address}`, {
chainId,
page: options?.page,
pageSize: options?.pageSize,
startTime: options?.startTime,
Expand All @@ -622,31 +651,40 @@ export async function apiGetTradesByAddress(
*/
export async function apiGetTakerTrades(
address: string,
chainId: number,
options?: { page?: number; pageSize?: number }
): Promise<ApiTradesByAddressResponse> {
assertBrowser('apiGetTakerTrades');
const url = apiUrl(`/v1/trades/taker/${address}`, {
const url = apiUrl(`/v2/trades/taker/${address}`, {
chainId,
page: options?.page,
pageSize: options?.pageSize
});
return fetchJson<ApiTradesByAddressResponse>(url);
}

/** Fetch the indexed trade totals for one confirmed transaction. */
export async function apiGetTradesByTx(txHash: string): Promise<ApiTradesByTxResponse> {
export async function apiGetTradesByTx(
txHash: string,
chainId: number
): Promise<ApiTradesByTxResponse> {
assertBrowser('apiGetTradesByTx');
return fetchJson<ApiTradesByTxResponse>(apiUrl(`/v1/trades/tx/${txHash}`), { retries: 0 });
return fetchJson<ApiTradesByTxResponse>(apiUrl(`/v2/trades/tx/${txHash}`, { chainId }), {
retries: 0
});
}

/**
* Fetch orders by owner address from the REST API
*/
export async function apiGetOrdersByOwner(
ownerAddress: string,
chainId: number,
options?: { page?: number; pageSize?: number; state?: 'active' | 'inactive' | 'all' }
): Promise<ApiOrdersListResponse> {
assertBrowser('apiGetOrdersByOwner');
const url = apiUrl(`/v1/orders/owner/${ownerAddress}`, {
const url = apiUrl(`/v2/orders/owner/${ownerAddress}`, {
chainId,
page: options?.page,
pageSize: options?.pageSize,
state: options?.state
Expand Down Expand Up @@ -675,7 +713,7 @@ export async function apiQueryTrades(
signal?: AbortSignal
): Promise<ApiTradesQueryResponse> {
assertBrowser('apiQueryTrades');
return fetchJson<ApiTradesQueryResponse>(apiUrl('/v1/trades/query'), {
return fetchJson<ApiTradesQueryResponse>(apiUrl('/v2/trades/query'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(request),
Expand All @@ -687,28 +725,33 @@ export async function apiQueryTrades(
* Fetch trades for multiple orders in a single query request.
* Used to compute filled amounts for a user's deployed orders.
*/
export async function apiGetTradesBatch(orderHashes: string[]): Promise<ApiTradesBatchResponse> {
return apiQueryTrades({ orderHashes });
export async function apiGetTradesBatch(
orderHashes: string[],
chainId: number
): Promise<ApiTradesBatchResponse> {
return apiQueryTrades({ orderHashes, chainId });
}

/**
* Fetch trades by token address from the REST API
*/
export async function apiGetTradesByToken(
tokenAddress: string,
chainId: number,
page: number = 1,
pageSize: number = 200,
startTime?: number,
endTime?: number
): Promise<ApiTradesByAddressResponse> {
assertBrowser('apiGetTradesByToken');
const params = new URLSearchParams({
chainId: String(chainId),
page: String(page),
pageSize: String(pageSize)
});
if (startTime !== undefined) params.set('startTime', String(startTime));
if (endTime !== undefined) params.set('endTime', String(endTime));
return fetchJson<ApiTradesByAddressResponse>(
`/api/st0x/v1/trades/token/${tokenAddress}?${params}`
`/api/st0x/v2/trades/token/${tokenAddress}?${params}`
);
}
2 changes: 1 addition & 1 deletion src/lib/clients/raindexSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function resolveRegistryManifestUrl(): string {
return new URL(REGISTRY_MANIFEST_URL, `${appOrigin()}/`).toString();
}

function settingsUrlFromManifest(manifest: string, manifestUrl: string): string {
export function settingsUrlFromManifest(manifest: string, manifestUrl: string): string {
const settingsEntry = manifest
.split(/\r?\n/)
.map((line) => line.trim())
Expand Down
Loading
Loading