@swapkit/api
Advanced tools
Comparing version 0.0.0-nightly-20241203133447 to 0.0.0-nightly-20250108062728
{ | ||
"author": "swapkit-oss", | ||
"dependencies": { | ||
"@swapkit/helpers": "0.0.0-nightly-20241203133447", | ||
"zod": "3.23.8" | ||
"@swapkit/helpers": "0.0.0-nightly-20250108062728", | ||
"zod": "3.24.1" | ||
}, | ||
@@ -30,3 +30,3 @@ "description": "SwapKit - API", | ||
"types": "./src/index.ts", | ||
"version": "0.0.0-nightly-20241203133447" | ||
"version": "0.0.0-nightly-20250108062728" | ||
} |
@@ -5,6 +5,4 @@ import * as microgardEndpoints from "./microgard/endpoints"; | ||
import * as thornodeEndpoints from "./thornode/endpoints"; | ||
import * as thorswapApiEndpoints from "./thorswapApi/endpoints"; | ||
import * as thorswapStaticEndpoints from "./thorswapStatic/endpoints"; | ||
export * from "./thorswapApi/types"; | ||
export * from "./microgard/types"; | ||
@@ -15,6 +13,11 @@ export * from "./thorswapStatic/types"; | ||
export { microgardEndpoints }; | ||
export { swapkitApiEndpoints }; | ||
export { thornodeEndpoints }; | ||
export { thorswapStaticEndpoints }; | ||
export { mayachainMidgard, thorchainMidgard }; | ||
export const SwapKitApi = { | ||
...microgardEndpoints, | ||
...thornodeEndpoints, | ||
...thorswapApiEndpoints, | ||
...swapkitApiEndpoints, | ||
@@ -21,0 +24,0 @@ ...thorswapStaticEndpoints, |
@@ -0,3 +1,10 @@ | ||
import crypto from "crypto"; | ||
import { ProviderName, RequestClient, SwapKitError } from "@swapkit/helpers"; | ||
import { | ||
type BrokerDepositChannelParams, | ||
type DepositChannelResponse, | ||
DepositChannelResponseSchema, | ||
type GasResponse, | ||
GasResponseSchema, | ||
type PriceRequest, | ||
@@ -14,3 +21,2 @@ type PriceResponse, | ||
} from "./types"; | ||
const baseUrl = "https://api.swapkit.dev"; | ||
@@ -23,17 +29,100 @@ const baseUrlDev = "https://dev-api.swapkit.dev"; | ||
export function getTrackerDetails(payload: TrackerParams, apiKey?: string) { | ||
return RequestClient.post<TrackerResponse>(`${getBaseUrl()}/track`, { | ||
const getAuthHeaders = (hash?: string, apiKey?: string, referer?: string) => ({ | ||
...(apiKey && !hash ? { "x-api-key": apiKey } : {}), | ||
...(hash && referer ? { "x-payload-hash": hash, referer } : {}), | ||
}); | ||
export const computeHash = ( | ||
hashParams: | ||
| { | ||
apiKey: string; | ||
method: "POST"; | ||
payload: any; | ||
} | ||
| { | ||
apiKey: string; | ||
method: "GET"; | ||
url: string; | ||
}, | ||
): string => { | ||
const { method } = hashParams; | ||
switch (method) { | ||
case "POST": | ||
return computeHashForPost(hashParams); | ||
case "GET": | ||
return computeHashForGet(hashParams); | ||
default: | ||
throw new SwapKitError("api_v2_invalid_method_key_hash", { | ||
message: `Invalid method: ${method}`, | ||
}); | ||
} | ||
}; | ||
export const computeHashForGet = ({ | ||
url, | ||
apiKey, | ||
}: { | ||
url: string; | ||
apiKey: string; | ||
}): string => { | ||
return crypto.createHash("sha256").update(`${url}${apiKey}`, "utf8").digest("hex"); | ||
}; | ||
export const computeHashForPost = ({ | ||
apiKey, | ||
payload, | ||
}: { | ||
apiKey: string; | ||
payload: any; | ||
}): string => { | ||
const normalizedBody = JSON.stringify(payload); | ||
return crypto.createHash("sha256").update(`${normalizedBody}${apiKey}`, "utf8").digest("hex"); | ||
}; | ||
export function getTrackerDetails(payload: TrackerParams, apiKey?: string, referer?: string) { | ||
const url = `${getBaseUrl()}/track`; | ||
const hash = | ||
referer && apiKey | ||
? computeHash({ | ||
method: "POST", | ||
apiKey, | ||
payload, | ||
}) | ||
: undefined; | ||
return RequestClient.post<TrackerResponse>(url, { | ||
json: payload, | ||
headers: apiKey ? { "x-api-key": apiKey } : {}, | ||
headers: getAuthHeaders(hash, apiKey, referer), | ||
}); | ||
} | ||
export async function getSwapQuoteV2<T extends boolean>( | ||
/** | ||
* @deprecated Use getSwapQuote instead | ||
*/ | ||
export function getSwapQuoteV2<T extends boolean>( | ||
searchParams: QuoteRequest, | ||
isDev?: T, | ||
apiKey?: string, | ||
referer?: string, | ||
) { | ||
const response = await RequestClient.post<QuoteResponse>(`${getBaseUrl(isDev)}/quote`, { | ||
return getSwapQuote(searchParams, isDev, apiKey, referer); | ||
} | ||
export async function getSwapQuote<T extends boolean>( | ||
searchParams: QuoteRequest, | ||
isDev?: T, | ||
apiKey?: string, | ||
referer?: string, | ||
) { | ||
const url = `${getBaseUrl(isDev)}/quote`; | ||
const hash = | ||
referer && apiKey | ||
? computeHash({ | ||
method: "POST", | ||
apiKey: apiKey, | ||
payload: searchParams, | ||
}) | ||
: undefined; | ||
const response = await RequestClient.post<QuoteResponse>(url, { | ||
json: searchParams, | ||
headers: apiKey ? { "x-api-key": apiKey } : {}, | ||
headers: getAuthHeaders(hash, apiKey, referer), | ||
}); | ||
@@ -60,18 +149,67 @@ | ||
export function getTokenListProvidersV2(isDev = false, apiKey?: string) { | ||
return RequestClient.get<TokenListProvidersResponse>(`${getBaseUrl(isDev)}/providers`, { | ||
headers: apiKey ? { "x-api-key": apiKey } : {}, | ||
export function getTokenListProvidersV2(isDev = false, apiKey?: string, referer?: string) { | ||
const url = `${getBaseUrl(isDev)}/providers`; | ||
const hash = | ||
referer && apiKey | ||
? computeHash({ | ||
method: "GET", | ||
apiKey, | ||
url, | ||
}) | ||
: undefined; | ||
return RequestClient.get<TokenListProvidersResponse>(url, { | ||
headers: getAuthHeaders(hash, apiKey, referer), | ||
}); | ||
} | ||
export function getTokenListV2(provider: ProviderName, isDev = false, apiKey?: string) { | ||
return RequestClient.get<TokensResponseV2>(`${getBaseUrl(isDev)}/tokens?provider=${provider}`, { | ||
headers: apiKey ? { "x-api-key": apiKey } : {}, | ||
/** | ||
* @deprecated Use getTokenList instead | ||
*/ | ||
export function getTokenListV2( | ||
provider: ProviderName, | ||
isDev = false, | ||
apiKey?: string, | ||
referer?: string, | ||
) { | ||
return getTokenList(provider, isDev, apiKey, referer); | ||
} | ||
export function getTokenList( | ||
provider: ProviderName, | ||
isDev = false, | ||
apiKey?: string, | ||
referer?: string, | ||
) { | ||
const url = `${getBaseUrl(isDev)}/tokens?provider=${provider}`; | ||
const hash = | ||
referer && apiKey | ||
? computeHash({ | ||
method: "GET", | ||
apiKey, | ||
url, | ||
}) | ||
: undefined; | ||
return RequestClient.get<TokensResponseV2>(url, { | ||
headers: getAuthHeaders(hash, apiKey, referer), | ||
}); | ||
} | ||
export async function getPrice(body: PriceRequest, isDev = false, apiKey?: string) { | ||
const response = await RequestClient.post<PriceResponse>(`${getBaseUrl(isDev)}/price`, { | ||
export async function getPrice( | ||
body: PriceRequest, | ||
isDev = false, | ||
apiKey?: string, | ||
referer?: string, | ||
) { | ||
const url = `${getBaseUrl(isDev)}/price`; | ||
const hash = | ||
referer && apiKey | ||
? computeHash({ | ||
method: "POST", | ||
apiKey, | ||
payload: body, | ||
}) | ||
: undefined; | ||
const response = await RequestClient.post<PriceResponse>(url, { | ||
json: body, | ||
headers: apiKey ? { "x-api-key": apiKey } : {}, | ||
headers: getAuthHeaders(hash, apiKey, referer), | ||
}); | ||
@@ -92,2 +230,30 @@ | ||
export async function getGasRate(isDev = false, apiKey?: string, referer?: string) { | ||
const url = `${getBaseUrl(isDev)}/gas`; | ||
const hash = | ||
referer && apiKey | ||
? computeHash({ | ||
method: "GET", | ||
apiKey, | ||
url, | ||
}) | ||
: undefined; | ||
const response = await RequestClient.get<GasResponse>(url, { | ||
headers: getAuthHeaders(hash, apiKey, referer), | ||
}); | ||
try { | ||
const parsedResponse = GasResponseSchema.safeParse(response); | ||
if (!parsedResponse.success) { | ||
throw new SwapKitError("api_v2_invalid_response", parsedResponse.error); | ||
} | ||
return parsedResponse.data; | ||
} catch (error) { | ||
throw new SwapKitError("api_v2_invalid_response", error); | ||
} | ||
} | ||
// TODO update this once the trading pairs are supported by BE api | ||
@@ -98,2 +264,3 @@ export async function getTokenTradingPairs( | ||
apiKey?: string, | ||
referer?: string, | ||
) { | ||
@@ -111,3 +278,3 @@ const tradingPairs = new Map< | ||
const providerRequests = providers.map(async (provider) => { | ||
const tokenList = await getTokenListV2(provider, isDev, apiKey); | ||
const tokenList = await getTokenListV2(provider, isDev, apiKey, referer); | ||
return tokenList; | ||
@@ -187,1 +354,32 @@ }); | ||
} | ||
export async function getChainflipDepositChannel({ | ||
isDev = false, | ||
body, | ||
}: { | ||
isDev?: boolean; | ||
body: BrokerDepositChannelParams; | ||
}) { | ||
const { destinationAddress } = body; | ||
if (!destinationAddress) { | ||
throw new SwapKitError("chainflip_broker_invalid_params"); | ||
} | ||
const url = `${getBaseUrl(isDev)}/channel`; | ||
const response = await RequestClient.post<DepositChannelResponse>(url, { | ||
json: body, | ||
}); | ||
try { | ||
const parsedResponse = DepositChannelResponseSchema.safeParse(response); | ||
if (!parsedResponse.success) { | ||
throw new SwapKitError("api_v2_invalid_response", parsedResponse.error); | ||
} | ||
return parsedResponse.data; | ||
} catch (error) { | ||
throw new SwapKitError("api_v2_invalid_response", error); | ||
} | ||
} |
@@ -5,2 +5,3 @@ import { | ||
ChainId, | ||
ErrorCode, | ||
FeeTypeEnum, | ||
@@ -12,2 +13,15 @@ ProviderName, | ||
export enum PriorityLabel { | ||
CHEAPEST = "CHEAPEST", | ||
FASTEST = "FASTEST", | ||
RECOMMENDED = "RECOMMENDED", | ||
} | ||
export enum RouteQuoteTxType { | ||
PSBT = "PSBT", | ||
EVM = "EVM", | ||
COSMOS = "COSMOS", | ||
RADIX = "RADIX", | ||
} | ||
export enum TxnType { | ||
@@ -233,3 +247,6 @@ native_send = "native_send", // native send, msgSend, etc. | ||
}, | ||
{ message: "affiliateFee must be a positive integer", path: ["affiliateFee"] }, | ||
{ | ||
message: "affiliateFee must be a positive integer", | ||
path: ["affiliateFee"], | ||
}, | ||
), | ||
@@ -257,2 +274,12 @@ ), | ||
), | ||
cfBoost: z.optional( | ||
z.boolean({ | ||
description: "Set to true to enable CF boost to speed up Chainflip swaps. BTC only.", | ||
}), | ||
), | ||
referrer: z.optional( | ||
z.string({ | ||
description: "Referrer address (referral program)", | ||
}), | ||
), | ||
}) | ||
@@ -277,2 +304,53 @@ .refine((data) => data.sellAsset !== data.buyAsset, { | ||
export const BrokerDepositChannelParamsSchema = z.object({ | ||
sellAsset: z.object({ | ||
chain: z.string(), // identifier of the asset | ||
asset: z.string(), // identifier of the asset | ||
}), | ||
buyAsset: z.object({ | ||
chain: z.string(), // identifier of the asset | ||
asset: z.string(), // identifier of the asset | ||
}), | ||
destinationAddress: z.string(), | ||
channelMetadata: z | ||
.object({ | ||
cfParameters: z.string().optional(), | ||
gasBudget: z.string().optional(), | ||
message: z.string().optional(), | ||
}) | ||
.optional(), | ||
affiliateFees: z | ||
.array( | ||
z.object({ | ||
brokerAddress: z.string(), | ||
feeBps: z.number(), | ||
}), | ||
) | ||
.optional(), | ||
refundParameters: z | ||
.object({ | ||
minPrice: z.string().optional(), | ||
refundAddress: z.string().optional(), | ||
retryDuration: z.number().optional(), | ||
}) | ||
.optional(), | ||
dcaParameters: z | ||
.object({ | ||
chunkInterval: z.number().optional(), | ||
numberOfChunks: z.number().optional(), | ||
}) | ||
.optional(), | ||
brokerCommissionBps: z.number().optional(), | ||
maxBoostFeeBps: z.number().optional(), | ||
}); | ||
export type BrokerDepositChannelParams = z.infer<typeof BrokerDepositChannelParamsSchema>; | ||
export const DepositChannelResponseSchema = z.object({ | ||
channelId: z.string(), | ||
depositAddress: z.string(), | ||
}); | ||
export type DepositChannelResponse = z.infer<typeof DepositChannelResponseSchema>; | ||
const TxnPayloadSchema = z.object({ | ||
@@ -379,4 +457,2 @@ evmCalldata: z.optional(z.string()), // raw 0xcalldata | ||
export type EVMTransaction = z.infer<typeof EVMTransactionSchema>; | ||
export const EstimatedTimeSchema = z.object({ | ||
@@ -420,2 +496,4 @@ inbound: z.optional( | ||
export type EVMTransaction = z.infer<typeof EVMTransactionSchema>; | ||
export const EVMTransactionDetailsParamsSchema = z.array( | ||
@@ -470,2 +548,29 @@ z.union([ | ||
const EncodeObjectSchema = z.object({ | ||
typeUrl: z.string(), | ||
value: z.unknown(), | ||
}); | ||
const FeeSchema = z.object({ | ||
amount: z.array( | ||
z.object({ | ||
denom: z.string(), | ||
amount: z.string(), | ||
}), | ||
), | ||
gas: z.string(), | ||
}); | ||
// Define the full schema | ||
export const CosmosTransactionSchema = z.object({ | ||
memo: z.string(), | ||
accountNumber: z.number(), | ||
sequence: z.number(), | ||
chainId: z.nativeEnum(ChainId), | ||
msgs: z.array(EncodeObjectSchema), | ||
fee: FeeSchema, | ||
}); | ||
export type CosmosTransaction = z.infer<typeof CosmosTransactionSchema>; | ||
export const RouteLegSchema = z.object({ | ||
@@ -525,2 +630,6 @@ sellAsset: z.string({ | ||
export const ChainflipMetadataSchema = BrokerDepositChannelParamsSchema; | ||
export type ChainflipMetadata = z.infer<typeof ChainflipMetadataSchema>; | ||
export const RouteQuoteMetadataSchema = z.object({ | ||
@@ -540,2 +649,10 @@ priceImpact: z.optional( | ||
maxStreamingQuantity: z.number().optional(), | ||
tags: z.array(z.nativeEnum(PriorityLabel)), | ||
affiliate: z.optional(z.string()), | ||
affiliateFee: z.optional(z.string()), | ||
txType: z.optional(z.nativeEnum(RouteQuoteTxType)), | ||
chainflip: z.optional(ChainflipMetadataSchema), | ||
referrer: z.optional(z.string()), | ||
}); | ||
@@ -551,2 +668,4 @@ | ||
export type RouteQuoteWarning = z.infer<typeof RouteQuoteWarningSchema>; | ||
const QuoteResponseRouteLegItem = z.object({ | ||
@@ -616,4 +735,4 @@ provider: z.nativeEnum(ProviderName), | ||
fees: FeesSchema, | ||
tx: z.optional(EVMTransactionSchema), | ||
transaction: z.optional(z.unknown()), // Can take many forms depending on the chains | ||
txType: z.optional(z.nativeEnum(RouteQuoteTxType)), | ||
tx: z.optional(z.union([EVMTransactionSchema, CosmosTransactionSchema, z.string()])), | ||
estimatedTime: z.optional(EstimatedTimeSchema), // TODO remove optionality | ||
@@ -633,2 +752,3 @@ totalSlippageBps: z.number({ | ||
routes: z.array(QuoteResponseRouteItem), | ||
// in case of bad request or actual backend error, not bad quotes from providers | ||
error: z.optional( | ||
@@ -639,2 +759,12 @@ z.string({ | ||
), | ||
// errors from providers | ||
providerErrors: z.optional( | ||
z.array( | ||
z.object({ | ||
provider: z.nativeEnum(ProviderName).optional(), | ||
errorCode: z.optional(z.nativeEnum(ErrorCode)), | ||
message: z.optional(z.string()), | ||
}), | ||
), | ||
), | ||
}); | ||
@@ -645,1 +775,13 @@ | ||
export type QuoteResponseRouteLeg = z.infer<typeof QuoteResponseRouteLegItem>; | ||
export const GasResponseSchema = z.array( | ||
z.object({ | ||
id: z.number(), | ||
chainId: z.string(), | ||
value: z.string(), | ||
unit: z.string(), | ||
createdAt: z.string(), | ||
}), | ||
); | ||
export type GasResponse = z.infer<typeof GasResponseSchema>; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
2361875
4556
14
2
1
+ Added@swapkit/helpers@0.0.0-nightly-20250108062728(transitive)
+ Added@swapkit/tokens@0.0.0-nightly-20250108062728(transitive)
+ Addedzod@3.24.1(transitive)
- Removed@swapkit/helpers@0.0.0-nightly-20241203133447(transitive)
- Removed@swapkit/tokens@0.0.0-nightly-20241203133447(transitive)
- Removedzod@3.23.8(transitive)
Updatedzod@3.24.1