diff --git a/README.md b/README.md index ce1bfe2..4f2d05e 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ Orion’s SDK is free to use and does not require an API key or registration. Re - [Usage](#usage) - [Initialization](#initialization) - [High level methods](#high-level-methods) +- [Get assets](#get-assets) +- [Get pairs](#get-pairs) - [Withdraw](#withdraw) - [Deposit](#deposit) - [Get swap info](#get-swap-info) @@ -104,6 +106,39 @@ detectEthereumProvider().then((provider) => { ## High level methods +## Get assets + +```ts +const assets = await orion.getAssets(); // Optional: tradableOnly: boolean (default: true) + +// Response example: +// { +// ORN: { +// '1': { address: '0x0258f474786ddfd37abce6df6bbb1dd5dfc4434a' }, +// '56': { address: '0xe4ca1f75eca6214393fce1c1b316c237664eaa8e' }, +// '66': { address: '0xd2cdcb6bdee6f78de7988a6a60d13f6ef0b576d9' }, +// '137': { address: '0xd2cdcb6bdee6f78de7988a6a60d13f6ef0b576d9' }, +// '250': { address: '0xd2cdcb6bdee6f78de7988a6a60d13f6ef0b576d9' } +// }, +// BNB: { +// '56': { address: '0x0000000000000000000000000000000000000000' }, +// '250': { address: '0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454' } +// }, +// } +``` + +## Get pairs + +```ts +const pairs = await orion.getPairs("spot"); // 'spot' | 'futures' + +// Response example: +// { +// 'ORN-USDT': [ '250', '66', '1', '56', '137' ], +// 'USDT-USDC': [ '250', '66', '1', '56', '137' ], +// } +``` + ### Withdraw ```ts diff --git a/package.json b/package.json index 0bcf190..cb565ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.17.10", + "version": "0.17.11", "description": "Orion Protocol SDK", "main": "./lib/esm/index.js", "module": "./lib/esm/index.js", diff --git a/src/Orion/index.ts b/src/Orion/index.ts index 3d9ce04..c02c8b2 100644 --- a/src/Orion/index.ts +++ b/src/Orion/index.ts @@ -4,7 +4,8 @@ import { type networkCodes } from '../constants'; import OrionUnit from '../OrionUnit'; import OrionAnalytics from '../services/OrionAnalytics'; import { ReferralSystem } from '../services/ReferralSystem'; -import { type DeepPartial, type SupportedChainId, type VerboseOrionUnitConfig } from '../types'; +import simpleFetch from '../simpleFetch'; +import { type SupportedChainId, type DeepPartial, type VerboseOrionUnitConfig } from '../types'; import { isValidChainId } from '../utils'; type EnvConfig = { @@ -17,6 +18,16 @@ type EnvConfig = { > > } +type AggregatedAssets = Partial< + Record< + string, + Partial< + Record + > + > + >; type KnownEnv = 'testing' | 'staging' | 'production'; @@ -134,4 +145,74 @@ export default class Orion { getSiblingsOf(chainId: SupportedChainId) { return this.unitsArray.filter((unit) => unit.chainId !== chainId); } + + async getAssets(tradableOnly = true) { + const aggregatedAssets: AggregatedAssets = {}; + + await Promise.all(this.unitsArray.map(async (unit) => { + const { assetToAddress } = await simpleFetch(unit.orionBlockchain.getInfo)(); + Object.entries(assetToAddress).forEach(([asset, address]) => { + if (address === undefined) throw new Error(`Address is undefined for asset: ${asset}`); + aggregatedAssets[asset] = { + ...aggregatedAssets[asset], + [unit.chainId]: { + address, + }, + } + }); + })); + + if (tradableOnly) { + const tradableAggregatedAssets: AggregatedAssets = {}; + const aggregatedPairs = await this.getPairs('spot'); + Object.entries(aggregatedPairs).forEach(([pair, chainIds]) => { + const [baseAsset, quoteAsset] = pair.split('-'); + if (chainIds === undefined) throw new Error(`ChainIds is undefined for pair: ${pair}`); + if (baseAsset === undefined || quoteAsset === undefined) throw new Error(`Invalid pair: ${pair}`); + + const aggregatedBaseAsset = aggregatedAssets[baseAsset]; + if (aggregatedBaseAsset === undefined) { + const networks = chainIds.map((chainId) => chains[chainId]?.label).join(', '); + console.error( + `Asset found in Aggregator, but not in Orion Blockchain (base): ${baseAsset} (${pair}).` + + ` Networks: ${networks}` + ); + } else { + tradableAggregatedAssets[baseAsset] = aggregatedBaseAsset; + } + const aggregatedQuoteAsset = aggregatedAssets[quoteAsset]; + if (aggregatedQuoteAsset === undefined) { + const networks = chainIds.map((chainId) => chains[chainId]?.label).join(', '); + console.error( + `Asset found in Aggregator, but not in OrionBlockchain (quote): ${quoteAsset} (${pair}).` + + ` Networks: ${networks}` + ); + } else { + tradableAggregatedAssets[quoteAsset] = aggregatedQuoteAsset; + } + }); + } + return aggregatedAssets; + } + + async getPairs(...params: Parameters) { + const result: Partial< + Record< + string, + SupportedChainId[] + > + > = {}; + + await Promise.all(this.unitsArray.map(async (unit) => { + const pairs = await simpleFetch(unit.orionAggregator.getPairsList)(...params); + pairs.forEach((pair) => { + result[pair] = [ + ...(result[pair] ?? []), + unit.chainId, + ]; + }); + })); + + return result; + } }