Migration Guide v12 ➡ v13
This guide covers all breaking changes, API updates, and new features introduced in v13 of ParaSpell XCM Tools.
The update focuses on:
- Simplifying the builder API
- Removing deprecated and legacy functionality
- Unifying Swap integration support for all XCM SDKs
Tracking issue (For deep dive code checking):
https://github.com/paraspell/xcm-tools/issues/1624
⚠️ Breaking Changes
🛠️ Specific XCM API breaking changes
The XCM API has now moved under the paraspell.xyz domain, so instead of https://api.lightspell.xyz/v5/assets/Astar you now use https://api.paraspell.xyz/v1/assets/Astar.
🛠️ XCM Tools related changes (SDKs + API)
1. Builder API renaming
What changed
.senderAddress()→.sender().address()→.recipient()
This improves readability and aligns with natural terminology.
Before (v12)
builder
.senderAddress(sender)
.address(recipient)After (v13)
builder
.sender(sender)
.recipient(recipient)2. Fee estimation functions removed
What changed
All deprecated fee estimation functions (based on paymentInfo) have been removed.
List of functions and what they should be replaced by:
.getXcmFeeEstimate() -> .getXcmFee()
.getOriginXcmFeeEstimate() -> .getOriginXcmFee()Migration
- Remove any usage of fee estimation helpers
- Use XCM fee queries instead
3. /router API endpoint removed
What changed
The /router API endpoint has been removed.
Routing functionality is now fully integrated into the SDK builder.
Available as swap endpoint in API.
Migration
- Replace
/routerendpoint with swap endpoint
4. RouterBuilder usage change
What changed
RouterBuilderis now generic- It is no longer intended to be used directly from the swap package
Before (v12)
await RouterBuilder()
.from(TSubstrateChain)
.to(TChain)
.currencyFrom(currencyFrom)
.currencyTo(currencyTo)
.amount(amount)
.slippagePct(pct)
.senderAddress(injectorAddress)
.recipientAddress(recipientAddress)
.signer(signer)
.onStatusChange((status: TRouterEvent) => {
console.log(status.type);
console.log(status.routerPlan);
console.log(status.chain);
console.log(status.destinationChain);
console.log(status.currentStep);
})
.buildAndSend()After (v13)
const builder = Builder()
.from(TSubstrateChain)
.to(TChain)
.currency(CURRENCY_SPEC)
.recipient(address)
.sender(address)
.swap({
currencyTo: CURRENCY_SPEC,
})
const tx = await builder.buildAll()
await builder.disconnect()5. TSendOptions renamed
What changed
TSendOptions → TTransferOptionsMigration
- Replace all usages of
TSendOptionswithTTransferOptions
6. Deprecated asset helpers
What changed
The following functions are now deprecated:
hasSupportForAssetgetAssetIdgetAssetDecimals
These are deprecated in favor of findAssetInfo.
Migration
// ❌ Old
hasSupportForAsset(...)
getAssetId(...)
getAssetDecimals(...)
// ✅ New (Has all three information in one place)
findAssetInfo(...)7. findAssetInfo update
What changed
- Third parameter
destinationis now optional
Before (v12)
findAssetInfo(chain, CURRENCY_SPEC, destination)After (v13)
// If not given, nothing changes (unless destination is Ethereum and you are searching by Asset symbol, make sure to provide it in that case because you can get a duplicate asset error)
findAssetInfo(chain, CURRENCY_SPEC, destination?)8. getXcmFee response change
What changed
isExchangeflag has been moved- It now exists inside each
hop.result
Before (v12)
Accessing result:
result.hops[i].isExchangeExample result:
{
"origin": {
"weight": {
"refTime": "18446744073709551615",
"proofSize": "22338"
},
"fee": "14901746512880889",
"feeType": "dryRun",
"sufficient": false,
"asset": {
"symbol": "ASTR",
"isNative": true,
"decimals": 18,
"existentialDeposit": "1000000",
"location": {
"parents": 1,
"interior": {
"X1": [
{
"Parachain": 2006
}
]
}
}
}
},
"destination": {
"fee": "149",
"feeType": "dryRun",
"asset": {
"assetId": "10",
"symbol": "USDT",
"decimals": 6,
"existentialDeposit": "10000",
"location": {
"parents": 1,
"interior": {
"X3": [
{
"Parachain": 1000
},
{
"PalletInstance": 50
},
{
"GeneralIndex": 1984
}
]
}
},
"isFeeAsset": true,
"alias": "USDT1"
}
},
"hops": [
{
"chain": "AssetHubPolkadot",
"result": {
"fee": "327948830",
"feeType": "dryRun",
"sufficient": true,
"asset": {
"symbol": "DOT",
"isNative": true,
"decimals": 10,
"existentialDeposit": "100000000",
"location": {
"parents": 1,
"interior": {
"Here": null
}
},
"isFeeAsset": true
},
"forwardedXcms": [],
"weight": {
"refTime": "530928826",
"proofSize": "16264"
},
"isExchange": true
},
"isExchange": true
}
]
}After (v13)
Accessing result:
result.hops[i].result.isExchangeExample result:
{
"origin": {
"weight": {
"refTime": "18446744073709551615",
"proofSize": "22338"
},
"fee": "14901746512880889",
"feeType": "dryRun",
"sufficient": false,
"asset": {
"symbol": "ASTR",
"isNative": true,
"decimals": 18,
"existentialDeposit": "1000000",
"location": {
"parents": 1,
"interior": {
"X1": [
{
"Parachain": 2006
}
]
}
}
}
},
"destination": {
"fee": "149",
"feeType": "dryRun",
"asset": {
"assetId": "10",
"symbol": "USDT",
"decimals": 6,
"existentialDeposit": "10000",
"location": {
"parents": 1,
"interior": {
"X3": [
{
"Parachain": 1000
},
{
"PalletInstance": 50
},
{
"GeneralIndex": 1984
}
]
}
},
"isFeeAsset": true,
"alias": "USDT1"
}
},
"hops": [
{
"chain": "AssetHubPolkadot",
"result": {
"fee": "327948830",
"feeType": "dryRun",
"sufficient": true,
"asset": {
"symbol": "DOT",
"isNative": true,
"decimals": 10,
"existentialDeposit": "100000000",
"location": {
"parents": 1,
"interior": {
"Here": null
}
},
"isFeeAsset": true
},
"forwardedXcms": [],
"weight": {
"refTime": "530928826",
"proofSize": "16264"
},
"isExchange": true
},
}
]
}Migration
- Update any logic relying on
isExchangeto use the new location
9. Exchange parameter now takes TExchangeChain
What changed
- .exchange() parameter in Swap package now takes
TExchangeChainparameter, removingDexsuffix.
Before (v12)
.exchange("AssetHubPolkadotDex")After (v13)
.exchange("AssetHubPolkadot")Migration
Use TExchangeChain type:
.exchange("AssetHubPolkadot")✨ New Defaults & Behavior Changes
10. Abstract decimals enabled by default
What changed
abstractDecimalsis now enabled by default
Before (v12)
abstractDecimals: falseAfter (v13)
abstractDecimals: trueMigration
If you rely on raw decimals:
abstractDecimals: false🚀 New Features
11. signAndSubmitAll
What changed
A new method has been introduced:
signAndSubmitAll()Behavior
- Returns an array of transaction hexes
- Allows tracking of all submitted transactions
Comparison
// v13
signAndSubmit() // Used in one-click scenarios & basic transfers when a signer is provided to sender()
signAndSubmitAll() // Used in two-click swap scenarios when a signer is provided to sender()