Skip to content

Commit 57c5867

Browse files
committed
refactored according to feedback
1 parent 68da992 commit 57c5867

File tree

5 files changed

+106
-105
lines changed

5 files changed

+106
-105
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Builder, Version, BatchMode } from '@paraspell/sdk';
2+
3+
// Paseo has 10 decimals, use this to simplify.
4+
const PAS_UNITS = 10_000_000_000;
5+
// The RPC endpoints to connect to Paseo.
6+
// Not needed if using Polkadot.
7+
const PASEO_AH_RPC = 'wss://asset-hub-paseo.dotters.network';
8+
9+
async function batchTeleport() {
10+
const builder = Builder([PASEO_AH_RPC])
11+
.from('AssetHubPolkadot')
12+
.to('Polkadot')
13+
.currency({ symbol: 'DOT', amount: 1 * PAS_UNITS })
14+
.address('15whavTNSyceP8SL3Z1JukFcUPzmeR26RxKXkfQiPhsykg7s')
15+
.xcmVersion(Version.V5)
16+
.addToBatch()
17+
18+
.from('AssetHubPolkadot')
19+
.to('Polkadot')
20+
.currency({ symbol: 'DOT', amount: 1 * PAS_UNITS })
21+
.address('14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3')
22+
.xcmVersion(Version.V5)
23+
.addToBatch();
24+
const tx = await builder.buildBatch({
25+
// This settings object is optional and batch all is the default option
26+
mode: BatchMode.BATCH_ALL //or BatchMode.BATCH
27+
})
28+
const callData = await tx.getEncodedData();
29+
30+
// This generates a link the polkadot developer console.
31+
// Once there, it's easy to submit.
32+
console.log(`Send via PAPI console:
33+
https://dev.papi.how/extrinsics#networkId=paseo_asset_hub&endpoint=light-client&data=${callData.asHex()}
34+
`);
35+
}
36+
37+
batchTeleport();

