@make-software/cspr-trade-mcp-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +257 -0
- package/dist/assets/proxy_caller.wasm +0 -0
- package/dist/index.d.ts +362 -0
- package/dist/index.js +1003 -0
- package/package.json +32 -0
- package/src/api/currencies.ts +11 -0
- package/src/api/http.ts +57 -0
- package/src/api/index.ts +9 -0
- package/src/api/liquidity.ts +22 -0
- package/src/api/pairs.ts +77 -0
- package/src/api/quotes.ts +23 -0
- package/src/api/rates.ts +33 -0
- package/src/api/submission.ts +42 -0
- package/src/api/swaps.ts +24 -0
- package/src/api/tokens.ts +57 -0
- package/src/assets/index.ts +21 -0
- package/src/assets/proxy_caller.wasm +0 -0
- package/src/client.ts +587 -0
- package/src/config.ts +60 -0
- package/src/index.ts +4 -0
- package/src/resolver/currency-resolver.ts +19 -0
- package/src/resolver/index.ts +2 -0
- package/src/resolver/token-resolver.ts +43 -0
- package/src/transactions/approve.ts +14 -0
- package/src/transactions/index.ts +5 -0
- package/src/transactions/liquidity.ts +92 -0
- package/src/transactions/proxy-wasm.ts +33 -0
- package/src/transactions/swap.ts +76 -0
- package/src/transactions/transaction-builder.ts +44 -0
- package/src/types/api.ts +32 -0
- package/src/types/index.ts +6 -0
- package/src/types/liquidity.ts +72 -0
- package/src/types/pair.ts +29 -0
- package/src/types/quote.ts +41 -0
- package/src/types/token.ts +48 -0
- package/src/types/transaction.ts +72 -0
- package/src/utils/amounts.ts +30 -0
- package/tests/integration/api.integration.test.ts +64 -0
- package/tests/unit/api/http.test.ts +68 -0
- package/tests/unit/api/liquidity.test.ts +40 -0
- package/tests/unit/api/pairs.test.ts +53 -0
- package/tests/unit/api/quotes.test.ts +59 -0
- package/tests/unit/api/rates.test.ts +27 -0
- package/tests/unit/api/tokens.test.ts +100 -0
- package/tests/unit/assets/proxy-caller.test.ts +21 -0
- package/tests/unit/client.test.ts +73 -0
- package/tests/unit/config.test.ts +23 -0
- package/tests/unit/resolver/currency-resolver.test.ts +32 -0
- package/tests/unit/resolver/token-resolver.test.ts +51 -0
- package/tests/unit/transactions/approve.test.ts +13 -0
- package/tests/unit/transactions/liquidity.test.ts +59 -0
- package/tests/unit/transactions/proxy-wasm.test.ts +50 -0
- package/tests/unit/transactions/swap.test.ts +77 -0
- package/tests/unit/utils/amounts.test.ts +44 -0
- package/tsconfig.json +9 -0
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@make-software/cspr-trade-mcp-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format esm --dts && mkdir -p dist/assets && cp src/assets/proxy_caller.wasm dist/assets/",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"casper-js-sdk": "^5.0.6",
|
|
22
|
+
"big.js": "^6.2.2",
|
|
23
|
+
"blakejs": "^1.2.1",
|
|
24
|
+
"@noble/hashes": "^1.7.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/big.js": "^6.2.2",
|
|
28
|
+
"tsup": "^8.0.0",
|
|
29
|
+
"typescript": "^5.7.0",
|
|
30
|
+
"vitest": "^3.0.0"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Currency, ApiResponse } from '../types/index.js';
|
|
2
|
+
import type { HttpClient } from './http.js';
|
|
3
|
+
|
|
4
|
+
export class CurrenciesApi {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
async getCurrencies(): Promise<Currency[]> {
|
|
8
|
+
const response = await this.http.get<ApiResponse<Currency[]>>('/currencies');
|
|
9
|
+
return response.data;
|
|
10
|
+
}
|
|
11
|
+
}
|
package/src/api/http.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export class HttpClientError extends Error {
|
|
2
|
+
constructor(
|
|
3
|
+
message: string,
|
|
4
|
+
public readonly status: number,
|
|
5
|
+
public readonly body?: unknown,
|
|
6
|
+
) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'HttpClientError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class HttpClient {
|
|
13
|
+
constructor(
|
|
14
|
+
private readonly baseUrl: string,
|
|
15
|
+
private readonly headers: Record<string, string> = {},
|
|
16
|
+
) {}
|
|
17
|
+
|
|
18
|
+
async get<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T> {
|
|
19
|
+
const url = this.buildUrl(path, params);
|
|
20
|
+
const response = await fetch(url, {
|
|
21
|
+
method: 'GET',
|
|
22
|
+
headers: { 'Content-Type': 'application/json', ...this.headers },
|
|
23
|
+
});
|
|
24
|
+
return this.handleResponse<T>(response);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async post<T>(path: string, body: unknown): Promise<T> {
|
|
28
|
+
const url = this.buildUrl(path);
|
|
29
|
+
const response = await fetch(url, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: { 'Content-Type': 'application/json', ...this.headers },
|
|
32
|
+
body: JSON.stringify(body),
|
|
33
|
+
});
|
|
34
|
+
return this.handleResponse<T>(response);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private buildUrl(path: string, params?: Record<string, string | number | undefined>): string {
|
|
38
|
+
const url = new URL(path, this.baseUrl);
|
|
39
|
+
if (params) {
|
|
40
|
+
for (const [key, value] of Object.entries(params)) {
|
|
41
|
+
if (value !== undefined) {
|
|
42
|
+
url.searchParams.set(key, String(value));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return url.toString();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private async handleResponse<T>(response: Response): Promise<T> {
|
|
50
|
+
const body = await response.json();
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
const message = body?.error?.message ?? body?.message ?? `HTTP ${response.status}`;
|
|
53
|
+
throw new HttpClientError(message, response.status, body);
|
|
54
|
+
}
|
|
55
|
+
return body as T;
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/api/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { HttpClient, HttpClientError } from './http.js';
|
|
2
|
+
export { TokensApi } from './tokens.js';
|
|
3
|
+
export { PairsApi, type PairQuery, type PaginatedResult } from './pairs.js';
|
|
4
|
+
export { QuotesApi, type QuoteApiParams } from './quotes.js';
|
|
5
|
+
export { LiquidityApi } from './liquidity.js';
|
|
6
|
+
export { RatesApi } from './rates.js';
|
|
7
|
+
export { CurrenciesApi } from './currencies.js';
|
|
8
|
+
export { SwapsApi } from './swaps.js';
|
|
9
|
+
export { SubmissionApi } from './submission.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LiquidityPositionApiResponse, ImpermanentLossApiResponse, ApiResponse } from '../types/index.js';
|
|
2
|
+
import type { HttpClient } from './http.js';
|
|
3
|
+
|
|
4
|
+
export class LiquidityApi {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
async getPositions(accountIdentifier: string, currencyId?: number): Promise<LiquidityPositionApiResponse[]> {
|
|
8
|
+
const response = await this.http.get<ApiResponse<LiquidityPositionApiResponse[]>>(
|
|
9
|
+
`/accounts/${accountIdentifier}/liquidity-positions`,
|
|
10
|
+
{ includes: currencyId !== undefined ? `csprtrade_data(${currencyId})` : undefined }
|
|
11
|
+
);
|
|
12
|
+
return response.data;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getImpermanentLoss(accountIdentifier: string, pairHash: string): Promise<ImpermanentLossApiResponse> {
|
|
16
|
+
const response = await this.http.get<ApiResponse<ImpermanentLossApiResponse>>(
|
|
17
|
+
`/accounts/${accountIdentifier}/liquidity-position-impermanent-loss`,
|
|
18
|
+
{ pair_contract_package_hash: pairHash }
|
|
19
|
+
);
|
|
20
|
+
return response.data;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/api/pairs.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Pair, PairApiResponse, PaginatedApiResponse, ApiResponse } from '../types/index.js';
|
|
2
|
+
import type { HttpClient } from './http.js';
|
|
3
|
+
|
|
4
|
+
export interface PairQuery {
|
|
5
|
+
page?: number;
|
|
6
|
+
pageSize?: number;
|
|
7
|
+
orderBy?: 'timestamp' | 'reserve0' | 'reserve1';
|
|
8
|
+
orderDirection?: 'asc' | 'desc';
|
|
9
|
+
token0Hash?: string;
|
|
10
|
+
token1Hash?: string;
|
|
11
|
+
currencyId?: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface PaginatedResult<T> {
|
|
15
|
+
data: T[];
|
|
16
|
+
itemCount: number;
|
|
17
|
+
pageCount: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class PairsApi {
|
|
21
|
+
constructor(private readonly http: HttpClient) {}
|
|
22
|
+
|
|
23
|
+
async getPairs(opts?: PairQuery): Promise<PaginatedResult<Pair>> {
|
|
24
|
+
const response = await this.http.get<PaginatedApiResponse<PairApiResponse>>('/pairs', {
|
|
25
|
+
page: opts?.page !== undefined ? String(opts.page) : undefined,
|
|
26
|
+
page_size: opts?.pageSize !== undefined ? String(opts.pageSize) : undefined,
|
|
27
|
+
order_by: opts?.orderBy,
|
|
28
|
+
order_direction: opts?.orderDirection,
|
|
29
|
+
token0_contract_package_hash: opts?.token0Hash,
|
|
30
|
+
token1_contract_package_hash: opts?.token1Hash,
|
|
31
|
+
includes: opts?.currencyId !== undefined ? `csprtrade_data(${opts.currencyId})` : undefined,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
data: response.data.map(mapPair),
|
|
36
|
+
itemCount: response.item_count,
|
|
37
|
+
pageCount: response.page_count,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async getPairDetails(contractPackageHash: string, currencyId?: number): Promise<Pair> {
|
|
42
|
+
const response = await this.http.get<ApiResponse<PairApiResponse>>(
|
|
43
|
+
`/pairs/${contractPackageHash}`,
|
|
44
|
+
{
|
|
45
|
+
includes: currencyId !== undefined ? `csprtrade_data(${currencyId})` : undefined,
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
return mapPair(response.data);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function mapPair(api: PairApiResponse): Pair {
|
|
53
|
+
const meta0 = api.token0_contract_package?.metadata;
|
|
54
|
+
const meta1 = api.token1_contract_package?.metadata;
|
|
55
|
+
return {
|
|
56
|
+
contractPackageHash: api.contract_package_hash,
|
|
57
|
+
token0: {
|
|
58
|
+
packageHash: api.token0_contract_package_hash,
|
|
59
|
+
symbol: meta0?.symbol ?? '',
|
|
60
|
+
name: meta0?.name ?? '',
|
|
61
|
+
decimals: api.decimals0,
|
|
62
|
+
iconUrl: api.token0_contract_package?.icon_url ?? null,
|
|
63
|
+
},
|
|
64
|
+
token1: {
|
|
65
|
+
packageHash: api.token1_contract_package_hash,
|
|
66
|
+
symbol: meta1?.symbol ?? '',
|
|
67
|
+
name: meta1?.name ?? '',
|
|
68
|
+
decimals: api.decimals1,
|
|
69
|
+
iconUrl: api.token1_contract_package?.icon_url ?? null,
|
|
70
|
+
},
|
|
71
|
+
reserve0: api.reserve0,
|
|
72
|
+
reserve1: api.reserve1,
|
|
73
|
+
timestamp: api.timestamp,
|
|
74
|
+
fiatPrice0: api.token0_contract_package?.csprtrade_data?.price ?? null,
|
|
75
|
+
fiatPrice1: api.token1_contract_package?.csprtrade_data?.price ?? null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { QuoteApiResponse, ApiResponse } from '../types/index.js';
|
|
2
|
+
import type { HttpClient } from './http.js';
|
|
3
|
+
|
|
4
|
+
export interface QuoteApiParams {
|
|
5
|
+
tokenIn: string; // contract package hash
|
|
6
|
+
tokenOut: string; // contract package hash
|
|
7
|
+
amount: string; // raw amount
|
|
8
|
+
typeId: 1 | 2; // 1=exact_in, 2=exact_out
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class QuotesApi {
|
|
12
|
+
constructor(private readonly http: HttpClient) {}
|
|
13
|
+
|
|
14
|
+
async getQuote(params: QuoteApiParams): Promise<QuoteApiResponse> {
|
|
15
|
+
const response = await this.http.get<ApiResponse<QuoteApiResponse>>('/quote', {
|
|
16
|
+
token_in: params.tokenIn,
|
|
17
|
+
token_out: params.tokenOut,
|
|
18
|
+
amount: params.amount,
|
|
19
|
+
type_id: String(params.typeId),
|
|
20
|
+
});
|
|
21
|
+
return response.data;
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/api/rates.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ApiResponse } from '../types/index.js';
|
|
2
|
+
import type { HttpClient } from './http.js';
|
|
3
|
+
|
|
4
|
+
export class RatesApi {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
async getCsprRate(currencyId: number): Promise<unknown> {
|
|
8
|
+
const response = await this.http.get<ApiResponse<unknown>>(`/rates/${currencyId}/latest`);
|
|
9
|
+
return response.data;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async getTokenRate(contractPackageHash: string, currencyId?: number, dexId?: number): Promise<unknown> {
|
|
13
|
+
const response = await this.http.get<ApiResponse<unknown>>(
|
|
14
|
+
`/ft/${contractPackageHash}/rates/latest`,
|
|
15
|
+
{
|
|
16
|
+
currency_id: currencyId !== undefined ? String(currencyId) : undefined,
|
|
17
|
+
dex_id: dexId !== undefined ? String(dexId) : undefined,
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
return response.data;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async getTokenDexRate(contractPackageHash: string, targetHash?: string, dexId?: number): Promise<unknown> {
|
|
24
|
+
const response = await this.http.get<ApiResponse<unknown>>(
|
|
25
|
+
`/ft/${contractPackageHash}/dex-rates/latest`,
|
|
26
|
+
{
|
|
27
|
+
target_contract_package_hash: targetHash,
|
|
28
|
+
dex_id: dexId !== undefined ? String(dexId) : undefined,
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
return response.data;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { HttpClient } from './http.js';
|
|
2
|
+
import type { ApiResponse, SubmitResult } from '../types/index.js';
|
|
3
|
+
|
|
4
|
+
export interface WasmProxyTransactionParams {
|
|
5
|
+
callerPublicKey: string;
|
|
6
|
+
contractPackageHash: string;
|
|
7
|
+
entryPoint: string;
|
|
8
|
+
/** Hex-encoded serialized inner args bytes (from Args.toBytes()) */
|
|
9
|
+
args: string;
|
|
10
|
+
attachedAmount: number;
|
|
11
|
+
paymentAmount: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class SubmissionApi {
|
|
15
|
+
constructor(private readonly http: HttpClient) {}
|
|
16
|
+
|
|
17
|
+
/** Ask the API to build an unsigned TransactionV1 with the proxy WASM. */
|
|
18
|
+
async createWasmProxyTransaction(params: WasmProxyTransactionParams): Promise<unknown> {
|
|
19
|
+
const response = await this.http.post<ApiResponse<unknown>>(
|
|
20
|
+
'/wasm-proxy-transaction',
|
|
21
|
+
{
|
|
22
|
+
caller_public_key: params.callerPublicKey,
|
|
23
|
+
contract_package_hash: params.contractPackageHash,
|
|
24
|
+
entry_point: params.entryPoint,
|
|
25
|
+
args: params.args,
|
|
26
|
+
attached_amount: params.attachedAmount,
|
|
27
|
+
payment_amount: params.paymentAmount,
|
|
28
|
+
},
|
|
29
|
+
);
|
|
30
|
+
return response.data;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async submitTransaction(signedTransactionJson: unknown): Promise<SubmitResult> {
|
|
34
|
+
const response = await this.http.post<ApiResponse<{ api_version: string; transaction_hash: { Version1: string } }>>(
|
|
35
|
+
'/wasm-proxy-transaction-submission',
|
|
36
|
+
signedTransactionJson
|
|
37
|
+
);
|
|
38
|
+
return {
|
|
39
|
+
transactionHash: response.data.transaction_hash?.Version1 ?? '',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/api/swaps.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PaginatedApiResponse } from '../types/index.js';
|
|
2
|
+
import type { HttpClient } from './http.js';
|
|
3
|
+
|
|
4
|
+
export interface SwapApiQuery {
|
|
5
|
+
senderAccountHash?: string;
|
|
6
|
+
pairContractPackageHash?: string;
|
|
7
|
+
page?: number;
|
|
8
|
+
pageSize?: number;
|
|
9
|
+
orderDirection?: 'asc' | 'desc';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class SwapsApi {
|
|
13
|
+
constructor(private readonly http: HttpClient) {}
|
|
14
|
+
|
|
15
|
+
async getSwaps(opts?: SwapApiQuery): Promise<PaginatedApiResponse<unknown>> {
|
|
16
|
+
return this.http.get<PaginatedApiResponse<unknown>>('/swaps', {
|
|
17
|
+
sender_hash: opts?.senderAccountHash,
|
|
18
|
+
pair_contract_package_hash: opts?.pairContractPackageHash,
|
|
19
|
+
page: opts?.page !== undefined ? String(opts.page) : undefined,
|
|
20
|
+
page_size: opts?.pageSize !== undefined ? String(opts.pageSize) : undefined,
|
|
21
|
+
order_direction: opts?.orderDirection,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Token, TokenApiResponse, ApiResponse } from '../types/index.js';
|
|
2
|
+
import { CSPR_TOKEN_ID, CSPR_DECIMALS } from '../config.js';
|
|
3
|
+
import type { HttpClient } from './http.js';
|
|
4
|
+
|
|
5
|
+
export class TokensApi {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly http: HttpClient,
|
|
8
|
+
private readonly wcsprPackageHash?: string,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
async getTokens(currencyId?: number): Promise<Token[]> {
|
|
12
|
+
const response = await this.http.get<ApiResponse<TokenApiResponse[]>>('/tokens', {
|
|
13
|
+
includes: currencyId !== undefined ? `csprtrade_data(${currencyId})` : undefined,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const wcsprHash = this.wcsprPackageHash?.replace('hash-', '') ?? '';
|
|
17
|
+
const tokens = response.data.map(apiToken => {
|
|
18
|
+
const rawHash = apiToken.contract_package_hash.replace('hash-', '');
|
|
19
|
+
// Transform WCSPR into virtual "CSPR" token (matching frontend behavior)
|
|
20
|
+
if (rawHash === wcsprHash) {
|
|
21
|
+
const meta = apiToken.contract_package?.metadata;
|
|
22
|
+
return {
|
|
23
|
+
id: CSPR_TOKEN_ID,
|
|
24
|
+
name: 'Casper',
|
|
25
|
+
symbol: 'CSPR',
|
|
26
|
+
decimals: meta?.decimals ?? CSPR_DECIMALS,
|
|
27
|
+
packageHash: apiToken.contract_package_hash,
|
|
28
|
+
iconUrl: apiToken.contract_package?.icon_url ?? null,
|
|
29
|
+
fiatPrice: apiToken.contract_package?.csprtrade_data?.price ?? null,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return mapApiTokenToToken(apiToken);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return tokens;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async getTokensRaw(currencyId?: number): Promise<TokenApiResponse[]> {
|
|
39
|
+
const response = await this.http.get<ApiResponse<TokenApiResponse[]>>('/tokens', {
|
|
40
|
+
includes: currencyId !== undefined ? `csprtrade_data(${currencyId})` : undefined,
|
|
41
|
+
});
|
|
42
|
+
return response.data;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function mapApiTokenToToken(apiToken: TokenApiResponse): Token {
|
|
47
|
+
const meta = apiToken.contract_package?.metadata;
|
|
48
|
+
return {
|
|
49
|
+
id: apiToken.contract_package_hash,
|
|
50
|
+
name: meta?.name ?? apiToken.contract_package?.name ?? '',
|
|
51
|
+
symbol: meta?.symbol ?? '',
|
|
52
|
+
decimals: meta?.decimals ?? 0,
|
|
53
|
+
packageHash: apiToken.contract_package_hash,
|
|
54
|
+
iconUrl: apiToken.contract_package?.icon_url ?? null,
|
|
55
|
+
fiatPrice: apiToken.contract_package?.csprtrade_data?.price ?? null,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
let cachedWasm: Uint8Array | null = null;
|
|
6
|
+
|
|
7
|
+
export async function getProxyCallerWasm(): Promise<Uint8Array> {
|
|
8
|
+
if (cachedWasm) return cachedWasm;
|
|
9
|
+
|
|
10
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
let buffer: Buffer;
|
|
12
|
+
try {
|
|
13
|
+
// Bundled: dist/index.js → dist/assets/proxy_caller.wasm
|
|
14
|
+
buffer = await readFile(join(currentDir, 'assets', 'proxy_caller.wasm'));
|
|
15
|
+
} catch {
|
|
16
|
+
// Source: src/assets/index.ts → src/assets/proxy_caller.wasm
|
|
17
|
+
buffer = await readFile(join(currentDir, 'proxy_caller.wasm'));
|
|
18
|
+
}
|
|
19
|
+
cachedWasm = new Uint8Array(buffer);
|
|
20
|
+
return cachedWasm;
|
|
21
|
+
}
|
|
Binary file
|