Skip to content

Commit

Permalink
feat(sdk): Add asset search by multi-location ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeldev5 committed Nov 12, 2024
1 parent 7730776 commit 3e8ae88
Show file tree
Hide file tree
Showing 58 changed files with 7,072 additions and 5,736 deletions.
2 changes: 1 addition & 1 deletion apps/playground/src/components/XcmTransfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const XcmTransfer = () => {
return hasDuplicateIds
? { symbol: currency.symbol ?? "" }
: {
id: currency.assetId,
id: currency.assetId ?? "",
};
} else {
throw Error("Currency is required");
Expand Down
4 changes: 2 additions & 2 deletions apps/playground/src/routes/RouterTransferPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,12 @@ const RouterTransferPage = () => {
.to(to)
.exchange(exchange)
.currencyFrom(
isForeignAsset(currencyFrom)
isForeignAsset(currencyFrom) && currencyFrom.assetId
? { id: currencyFrom.assetId }
: { symbol: currencyFrom.symbol ?? "" },
)
.currencyTo(
isForeignAsset(currencyTo)
isForeignAsset(currencyTo) && currencyTo.assetId
? { id: currencyTo.assetId }
: { symbol: currencyTo.symbol ?? "" },
)
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/e2e/xcm-papi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const filteredNodes = NODE_NAMES_DOT_KSM.filter(

const findTransferableNodeAndAsset = (
from: TNode
): { nodeTo: TNode | undefined; asset: string | undefined; assetId: string | null } => {
): { nodeTo: TNode | undefined; asset: string | undefined; assetId: string | null | undefined } => {
const allFromAssets = getAssetsForNode(from)

const nodeTo = NODE_NAMES_DOT_KSM.filter(
Expand All @@ -92,7 +92,7 @@ const findTransferableNodeAndAsset = (

if (nodeTo === 'AssetHubPolkadot' || nodeTo === 'AssetHubKusama') {
const supportedAsset = getSupportedAssets(from, nodeTo).filter(
asset => asset.symbol !== 'DOT' && asset.symbol !== 'KSM'
asset => asset.symbol !== 'DOT' && asset.symbol !== 'KSM' && asset.symbol !== 'GLMR'
)[0]
return {
nodeTo,
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/e2e/xcm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const filteredNodes = NODE_NAMES_DOT_KSM.filter(

const findTransferableNodeAndAsset = (
from: TNode
): { nodeTo: TNode | undefined; asset: string | undefined; assetId: string | null } => {
): { nodeTo: TNode | undefined; asset: string | undefined; assetId: string | null | undefined } => {
const allFromAssets = getAssetsForNode(from)

const nodeTo = NODE_NAMES_DOT_KSM.filter(
Expand All @@ -62,7 +62,7 @@ const findTransferableNodeAndAsset = (

const filteredNodes =
node === 'AssetHubPolkadot' || node === 'AssetHubKusama'
? nodeAssets.filter(symbol => symbol !== 'DOT' && symbol !== 'KSM')
? nodeAssets.filter(symbol => symbol !== 'DOT' && symbol !== 'KSM' && symbol !== 'GLMR')
: nodeAssets

const commonAsset = filteredNodes.filter(asset => allFromAssets.includes(asset))[0]
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/scripts/assets/addAliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function addAliasesToDuplicateSymbols(assetsMap: TAssetJsonMap): TAssetJs

for (const asset of allAssets) {
if (asset.symbol === symbol && isForeignAsset(asset)) {
const aliasNumber = aliasNumbers[asset.assetId]
const aliasNumber = asset.assetId ? aliasNumbers[asset.assetId] : undefined
if (aliasNumber !== undefined) {
asset.alias = `${symbol}${aliasNumber}`
}
Expand Down
139 changes: 41 additions & 98 deletions packages/sdk/scripts/assets/fetchAssets.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import type { ApiPromise } from '@polkadot/api'
import type {
TForeignAsset,
TAssetJsonMap,
TMultiLocation,
TForeignAsset,
TNativeAsset,
TNode,
TNodeAssets,
TNodePolkadotKusama
} from '../../src/types'
import { getNode, getNodeEndpointOption } from '../../src/utils'
import { fetchTryMultipleProvidersWithTimeout } from '../scriptUtils'
import { nodeToQuery } from './nodeToQueryMap'
import { fetchBifrostAssets } from './fetchBifrostAssets'
import { GLOBAL, nodeToQuery } from './nodeToQueryMap'
import { fetchEthereumAssets } from './fetchEthereumAssets'
import { addAliasesToDuplicateSymbols } from './addAliases'
import { fetchOtherAssetsRegistry } from './fetchOtherAssetsRegistry'

const fetchNativeAssets = async (api: ApiPromise): Promise<TNativeAsset[]> => {
const propertiesRes = await api.rpc.system.properties()
Expand All @@ -30,9 +29,10 @@ const fetchNativeAssets = async (api: ApiPromise): Promise<TNativeAsset[]> => {
}))
}

const fetchOtherAssets = async (api: ApiPromise, query: string) => {
const fetchOtherAssets = async (api: ApiPromise, query: string): Promise<TForeignAsset[]> => {
const [module, section] = query.split('.')
const res = await api.query[module][section].entries()

return res
.map(
([
Expand Down Expand Up @@ -147,38 +147,6 @@ const fetchOtherAssetsAmplitude = async (api: ApiPromise, query: string) => {
)
}

const fetchOtherAssetsCentrifuge = async (api: ApiPromise, query: string) => {
const [module, section] = query.split('.')
const res = await api.query[module][section].entries()
return res
.filter(
([
{
args: [era]
}
]) => era.toHuman() !== 'Native'
)
.map(
([
{
args: [era]
},
value
]) => {
const { symbol, decimals } = value.toHuman() as any
const eraObj = era as any
return {
assetId:
eraObj.type === 'Tranche'
? Object.values(era.toHuman() ?? {})[0][0].replaceAll(',', '')
: Object.values(era.toHuman() ?? {})[0].replaceAll(',', ''),
symbol,
decimals: +decimals
}
}
)
}

const fetchOtherAssetsInnerType = async (api: ApiPromise, query: string) => {
const [module, section] = query.split('.')
const symbolsResponse = await api.query[module][section].entries()
Expand Down Expand Up @@ -273,15 +241,24 @@ const fetchNativeAsset = async (api: ApiPromise): Promise<string> => {
return symbols[0]
}

const fetchMultiLocations = async (api: ApiPromise): Promise<TMultiLocation[]> => {
const res = await api.query.foreignAssets.asset.entries()
const fetchMultiLocations = async (api: ApiPromise): Promise<TForeignAsset[]> => {
const res = await api.query.foreignAssets.metadata.entries()
return res.map(
([
{
args: [era]
},
value
]) => {
const multiLocation = era.toHuman() ?? {}
const { symbol, decimals } = value.toHuman() as any
return {
symbol,
decimals: +decimals,
multiLocation: multiLocation as object
}
]) => era.toJSON()
) as unknown as TMultiLocation[]
}
)
}

const fetchNodeAssets = async (
Expand All @@ -291,13 +268,6 @@ const fetchNodeAssets = async (
): Promise<Partial<TNodeAssets>> => {
const nativeAssetSymbol = await fetchNativeAsset(api)

// Different format of data
if (node === 'Acala' || node === 'Karura') {
const assets = await fetchAssetsType2(api, query!)
await api.disconnect()
return { ...assets, nativeAssetSymbol }
}

if (node === 'Polkadex') {
const nativeAssets = (await fetchNativeAssets(api)) ?? []
const otherAssets = await fetchAssetIdsOnly(api, query!)
Expand All @@ -319,31 +289,6 @@ const fetchNodeAssets = async (
nativeAssetSymbol
}
}

if (node === 'Pioneer') {
const { otherAssets } = await fetchAssetsType2(api, query!)
const nativeAssets = (await fetchNativeAssets(api)) ?? []
await api.disconnect()
return {
nativeAssets,
otherAssets,
nativeAssetSymbol
}
}

// Different format of data
if (node === 'Centrifuge' || node === 'Altair') {
const nativeAssets = (await fetchNativeAssets(api)) ?? []
const otherAssets = query ? await fetchOtherAssetsCentrifuge(api, query) : []
await api.disconnect()
return {
nativeAssets,
otherAssets,
nativeAssetSymbol
}
}

// Different format of data
if (node === 'Amplitude') {
const nativeAssets = (await fetchNativeAssets(api)) ?? []
const otherAssets = query ? await fetchOtherAssetsAmplitude(api, query) : []
Expand All @@ -366,6 +311,7 @@ const fetchNodeAssets = async (
nativeAssetSymbol
}
}

if (node === 'Picasso' || node === 'ComposableFinance') {
const nativeAssets = (await fetchNativeAssets(api)) ?? []
const otherAssets = query ? await fetchOtherAssetsInnerType(api, query) : []
Expand All @@ -377,32 +323,28 @@ const fetchNodeAssets = async (
}
}

if (node === 'BifrostPolkadot' || node === 'BifrostKusama') {
const { nativeAssets, otherAssets } = await fetchBifrostAssets(api, query ?? '')
await api.disconnect()
return {
nativeAssets,
otherAssets,
nativeAssetSymbol
}
}
const nativeAssets = (await fetchNativeAssets(api)) ?? []

if (node === 'AssetHubPolkadot' || node === 'AssetHubKusama') {
const nativeAssets = (await fetchNativeAssets(api)) ?? []
const otherAssets = query ? await fetchOtherAssets(api, query) : []
const multiLocations = await fetchMultiLocations(api)
await api.disconnect()
return {
nativeAssets,
otherAssets,
nativeAssetSymbol,
multiLocations
}
let otherAssets: TForeignAsset[]

try {
otherAssets =
query === GLOBAL
? await fetchOtherAssetsRegistry(node)
: typeof query === 'string'
? await fetchOtherAssets(api, query)
: []
} catch (e) {
console.warn(`Failed to fetch other assets for ${node}: ${e.message}`)
otherAssets = []
}

const nativeAssets = (await fetchNativeAssets(api)) ?? []
const isAssetHub = node === 'AssetHubPolkadot' || node === 'AssetHubKusama'

const otherAssets = query ? await fetchOtherAssets(api, query) : []
if (isAssetHub) {
const foreignAssets = await fetchMultiLocations(api)
otherAssets.push(...foreignAssets)
}

await api.disconnect()

Expand All @@ -417,6 +359,7 @@ export const fetchAllNodesAssets = async (assetsMapJson: any) => {
const output: TAssetJsonMap = JSON.parse(JSON.stringify(assetsMapJson))
for (const [node, query] of Object.entries(nodeToQuery)) {
const nodeName = node as TNode

console.log(`Fetching assets for ${nodeName}...`)

let newData
Expand All @@ -428,6 +371,7 @@ export const fetchAllNodesAssets = async (assetsMapJson: any) => {
newData = await fetchTryMultipleProvidersWithTimeout(nodeName as TNodePolkadotKusama, api =>
fetchNodeAssets(nodeName as TNodePolkadotKusama, api, query)
)

const isError = newData === null
const oldData = output[nodeName] ?? null
const paraId = getNodeEndpointOption(nodeName as TNodePolkadotKusama)?.paraId
Expand Down Expand Up @@ -456,8 +400,7 @@ export const fetchAllNodesAssets = async (assetsMapJson: any) => {
relayChainAssetSymbol: getNode(nodeName).type === 'polkadot' ? 'DOT' : 'KSM',
nativeAssetSymbol: newData?.nativeAssetSymbol ?? '',
nativeAssets: combinedNativeAssets,
otherAssets: combinedOtherAssets,
multiLocations: newData?.multiLocations ?? []
otherAssets: combinedOtherAssets
}
}
}
Expand Down
57 changes: 0 additions & 57 deletions packages/sdk/scripts/assets/fetchBifrostAssets.ts

This file was deleted.

Loading

0 comments on commit 3e8ae88

Please sign in to comment.