Skip to content

Commit e4a1f35

Browse files
authored
feat: fix migration asset hub issue (#126)
1 parent 2533e6f commit e4a1f35

File tree

13 files changed

+2720
-2003
lines changed

13 files changed

+2720
-2003
lines changed

packages/common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"test:watch": "vitest"
3939
},
4040
"dependencies": {
41-
"polkadot-api": "^1.9.13",
41+
"polkadot-api": "^1.23.1",
4242
"@polkadot-labs/hdkd": "^0.0.13",
4343
"@polkadot-labs/hdkd-helpers": "^0.0.13",
4444
"@subsquid/ss58": "^2.0.2"

packages/common/src/chains/supportedChains.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const westendAssetHubChain = createChain({
5555
id: "west_asset_hub",
5656
name: "AssetHubWestend",
5757
specName: "asset-hub-westend",
58-
wsUrls: ["wss://westend-asset-hub-rpc.polkadot.io", "wss://asset-hub-westend-rpc.n.dwellir.com"],
58+
wsUrls: ["wss://polkadot-asset-hub-rpc.polkadot.io"],
5959
relay: "west",
6060
type: "system",
6161
chainId: 1000,

packages/core/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838
"test:watch": "vitest"
3939
},
4040
"dependencies": {
41-
"@paraspell/sdk": "11.12.9",
42-
"@paraspell/xcm-router": "11.12.9",
43-
"@paraspell/assets": "11.12.9",
41+
"@paraspell/sdk": "11.14.8",
42+
"@paraspell/xcm-router": "11.14.8",
43+
"@paraspell/assets": "11.14.8",
4444
"@polkadot-agent-kit/common": "workspace:*",
4545
"@subsquid/ss58": "^2.0.2",
46-
"polkadot-api": "^1.14.1"
46+
"polkadot-api": "^1.23.1"
4747
},
4848
"devDependencies": {
4949
"@babel/plugin-syntax-import-attributes": "^7.26.0",

packages/core/src/defi/swap.ts

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getAssetDecimals } from "@paraspell/assets"
1+
import { getAssetDecimals, getAssetsObject } from "@paraspell/assets"
22
import type { TCurrency, TLocation, TNodeDotKsmWithRelayChains } from "@paraspell/sdk"
33
import type {
44
RouterBuilderCore,
@@ -11,8 +11,7 @@ import { RouterBuilder } from "@paraspell/xcm-router"
1111
import { parseUnits } from "@polkadot-agent-kit/common"
1212
import type { PolkadotSigner } from "polkadot-api/signer"
1313

14-
import type { AssetInfo } from "../utils/assets"
15-
import { getAllAssetsBySymbol } from "../utils/assets"
14+
import type { AssetInfo } from "../utils"
1615
import { getPairSupported } from "../utils/defi"
1716

1817
// Constants
@@ -78,24 +77,77 @@ function getAssetlocationWithSelection(
7877
chain: TNodeDotKsmWithRelayChains,
7978
symbol: string
8079
): TLocation {
81-
// Get all assets with this symbol
82-
const assets = getAllAssetsBySymbol(chain, symbol)
80+
const chainAssets = getAssetsObject(chain)
81+
const nativeAssetSymbol = chainAssets.nativeAssetSymbol
82+
83+
let assetsInfo: AssetInfo[] = []
84+
85+
// Check if symbol matches native asset symbol (case-insensitive comparison)
86+
if (symbol.toUpperCase() === nativeAssetSymbol?.toUpperCase()) {
87+
// Return native asset info
88+
const nativeAssets = chainAssets.nativeAssets || []
89+
const matchingNative = nativeAssets.find(
90+
(asset: { symbol: string }) => asset.symbol?.toUpperCase() === symbol.toUpperCase()
91+
)
92+
93+
if (matchingNative && matchingNative.location) {
94+
assetsInfo = [
95+
{
96+
symbol: matchingNative.symbol,
97+
location: matchingNative.location,
98+
decimals: matchingNative.decimals,
99+
isNative: true,
100+
isFeeAsset: matchingNative.isFeeAsset,
101+
existentialDeposit: matchingNative.existentialDeposit
102+
}
103+
]
104+
}
105+
}
106+
107+
// If not found in native assets, search in otherAssets
108+
if (assetsInfo.length === 0) {
109+
const otherAssets = chainAssets.otherAssets || []
110+
const matchingAssets = otherAssets.filter(
111+
(asset: { symbol: string }) => asset.symbol?.toUpperCase() === symbol.toUpperCase()
112+
)
113+
114+
assetsInfo = matchingAssets.map(
115+
(asset: {
116+
symbol: string
117+
assetId?: string
118+
decimals: number
119+
location?: TLocation
120+
existentialDeposit?: string
121+
isFeeAsset?: boolean
122+
alias?: string
123+
}) => ({
124+
symbol: asset.symbol,
125+
assetId: asset.assetId,
126+
decimals: asset.decimals,
127+
location: asset.location,
128+
existentialDeposit: asset.existentialDeposit,
129+
isFeeAsset: asset.isFeeAsset,
130+
alias: asset.alias,
131+
isNative: false
132+
})
133+
)
134+
}
83135

84136
// Handle no assets found
85-
if (!assets || assets.length === 0) {
137+
if (!assetsInfo || assetsInfo.length === 0) {
86138
throw new Error(`No asset found for symbol ${symbol} on ${chain}`)
87139
}
88140

89141
// Handle single asset - return directly
90-
if (assets.length === 1) {
91-
if (!assets[0].location) {
142+
if (assetsInfo.length === 1) {
143+
if (!assetsInfo[0].location) {
92144
throw new Error(`Asset ${symbol} on ${chain} does not have a location`)
93145
}
94-
return assets[0].location
146+
return assetsInfo[0].location
95147
}
96148

97149
// Handle multiple assets - apply selection strategy
98-
const selectedAsset = selectBestAsset(assets, symbol, chain)
150+
const selectedAsset = selectBestAsset(assetsInfo, symbol, chain)
99151

100152
if (!selectedAsset.location) {
101153
throw new Error(
@@ -221,6 +273,7 @@ function getCrossChainlocations(args: SwapTokenArgs) {
221273
args.from as TNodeDotKsmWithRelayChains,
222274
args.currencyFrom
223275
)
276+
224277
const locationTo = getAssetlocationWithSelection(
225278
args.to as TNodeDotKsmWithRelayChains,
226279
args.currencyTo

packages/core/src/utils/assets.ts

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import { getNativeAssets, getOtherAssets } from "@paraspell/assets"
2-
import type { TLocation, TNodeWithRelayChains, TRelaychain } from "@paraspell/sdk"
3-
import { RELAYCHAINS, SUBSTRATE_CHAINS } from "@paraspell/sdk"
4-
import type { Api, KnownChainId } from "@polkadot-agent-kit/common"
1+
import type { TLocation } from "@paraspell/sdk"
52

63
// Type for asset information from ParaSpell
74
export interface AssetInfo {
@@ -12,54 +9,5 @@ export interface AssetInfo {
129
existentialDeposit?: string
1310
isFeeAsset?: boolean
1411
alias?: string
15-
}
16-
17-
export async function getAssetBalance(
18-
api: Api<KnownChainId>,
19-
chain: string,
20-
assetSymbol: string,
21-
address: string
22-
) {
23-
if (isValidTNodeWithRelayChains(chain)) {
24-
const assets = getOtherAssets(chain as TNodeWithRelayChains)
25-
26-
const filteredAssets = assets.filter(asset => asset.symbol && asset.symbol === assetSymbol)
27-
28-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
29-
const assetAccount = await api.query.Assets.Account.getValue(
30-
Number(filteredAssets[0]?.assetId),
31-
address
32-
)
33-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return
34-
return assetAccount.balance
35-
} else {
36-
throw new Error(`Chain ${chain} is not a valid TNodeWithRelayChains`)
37-
}
38-
}
39-
40-
export function getAllAssetsBySymbol(chain: string, assetSymbol: string): AssetInfo[] {
41-
let assets: AssetInfo[] = []
42-
if (isValidTNodeWithRelayChains(chain)) {
43-
if (isValidRelayChains(chain)) {
44-
assets = getNativeAssets(chain as TRelaychain) as AssetInfo[]
45-
} else {
46-
assets = getOtherAssets(chain as TNodeWithRelayChains) as AssetInfo[]
47-
}
48-
49-
const filteredAssets = assets.filter(asset => asset.symbol && asset.symbol === assetSymbol)
50-
51-
return filteredAssets
52-
} else {
53-
throw new Error(`Chain ${chain} is not a valid TNodeWithRelayChains`)
54-
}
55-
}
56-
57-
// Including relay chains
58-
function isValidTNodeWithRelayChains(chain: string): boolean {
59-
return (SUBSTRATE_CHAINS as readonly string[]).includes(chain)
60-
}
61-
62-
// Just relay chains
63-
function isValidRelayChains(chain: string): boolean {
64-
return (RELAYCHAINS as readonly string[]).includes(chain)
12+
isNative: boolean
6513
}

packages/llm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"@polkadot-agent-kit/common": "workspace:*",
4242
"@polkadot-agent-kit/core": "workspace:*",
4343
"@langchain/core": "^0.3.40",
44-
"polkadot-api": "^1.14.1",
44+
"polkadot-api": "^1.23.1",
4545
"zod": "^3.24.3"
4646
},
4747
"devDependencies": {

packages/llm/src/langchain/defi/swap.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export const swapTokensTool = (signer: PolkadotSigner, sender: string) => {
2525
ToolNames.SWAP_TOKENS,
2626
async () => {
2727
const swapContext = createSwapContext(input, sender)
28-
2928
try {
3029
const transactionResult = await withTimeoutAndRetry(async () => {
3130
const routerPlan = await executeSwap(swapContext, signer)

packages/llm/src/prompt/index.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,20 +254,33 @@ When using any swap tool, you MUST use PascalCase for chain names as defined bel
254254
| polkadot asset hub | AssetHubPolkadot |
255255
| AssetHubPolkadot | AssetHubPolkadot |
256256
| Polkadot Asset Hub | AssetHubPolkadot |
257-
| Hydra | Hydra |
258-
| hydra | Hydra |
257+
| Hydration | Hydration |
258+
| hydra | Hydration |
259+
| Hydra | Hydration |
260+
| hydra | Hydration |
259261
| Kusama | Kusama |
260262
| kusama | Kusama |
261263
264+
265+
**CURRENCY FROM AND CURRENCY TO CONVERSION TABLE (FOR SWAPS ONLY):**
266+
| User Input | Real Param for SWAP (USE THIS) |
267+
|----------------------|--------------------------------|
268+
| DOT | DOT |
269+
| USDT | USDT |
270+
| USDC | USDC |
271+
| KSM | KSM |
272+
| dot | DOT |
273+
| usdc | USDC |
274+
262275
--- SWAP TOOL INSTRUCTIONS ---
263276
264277
**1. Cross-Chain Swaps (using 'swap_tokens'):**
265278
Use this when the user specifies a source chain and a destination chain.
266279
267280
**Parameters:**
268281
- \`amount\`: The quantity of tokens to swap (e.g., "0.1").
269-
- \`currencyFrom\`: The symbol of the token to swap from (e.g., 'DOT', 'KSM', 'HDX').
270-
- \`currencyTo\`: The symbol of the token to swap to (e.g., 'DOT', 'KSM', 'HDX', 'USDT').
282+
- \`currencyFrom\`: The symbol of the token to swap from (e.g., 'DOT', 'KSM', 'HDX') converted using the table above.
283+
- \`currencyTo\`: The symbol of the token to swap to (e.g., 'DOT', 'KSM', 'HDX', 'USDT') converted using the table above.
271284
- \`from\`: The source chain name (e.g., 'Polkadot'), converted using the table above.
272285
- \`to\`: The destination chain name (e.g., 'Hydra'), converted using the table above.
273286
- \`receiver\` (optional): The recipient's address. If not provided, defaults to the sender.
@@ -276,6 +289,7 @@ Use this when the user specifies a source chain and a destination chain.
276289
- **User:** "swap 0.1 DOT from Polkadot to USDT on Hydra"
277290
- **Tool Call:** \`swap_tokens({{ from: "Polkadot", to: "Hydra", currencyFrom: "DOT", currencyTo: "USDT", amount: "0.1" }})\`
278291
292+
**REMEMBER: just symbol token , dont care about native or foreign!**
279293
**2. DEX-Specific Swaps (using 'swapTokensDexTool'):**
280294
Use this when the user specifies a DEX (like HydrationDex) but not necessarily two different chains.
281295

packages/sdk/package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@
4545
"@polkadot-agent-kit/common": "workspace:*",
4646
"@polkadot-agent-kit/core": "workspace:*",
4747
"@polkadot-agent-kit/llm": "workspace:*",
48-
"polkadot-api": "^1.14.1",
48+
"polkadot-api": "^1.23.1",
4949
"zod": "^3.24.3",
5050
"@modelcontextprotocol/sdk": "^1.6.1",
5151
"zod-to-json-schema": "^3.24.3",
5252
"@langchain/google-genai": "^1.0.0",
53-
"@paraspell/sdk": "11.12.9",
54-
"@paraspell/assets": "11.12.9",
55-
"@paraspell/sdk-core": "11.12.9"
53+
"@paraspell/sdk": "11.14.8",
54+
"@paraspell/assets": "11.14.8",
55+
"@paraspell/sdk-core": "11.14.8"
5656
},
5757
"devDependencies": {
5858
"@babel/plugin-syntax-import-attributes": "^7.26.0",
@@ -68,7 +68,8 @@
6868
"rollup-plugin-dts": "^6.2.1",
6969
"@langchain/ollama": "^0.2.2",
7070
"langchain": "^0.1.21",
71-
"@agentic/langchain": "^7.6.9"
71+
"@agentic/langchain": "^7.6.9",
72+
"@galacticcouncil/sdk": "^10.2.0"
7273
},
7374
"peerDependencies": {
7475
"ai": "^4.1.16"

0 commit comments

Comments
 (0)