Skip to content

Commit 0faf98f

Browse files
committed
fix: send tx with rpc
1 parent ff2c42b commit 0faf98f

File tree

12 files changed

+697
-1
lines changed

12 files changed

+697
-1
lines changed
Lines changed: 279 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,279 @@
1-
TODO
1+
---
2+
title: Send Transactions with SDKs
3+
description: Learn how to construct, sign, and submit transactions using PAPI, Polkadot.js, Dedot, Python Substrate Interface, and Subxt.
4+
categories: Chain Interactions
5+
---
6+
7+
# Send Transactions with SDKs
8+
9+
## Introduction
10+
11+
Sending transactions on Polkadot SDK-based blockchains involves constructing an extrinsic (transaction), signing it with your account's private key, and submitting it to the network. Each SDK provides different methods for transaction construction, signing, and submission.
12+
13+
This guide demonstrates how to send transactions using five popular SDKs:
14+
15+
- **[Polkadot API (PAPI)](/reference/tools/papi/){target=\_blank}** - Modern TypeScript library with type-safe APIs
16+
- **[Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank}** - Comprehensive JavaScript library (maintenance mode)
17+
- **[Dedot](/reference/tools/dedot/){target=\_blank}** - Lightweight TypeScript library optimized for performance
18+
- **[Python Substrate Interface](/reference/tools/py-substrate-interface/){target=\_blank}** - Python library for Substrate chains
19+
- **[Subxt](/reference/tools/subxt/){target=\_blank}** - Rust library with compile-time type safety
20+
21+
Select your preferred SDK below to see complete, runnable examples that send balance transfer transactions on Polkadot Hub.
22+
23+
!!! note
24+
Ensure to replace `INSERT_WS_ENDPOINT` with the proper WebSocket endpoint, `INSERT_SENDER_MNEMONIC` with your account's mnemonic phrase, and `INSERT_DEST_ADDRESS` with the recipient address. For this example, you can use Polkadot Hub (`wss://polkadot-asset-hub-rpc.polkadot.io`).
25+
26+
!!! warning
27+
Never share your mnemonic phrase or private keys. The examples below use mnemonics for demonstration purposes only. In production, use secure key management solutions.
28+
29+
## Send Transactions
30+
31+
=== "PAPI"
32+
33+
[Polkadot API (PAPI)](/reference/tools/papi/){target=\_blank} is a modern, type-safe TypeScript library optimized for light-client functionality.
34+
35+
**Prerequisites**
36+
37+
- [Node.js](https://nodejs.org/){target=\_blank} v18 or higher
38+
- npm, pnpm, or yarn package manager
39+
40+
**Environment Setup**
41+
42+
1. Create and initialize a new project:
43+
44+
```bash
45+
mkdir papi-send-tx-example && cd papi-send-tx-example && \
46+
npm init -y && npm pkg set type=module
47+
```
48+
49+
2. Install dependencies:
50+
51+
```bash
52+
npm install polkadot-api @polkadot/util-crypto @polkadot/keyring && \
53+
npm install --save-dev @types/node tsx typescript
54+
```
55+
56+
3. Generate types for Polkadot Hub TestNet:
57+
58+
```bash
59+
npx papi add polkadotTestNet -w wss://asset-hub-paseo.dotters.network
60+
```
61+
62+
**Send Balance Transfer**
63+
64+
The following example constructs, signs, and submits a balance transfer transaction.
65+
66+
Create a file named `send-transfer.ts`:
67+
68+
```typescript title="send-transfer.ts"
69+
--8<-- "code/chain-interactions/send-transactions/with-sdks/papi/send-transfer.ts"
70+
```
71+
72+
Run the script:
73+
74+
```bash
75+
npx tsx send-transfer.ts
76+
```
77+
78+
You should see output similar to:
79+
80+
--8<-- 'code/chain-interactions/send-transactions/with-sdks/papi/send-transfer-ts.html'
81+
82+
=== "Polkadot.js"
83+
84+
!!! warning "Maintenance Mode Only"
85+
The Polkadot.js API is no longer actively developed. New projects should use [PAPI](/reference/tools/papi/){target=\_blank} or [Dedot](/reference/tools/dedot/){target=\_blank} as actively maintained alternatives.
86+
87+
[Polkadot.js API](/reference/tools/polkadot-js-api/){target=\_blank} is a comprehensive JavaScript library with extensive ecosystem support.
88+
89+
**Prerequisites**
90+
91+
- [Node.js](https://nodejs.org/){target=\_blank} v18 or higher
92+
- npm, pnpm, or yarn package manager
93+
94+
**Environment Setup**
95+
96+
1. Create and initialize a new project:
97+
98+
```bash
99+
mkdir pjs-send-tx-example && cd pjs-send-tx-example && \
100+
npm init -y && npm pkg set type=module
101+
```
102+
103+
2. Install dependencies:
104+
105+
```bash
106+
npm install @polkadot/api @polkadot/keyring @polkadot/util-crypto
107+
```
108+
109+
**Send Balance Transfer**
110+
111+
The following example constructs, signs, and submits a balance transfer transaction.
112+
113+
Create a file named `send-transfer.js`:
114+
115+
```javascript title="send-transfer.js"
116+
--8<-- "code/chain-interactions/send-transactions/with-sdks/pjs/send-transfer.js"
117+
```
118+
119+
Run the script:
120+
121+
```bash
122+
node send-transfer.js
123+
```
124+
125+
You should see output similar to:
126+
127+
--8<-- 'code/chain-interactions/send-transactions/with-sdks/pjs/send-transfer-js.html'
128+
129+
=== "Dedot"
130+
131+
[Dedot](/reference/tools/dedot/){target=\_blank} is a next-generation TypeScript client that's lightweight, tree-shakable, and maintains API compatibility with Polkadot.js.
132+
133+
**Prerequisites**
134+
135+
- [Node.js](https://nodejs.org/){target=\_blank} v18 or higher
136+
- npm, pnpm, or yarn package manager
137+
138+
**Environment Setup**
139+
140+
1. Create and initialize a new project:
141+
142+
```bash
143+
mkdir dedot-send-tx-example && cd dedot-send-tx-example && \
144+
npm init -y && npm pkg set type=module
145+
```
146+
147+
2. Install dependencies:
148+
149+
```bash
150+
npm install dedot @polkadot/keyring @polkadot/util-crypto && \
151+
npm install --save-dev @dedot/chaintypes @types/node tsx typescript
152+
```
153+
154+
**Send Balance Transfer**
155+
156+
The following example constructs, signs, and submits a balance transfer transaction.
157+
158+
Create a file named `send-transfer.ts`:
159+
160+
```typescript title="send-transfer.ts"
161+
--8<-- "code/chain-interactions/send-transactions/with-sdks/dedot/send-transfer.ts"
162+
```
163+
164+
Run the script:
165+
166+
```bash
167+
npx tsx send-transfer.ts
168+
```
169+
170+
You should see output similar to:
171+
172+
--8<-- 'code/chain-interactions/send-transactions/with-sdks/dedot/send-transfer-ts.html'
173+
174+
=== "Python"
175+
176+
[Python Substrate Interface](/reference/tools/py-substrate-interface/){target=\_blank} provides a Python library for interacting with Substrate-based chains.
177+
178+
**Prerequisites**
179+
180+
- [Python](https://www.python.org/){target=\_blank} 3.8 or higher
181+
- pip package manager
182+
183+
**Environment Setup**
184+
185+
1. Create a new project directory and set up a virtual environment:
186+
187+
```bash
188+
mkdir psi-send-tx-example && cd psi-send-tx-example && \
189+
python3 -m venv venv && source venv/bin/activate
190+
```
191+
192+
2. Install the substrate-interface package:
193+
194+
```bash
195+
pip install substrate-interface
196+
```
197+
198+
**Send Balance Transfer**
199+
200+
The following example constructs, signs, and submits a balance transfer transaction.
201+
202+
Create a file named `send_transfer.py`:
203+
204+
```python title="send_transfer.py"
205+
--8<-- "code/chain-interactions/send-transactions/with-sdks/psi/send_transfer.py"
206+
```
207+
208+
Run the script:
209+
210+
```bash
211+
python send_transfer.py
212+
```
213+
214+
You should see output similar to:
215+
216+
--8<-- 'code/chain-interactions/send-transactions/with-sdks/psi/send-transfer-py.html'
217+
218+
=== "Subxt"
219+
220+
[Subxt](/reference/tools/subxt/){target=\_blank} is a Rust library that provides compile-time type safety through code generation from chain metadata.
221+
222+
**Prerequisites**
223+
224+
- [Rust](https://rustup.rs/){target=\_blank} toolchain (latest stable)
225+
- Cargo package manager
226+
227+
**Environment Setup**
228+
229+
1. Create a new Rust project:
230+
231+
```bash
232+
cargo new subxt-send-tx-example && cd subxt-send-tx-example
233+
```
234+
235+
2. Install the Subxt CLI:
236+
237+
```bash
238+
cargo install subxt-cli@{{ dependencies.crates.subxt_cli.version }}
239+
```
240+
241+
3. Download the Polkadot Hub metadata:
242+
243+
```bash
244+
subxt metadata --url INSERT_WS_ENDPOINT -o asset_hub_metadata.scale
245+
```
246+
247+
4. Update `Cargo.toml` with the required dependencies:
248+
249+
```toml title="Cargo.toml"
250+
--8<-- "code/chain-interactions/send-transactions/with-sdks/subxt/Cargo.toml"
251+
```
252+
253+
**Send Balance Transfer**
254+
255+
The following example constructs, signs, and submits a balance transfer transaction.
256+
257+
Create a file at `src/bin/send_transfer.rs`:
258+
259+
```rust title="src/bin/send_transfer.rs"
260+
--8<-- "code/chain-interactions/send-transactions/with-sdks/subxt/src/bin/send_transfer.rs"
261+
```
262+
263+
Run the script:
264+
265+
```bash
266+
cargo run --bin send_transfer
267+
```
268+
269+
You should see output similar to:
270+
271+
--8<-- 'code/chain-interactions/send-transactions/with-sdks/subxt/send-transfer-rs.html'
272+
273+
## Where to Go Next
274+
275+
Now that you understand how to send transactions, explore these related topics:
276+
277+
- **[Query On-Chain State](/chain-interactions/query-data/query-sdks/)** - Learn to query storage and runtime data
278+
- **[Calculate Transaction Fees](/chain-interactions/send-transactions/calculate-transaction-fees/)** - Estimate fees before sending transactions
279+
- **[SDK Reference Pages](/reference/tools/papi/)** - Detailed documentation for each SDK
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<div class="termynal" data-termynal>
2+
<span data-ty="input"><span class="file-path"></span>npx tsx send-transfer.ts</span>
3+
<span data-ty></span>Connected to Polkadot Testnet</span>
4+
<span data-ty>Sender address: 5GgbDVeKZwCmMHzn58iFSgSZDTojRMM52arXnuNXto28R7mg</span>
5+
<span data-ty>Recipient address: 5GgbDVeKZwCmMHzn58iFSgSZDTojRMM52arXnuNXto28R7mg</span>
6+
<span data-ty>Amount: 1000000000 (1 PAS)</span>
7+
<span data-ty></span>
8+
<span data-ty>Sender balance: 59868680224</span>
9+
<span data-ty></span>
10+
<span data-ty>Signing and submitting transaction...</span>
11+
<span data-ty>Transaction status: Validated</span>
12+
<span data-ty>Transaction status: Broadcasting</span>
13+
<span data-ty>Transaction status: BestChainBlockIncluded</span>
14+
<span data-ty>Transaction included in block: 0x80b039e897d8cfe4ec0c641cd17cc7a47ed4b26797b31c7d3c93c3b0b96f7b9f</span>
15+
<span data-ty>Transaction status: Finalized</span>
16+
<span data-ty>Transaction hash: 0x325a1c1cff76fb6a004190cf5ee382f89433596b3c396f10fd25ce6945f2b1df</span>
17+
<span data-ty>Transaction finalized in block: 0x80b039e897d8cfe4ec0c641cd17cc7a47ed4b26797b31c7d3c93c3b0b96f7b9f</span>
18+
<span data-ty>Transaction successful!</span>
19+
<span data-ty>Disconnected from Polkadot Testnet</span>
20+
</div>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { DedotClient, WsProvider } from "dedot";
2+
import type { PolkadotAssetHubApi } from "@dedot/chaintypes";
3+
import { cryptoWaitReady } from "@polkadot/util-crypto";
4+
import { Keyring } from "@polkadot/keyring";
5+
6+
const POLKADOT_TESTNET_RPC = "INSERT_RPC_URL";
7+
const SENDER_MNEMONIC = "INSERT_MNEMONIC";
8+
const DEST_ADDRESS = "INSERT_DEST_ADDRESS";
9+
const AMOUNT = 1_000_000_000n; // 1 PAS (adjust decimals as needed)
10+
11+
async function main() {
12+
// Wait for crypto to be ready
13+
await cryptoWaitReady();
14+
15+
// Initialize provider and client with Asset Hub types
16+
const provider = new WsProvider(POLKADOT_TESTNET_RPC);
17+
const client = await DedotClient.new<PolkadotAssetHubApi>(provider);
18+
19+
console.log("Connected to Polkadot Testnet");
20+
21+
// Set up keyring and get sender account
22+
const keyring = new Keyring({ type: "sr25519" });
23+
const sender = keyring.addFromMnemonic(SENDER_MNEMONIC);
24+
const senderAddress = sender.address;
25+
26+
console.log(`Sender address: ${senderAddress}`);
27+
console.log(`Recipient address: ${DEST_ADDRESS}`);
28+
console.log(`Amount: ${AMOUNT} (${AMOUNT / 1_000_000_000n} PAS)\n`);
29+
30+
// Get sender's account info to check balance
31+
const accountInfo = await client.query.system.account(senderAddress);
32+
console.log(`Sender balance: ${accountInfo.data.free}`);
33+
34+
// Sign and submit the transfer transaction
35+
console.log("\nSigning and submitting transaction...");
36+
37+
// Wait for transaction to complete using a Promise
38+
await new Promise<void>((resolve, reject) => {
39+
client.tx.balances
40+
.transferKeepAlive(DEST_ADDRESS, AMOUNT)
41+
.signAndSend(sender, async ({ status, txHash, dispatchError }) => {
42+
console.log(`Transaction status: ${status.type}`);
43+
44+
// Log transaction hash immediately
45+
if (txHash) {
46+
console.log(`Transaction hash: ${typeof txHash === 'string' ? txHash : txHash.toHex()}`);
47+
}
48+
49+
if (status.type === "BestChainBlockIncluded") {
50+
console.log(`Transaction included in block: ${status.value.blockHash}`);
51+
}
52+
53+
if (status.type === "Finalized") {
54+
console.log(`Transaction finalized in block: ${status.value.blockHash}`);
55+
56+
// Check for dispatch errors
57+
if (dispatchError) {
58+
if (dispatchError.type === 'Module') {
59+
const decoded = client.registry.findMetaError(dispatchError.value);
60+
console.error(`Dispatch error: ${decoded.section}.${decoded.name}: ${decoded.docs}`);
61+
reject(new Error(`Transaction failed: ${decoded.section}.${decoded.name}`));
62+
} else {
63+
console.error(`Dispatch error: ${dispatchError.type}`);
64+
reject(new Error(`Transaction failed: ${dispatchError.type}`));
65+
}
66+
} else {
67+
console.log("Transaction successful!");
68+
resolve();
69+
}
70+
}
71+
})
72+
.catch(reject);
73+
});
74+
75+
// Disconnect the client after transaction completes
76+
await client.disconnect();
77+
console.log("Disconnected from Polkadot Hub");
78+
}
79+
80+
main().catch(console.error);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<div class="termynal" data-termynal>
2+
<span data-ty="input"><span class="file-path"></span>npx tsx send-transfer.ts</span>
3+
<span data-ty>Sender address: 5GgbDVeKZwCmMHzn58iFSgSZDTojRMM52arXnuNXto28R7mg</span>
4+
<span data-ty>Connected to Polkadot Testnet</span>
5+
<span data-ty>Signing and submitting transaction...</span>
6+
<span data-ty>Transaction submitted with hash: 0x45ce4b5223428d003ddeed5118182eede1224dd0b6e881d7ed40517d60aa1c57</span>
7+
<span data-ty>Disconnected</span>
8+
</div>

0 commit comments

Comments
 (0)