develop/interoperability/best-practices-for-teleporting-assets.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ You can find a full list of XCM errors in the [Polkadot Rust Docs](https://parit
312312

313313
### TestNet vs MainNet Configuration
314314

315-
Different networks within the Polkadot ecosystem have varying characteristics that affect teleportation implementation. TestNet environments like Paseo use different decimal precision (12 for PAS vs 10 for DOT), can have different existential deposit amounts, and require test-specific RPC endpoints. Always use appropriate configuration for the target environment and avoid mixing TestNet and MainNet configurations.
315+
Different networks within the Polkadot ecosystem have varying characteristics that affect teleportation implementation. TestNet environments like [Paseo](/develop/networks/#paseo){target=\_blank} use different decimal precision (12 for PAS vs 10 for DOT), can have different existential deposit amounts, and require test-specific RPC endpoints. Always use appropriate configuration for the target environment and avoid mixing TestNet and MainNet configurations.
316316

317317
MainNet production environments require higher existential deposits, involve real economic value at risk, experience network congestion that affects fees, and have stricter validation requirements. Plan for these production realities by implementing robust error handling, fee buffers, and comprehensive monitoring systems.
318318

llms.txt

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -837,7 +837,7 @@ You can find a full list of XCM errors in the [Polkadot Rust Docs](https://parit
837837

838838
### TestNet vs MainNet Configuration
839839

840-
Different networks within the Polkadot ecosystem have varying characteristics that affect teleportation implementation. TestNet environments like Paseo use different decimal precision (12 for PAS vs 10 for DOT), can have different existential deposit amounts, and require test-specific RPC endpoints. Always use appropriate configuration for the target environment and avoid mixing TestNet and MainNet configurations.
840+
Different networks within the Polkadot ecosystem have varying characteristics that affect teleportation implementation. TestNet environments like [Paseo](/develop/networks/#paseo){target=\_blank} use different decimal precision (12 for PAS vs 10 for DOT), can have different existential deposit amounts, and require test-specific RPC endpoints. Always use appropriate configuration for the target environment and avoid mixing TestNet and MainNet configurations.
841841

842842
MainNet production environments require higher existential deposits, involve real economic value at risk, experience network congestion that affects fees, and have stricter validation requirements. Plan for these production realities by implementing robust error handling, fee buffers, and comprehensive monitoring systems.
843843

@@ -22711,9 +22711,9 @@ The Foreign Assets pallet, an instance of the Assets pallet, manages these asset
2271122711

2271222712
## Sufficient and Non-Sufficient Assets
2271322713

22714-
[Sufficient assets](https://wiki.polkadot.network/learn/learn-assets/#sufficient-assets) are assets that have been voted upon and approved by governance that can suffice for account existence. This means that sufficient assets can be used for an account's [existential deposit](https://wiki.polkadot.network/learn/learn-accounts/#existential-deposit-and-reaping) on Asset Hub.
22714+
[Sufficient assets](https://wiki.polkadot.network/learn/learn-assets/#sufficient-assets){target=\_blank} are assets that have been voted upon and approved by governance that can suffice for account existence. This means that sufficient assets can be used for an account's [existential deposit](https://wiki.polkadot.network/learn/learn-accounts/#existential-deposit-and-reaping){target=\_blank} on Asset Hub.
2271522715

22716-
Non-sufficient assets, on the other hand, **cannot** suffice on their own for account existence. Non-sufficient assets rely on a sufficient asset for the existential deposit. However, through the use of [asset conversion](https://wiki.polkadot.network/learn/learn-asset-conversion-assethub/), non-sufficient assets can be treated as first-class citizens on Asset Hub with similar functionality to sufficient assets, creating a seamless experience for end users.
22716+
Non-sufficient assets, on the other hand, **cannot** suffice on their own for account existence. Non-sufficient assets rely on a sufficient asset for the existential deposit. However, through the use of [asset conversion](https://wiki.polkadot.network/learn/learn-asset-conversion-assethub/){target=\_blank}, non-sufficient assets can be treated as first-class citizens on Asset Hub with similar functionality to sufficient assets, creating a seamless experience for end users.
2271722717

2271822718
### Sufficient Assets
2271922719

@@ -22726,9 +22726,9 @@ On Asset Hub, sufficient assets:
2272622726

2272722727
### Non-Sufficient Assets
2272822728

22729-
Through the use of [asset conversion](https://wiki.polkadot.network/learn/learn-asset-conversion-assethub), Asset Hub provides an abstraction layer and mechanism that can convert any asset regardless of asset type (sufficient or non-sufficient) to the parachain's native asset which in turn allows for non-sufficient assets to be swapped for the native asset to pay for the existential deposit, the transaction fee, the XCM fee, and the storage deposit.
22729+
Through the use of [asset conversion](https://wiki.polkadot.network/learn/learn-asset-conversion-assethub){target=\_blank}, Asset Hub provides an abstraction layer and mechanism that can convert any asset regardless of asset type (sufficient or non-sufficient) to the parachain's native asset which in turn allows for non-sufficient assets to be swapped for the native asset to pay for the existential deposit, the transaction fee, the XCM fee, and the storage deposit.
2273022730

22731-
This allows developers to create a seamless experience for end users by allowing end users to use any asset as long as the asset has a [liquidity pool set up](https://wiki.polkadot.network/learn/learn-guides-asset-conversion/#create-a-liquidity-pool) against the native asset (e.g. DOT) on Asset Hub and has healthy liquidity in the pool to prevent getting burned on swaps.
22731+
This allows developers to create a seamless experience for end users by allowing end users to use any asset as long as the asset has a [liquidity pool set up](https://wiki.polkadot.network/learn/learn-guides-asset-conversion/#create-a-liquidity-pool){target=\_blank} against the native asset (e.g. DOT) on Asset Hub and has healthy liquidity in the pool to prevent getting burned on swaps.
2273222732

2273322733
!!!note "Parachain Compatibility"
2273422734
It is important to note that the functionality covered on this page is configured for Asset Hub. Depending on the use case, the destination parachain or sending parachain may also need to be configured in a similar manner (e.g. supporting sufficient assets, support ED in any sufficient asset, paying fees in any sufficient asset, swapping a non-sufficient asset for a native asset) to allow for the features covered on this page to also exist on that chain.
@@ -22739,7 +22739,7 @@ This allows developers to create a seamless experience for end users by allowing
2273922739

2274022740
### Transaction Fees
2274122741

22742-
On Asset Hub, both sufficient and non-sufficient assets can be used for paying transaction fees. For sufficient assets, Asset Hub natively converts the native asset (e.g. DOT) amount required to an asset balance and the signer actually pays that asset to a collator. And for non-sufficient assets on Asset Hub developers can leverage [asset conversion](https://wiki.polkadot.network/learn/learn-asset-conversion-assethub) via a [swap](/tutorials/polkadot-sdk/system-chains/asset-hub/asset-conversion/) or an XCM `ExchangeAsset` instruction to swap the non-sufficient asset for the native asset. For this to work, non-sufficient assets need to have a [liquidity pool set up](https://wiki.polkadot.network/learn/learn-guides-asset-conversion/#create-a-liquidity-pool) against the native asset (e.g. DOT).
22742+
On Asset Hub, both sufficient and non-sufficient assets can be used for paying transaction fees. For sufficient assets, Asset Hub natively converts the native asset (e.g. DOT) amount required to an asset balance and the signer actually pays that asset to a collator. And for non-sufficient assets on Asset Hub developers can leverage [asset conversion](https://wiki.polkadot.network/learn/learn-asset-conversion-assethub){target=\_blank} via a [swap](/tutorials/polkadot-sdk/system-chains/asset-hub/asset-conversion/) or an XCM `ExchangeAsset` instruction to swap the non-sufficient asset for the native asset. For this to work, non-sufficient assets need to have a [liquidity pool set up](https://wiki.polkadot.network/learn/learn-guides-asset-conversion/#create-a-liquidity-pool){target=\_blank} against the native asset (e.g. DOT).
2274322743

2274422744
!!!note
2274522745
UI's, wallets, and tools may have limitations because of design decisions and/or contraints it places e.g. constructing the XCM call in a specific manner and therefore limiting the end user when in reality Asset Hub encompasses more functionality such as the ability to pay transaction fees and XCM fees in any asset.
@@ -22748,23 +22748,23 @@ On Asset Hub, both sufficient and non-sufficient assets can be used for paying t
2274822748

2274922749
Both sufficient assets and non-sufficient assets can be used to pay for XCM fees on Asset Hub. However, it is important to note that the XCM program needs to explicitly reference the asset to pay the XCM fee in.
2275022750

22751-
For non-sufficient assets, this can be done by calling [asset conversion's swap](https://paritytech.github.io/polkadot-sdk/master/pallet_asset_conversion/pallet/dispatchables/fn.swap_tokens_for_exact_tokens.html) or including an [`ExchangeAsset`](https://paritytech.github.io/polkadot-sdk/master/cumulus_primitives_core/enum.Instruction.html#variant.ExchangeAsset) instruction in the XCM program to swap the non-sufficient asset for the native asset to pay for the XCM fee.
22751+
For non-sufficient assets, this can be done by calling [asset conversion's swap](https://paritytech.github.io/polkadot-sdk/master/pallet_asset_conversion/pallet/dispatchables/fn.swap_tokens_for_exact_tokens.html){target=\_blank} or including an [`ExchangeAsset`](https://paritytech.github.io/polkadot-sdk/master/cumulus_primitives_core/enum.Instruction.html#variant.ExchangeAsset){target=\_blank} instruction in the XCM program to swap the non-sufficient asset for the native asset to pay for the XCM fee.
2275222752

2275322753
!!!note "UIs, Wallets, and Tools Interacting with Asset Hub"
2275422754
When developing cross-chain applications to interact with Asset Hub it is important to consider the UI/UX and the trade-offs it may have.
2275522755

2275622756
Example Scenario: Sending 100 USDT to a new Asset Hub account
2275722757
Option 1 - Deduct from sending amount:
2275822758

22759-
Receiver gets: 100 USDT - 0.01 DOT (for ED) - transaction and XCM fees
22760-
Sender pays exactly 100 USDT total
22761-
Simpler for sender, but receiver gets less than expected
22759+
- Receiver gets: 100 USDT - 0.01 DOT (for ED) - transaction and XCM fees
22760+
- Sender pays exactly 100 USDT total
22761+
- Simpler for sender, but receiver gets less than expected
2276222762

2276322763
Option 2 - Additional sender cost:
2276422764

22765-
Receiver gets: full 100 USDT + 0.01 DOT (for ED)
22766-
Sender pays: 100 USDT + 0.01 DOT (for ED) + transaction and XCM fees
22767-
More expensive for sender, but receiver gets full amount
22765+
- Receiver gets: full 100 USDT + 0.01 DOT (for ED)
22766+
- Sender pays: 100 USDT + 0.01 DOT (for ED) + transaction and XCM fees
22767+
- More expensive for sender, but receiver gets full amount
2276822768

2276922769
Each approach requires different XCM program construction and affects the overall user experience.
2277022770

@@ -36065,33 +36065,33 @@ Doc-Content: https://docs.polkadot.com/tutorials/polkadot-sdk/system-chains/asse
3606536065
--- BEGIN CONTENT ---
3606636066
---
3606736067
title: Batch Teleport Assets
36068-
description: A tutorial detailing the step-by-step process of batch teleporting assets
36068+
description: A comprehensive tutorial detailing the step-by-step process of batch teleporting assets across Polkadot parachains using ParaSpell SDK
3606936069
tutorial_badge: Intermediate
3607036070
---
3607136071

3607236072
# Batch Teleport Assets
3607336073

3607436074
## Introduction
3607536075

36076-
Cross-chain asset transfers are a fundamental feature of the Polkadot ecosystem, enabling seamless movement of tokens between different parachains. The [ParaSpell SDK](https://paraspell.github.io/docs/){target=_blank} simplifies this process by providing powerful tools for executing both single and batch teleport operations.
36076+
Cross-chain asset transfers are a fundamental feature of the Polkadot ecosystem, enabling seamless movement of tokens between different parachains. The [ParaSpell SDK](https://paraspell.github.io/docs/){target=\_blank} simplifies this process by providing powerful tools for executing both single and batch teleport operations.
3607736077

36078-
This tutorial will guide you through creating batch teleport transactions using the [ParaSpell SDK](https://paraspell.github.io/docs/){target=_blank}. You'll learn how to bundle multiple cross-chain transfers into a single transaction, making your operations more efficient and cost-effective. By the end, you'll be able to execute batch teleports between Polkadot Hub chains and understand the underlying mechanisms.
36078+
This tutorial will guide you through creating batch teleport transactions using the [ParaSpell SDK](https://paraspell.github.io/docs/){target=\_blank}. You'll learn how to bundle multiple cross-chain transfers into a single transaction, making your operations more efficient and cost-effective. By the end, you'll be able to execute batch teleports between Polkadot Hub chains and understand the underlying mechanisms.
3607936079

3608036080
## Prerequisites
3608136081

3608236082
Before getting started, ensure you have the following:
3608336083

36084-
- [Bun](https://bun.sh/){target=_blank} v1.0 or later installed on your system
36084+
- [Bun](https://bun.sh/){target=\_blank} v1.0 or later installed on your system
3608536085
- A Polkadot wallet with sufficient test tokens for transaction fees
3608636086
- Basic understanding of TypeScript/JavaScript
36087-
- General understanding of the [Polkadot protocol](/polkadot-protocol/parachain-basics/){target=_blank}
36088-
- Some knowledge of [XCM (Cross-Consensus Messaging)](/develop/interoperability/intro-to-xcm/){target=_blank}
36087+
- General understanding of the [Polkadot protocol](/polkadot-protocol/parachain-basics/){target=\_blank}
36088+
- Some knowledge of [XCM (Cross-Consensus Messaging)](/develop/interoperability/intro-to-xcm/){target=\_blank}
3608936089

3609036090
## Project Overview
3609136091

3609236092
This tutorial demonstrates how to create batch teleport transactions that can transfer tokens from one parachain to multiple destinations on the Polkadot relay chain in a single operation. You'll work with:
3609336093

36094-
- [Asset Hub](/polkadot-protocol/architecture/system-chains/asset-hub/){target=_blank} as the source chain
36094+
- [Asset Hub](/polkadot-protocol/architecture/system-chains/asset-hub/){target=\_blank} as the source chain
3609536095
- Multiple destination addresses
3609636096
- DOT/PAS tokens as the transferred assets
3609736097
- Batch transaction construction and execution
@@ -36158,10 +36158,9 @@ bun add @paraspell/sdk@{{dependencies.javascript_packages.paraspell_sdk.version}
3615836158

3615936159
## Create the Implementation
3616036160

36161-
Create an `index.ts` file with the complete batch teleport implementation.
36162-
> For testing purposes, you will be using [Paseo Asset Hub](/develop/networks/#paseo){target=_blank} (a Polkadot community-driven TestNet).
36161+
Create an `index.ts` file with the complete batch teleport implementation. For testing purposes, you will be using [Paseo Asset Hub](/develop/networks/#paseo){target=\_blank} (a Polkadot community-driven TestNet).
3616336162

36164-
```typescript
36163+
```typescript title="index.ts"
3616536164
import { Builder, Version, BatchMode } from '@paraspell/sdk';
3616636165

3616736166
// Paseo has 10 decimals, use this to simplify.
@@ -36170,9 +36169,7 @@ const PAS_UNITS = 10_000_000_000;
3617036169
// Not needed if using Polkadot.
3617136170
const PASEO_AH_RPC = 'wss://asset-hub-paseo.dotters.network';
3617236171

36173-
teleport();
36174-
36175-
async function teleport() {
36172+
async function batchTeleport() {
3617636173
const builder = Builder([PASEO_AH_RPC])
3617736174
.from('AssetHubPolkadot')
3617836175
.to('Polkadot')
@@ -36199,20 +36196,22 @@ async function teleport() {
3619936196
https://dev.papi.how/extrinsics#networkId=paseo_asset_hub&endpoint=light-client&data=${callData.asHex()}
3620036197
`);
3620136198
}
36199+
36200+
batchTeleport();
3620236201
```
3620336202

3620436203
!!!note "Understanding Batch Modes"
3620536204
The ParaSpell SDK supports two batch modes:
3620636205

36207-
### BatchMode.BATCH_ALL
36208-
- **Behavior**: All operations must succeed, or the entire batch fails
36209-
- **Use Case**: When all transfers are critical and interdependent
36210-
- **Gas Efficiency**: More efficient as it's a single atomic operation
36206+
- BatchMode.BATCH_ALL
36207+
- **Behavior**: All operations must succeed, or the entire batch fails
36208+
- **Use Case**: When all transfers are critical and interdependent
36209+
- **Gas Efficiency**: More efficient as it's a single atomic operation
3621136210

36212-
### BatchMode.BATCH
36213-
- **Behavior**: Individual operations can fail independently
36214-
- **Use Case**: When some transfers can fail without affecting others
36215-
- **Resilience**: More resilient but with slightly higher gas overhead
36211+
- BatchMode.BATCH
36212+
- **Behavior**: Individual operations can fail independently
36213+
- **Use Case**: When some transfers can fail without affecting others
36214+
- **Resilience**: More resilient but with slightly higher gas overhead
3621636215

3621736216
Update your `package.json` to include the necessary scripts:
3621836217

@@ -36225,7 +36224,8 @@ Update your `package.json` to include the necessary scripts:
3622536224
"type": "module",
3622636225
"scripts": {
3622736226
"start": "bun run index.ts",
36228-
"dev": "bun run index.ts"
36227+
"dev": "bun run --watch index.ts" // --watch automatically restarts the script when files change
36228+
},
3622936229
},
3623036230
"dependencies": {
3623136231
"@paraspell/sdk": "^{{dependencies.javascript_packages.paraspell_sdk.version}}"

0 commit comments

Comments
 (0)