zerion-sdk
Version:
A Typed Interface for ZerionAPI
117 lines (116 loc) • 5.22 kB
JavaScript
import { transformPositionDataToUserDashboardResponse } from "./transform/ui";
import { STATIC_CHAINS_MAINNET, STATIC_NATIVE_TOKENS_MAINNET, STATIC_CHAINS_TESTNET, STATIC_NATIVE_TOKENS_TESTNET, ZerionService, } from "./services/zerion";
import { DEFAULT_FUNGIBLE_OPTIONS, POLYGON_NATIVE_ASSET_ID } from "./config";
import { buildQueryString, polygonNativeAssetImplementation } from "./util";
export class ZerionAPI {
service;
isTestnet;
ui;
constructor(apiKey, testnet = false) {
this.service = new ZerionService(apiKey, testnet);
this.isTestnet = testnet;
this.ui = new ZerionUI(this);
}
async getChains(useStatic) {
if (useStatic) {
return this.isTestnet ? STATIC_CHAINS_TESTNET : STATIC_CHAINS_MAINNET;
}
const { data } = await this.service.fetchFromZerion("/chains/");
return data;
}
async getPortfolio(walletAddress, currency = "usd") {
const { data } = await this.service.fetchFromZerion(`/wallets/${walletAddress}/portfolio?currency=${currency}`);
return data;
}
async getFungiblePositions(walletAddress, options = DEFAULT_FUNGIBLE_OPTIONS) {
const { filterPositions, filterTrash, sort, currency } = options;
const { data } = await this.service.fetchFromZerion(`/wallets/${walletAddress}/positions/?filter[positions]=${filterPositions}¤cy=${currency}&filter[trash]=${filterTrash}&sort=${sort}`);
data.map((position) => {
if (position.relationships.fungible.data.id === POLYGON_NATIVE_ASSET_ID) {
position.attributes.fungible_info.implementations =
polygonNativeAssetImplementation();
}
});
return data;
}
async fungibles(id) {
const { data } = await this.service.fetchFromZerion(`/fungibles/${id}`);
if (data.id === "7560001f-9b6d-4115-b14a-6c44c4334ef2") {
data.attributes.implementations = polygonNativeAssetImplementation();
}
return data;
}
async fetchNFTs(walletAddress, options) {
if (this.isTestnet) {
console.warn("This endpoint is not supported for testnet. Returning empty list");
return [];
}
// Base parameters
const baseParams = {
currency: options?.currency || "usd",
"page[size]": options?.pageSize || 100,
"filter[chain_ids]": options?.network,
"filter[collection]": options?.collection,
"filter[category]": options?.category,
"filter[status]": options?.status,
"page[number]": options?.pageNumber,
sort: options?.sort,
include: options?.include,
};
const { data } = await this.service.fetchFromZerion(
// TODO: Add pagination!
`/wallets/${walletAddress}/nft-positions/?${buildQueryString(baseParams)}`);
return data;
}
async getNativeTokens(chains, useStatic) {
if (useStatic)
return Object.fromEntries(chains.map((chain) => [
chain.id,
(this.isTestnet
? STATIC_NATIVE_TOKENS_TESTNET
: STATIC_NATIVE_TOKENS_MAINNET)[chain.id],
]));
const nativeTokenResponses = await Promise.all(chains.map(async (chain) => {
const nativeTokenId = chain.relationships.native_fungible.data.id;
const tokenData = await this.fungibles(nativeTokenId);
return { chainId: chain.id, tokenData };
}));
const nativeTokens = Object.fromEntries(nativeTokenResponses.map(({ chainId, tokenData }) => [chainId, tokenData]));
return nativeTokens;
}
}
export class ZerionUI {
client;
constructor(client) {
this.client = client;
}
async getUserBalances(walletAddress, params) {
const { fungibleOptions: preFungibleOptions, options } = params || {};
// Many testnet tokens are not returned by the API unless trash filter is disabled.
const testnetOverrides = this.client.isTestnet && !preFungibleOptions
? { filterTrash: "no_filter" }
: {};
const fungibleOptions = {
...DEFAULT_FUNGIBLE_OPTIONS,
...preFungibleOptions,
...testnetOverrides,
};
const [chains, positions] = await Promise.all([
this.client.getChains(params?.useStatic),
this.client.getFungiblePositions(walletAddress, fungibleOptions),
]);
const nativeTokens = options?.showZeroNative
? await (async () => {
const supportedChains = options?.supportedChains;
const relevantChains = supportedChains
? chains.filter((chain) => supportedChains.includes(parseInt(chain.attributes.external_id, 16)))
: chains;
return this.client.getNativeTokens(relevantChains, params?.useStatic);
})()
: {};
return transformPositionDataToUserDashboardResponse(positions, chains, {
...options,
nativeTokens, // Pass native token data to transform
}, this.client.isTestnet);
}
}