Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .papi/descriptors/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.0-autogenerated.5713703155598959433",
"version": "0.1.0-autogenerated.10336401122289269029",
"name": "@polkadot-api/descriptors",
"files": [
"dist"
Expand Down
Binary file added .papi/metadata/paseo.scale
Binary file not shown.
8 changes: 7 additions & 1 deletion .papi/polkadot-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
"wsUrl": "wss://hydration-rpc.n.dwellir.com",
"metadata": ".papi/metadata/hydra.scale",
"genesis": "0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d"
},
"paseo": {
"chain": "paseo",
"metadata": ".papi/metadata/paseo.scale",
"genesis": "0x77afd6190f1554ad45fd0d31aee62aacc33c6db0ea801129acb813f913e0764f",
"codeHash": "0xcc4b027a0dbb5e0f389dd8418c41012d618290a22f84af8411c8fd20b2738304"
}
}
}
}
10 changes: 10 additions & 0 deletions examples/telegram-bot/src/TelegramBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,22 @@ export class TelegramBot {
const xcmTransferNativeAsset = this.agent.xcmTransferNativeTool();

const swapTokens = this.agent.swapTokensTool();
const joinPool = this.agent.joinPoolTool();
const bondExtra = this.agent.bondExtraTool();
const unbond = this.agent.unbondTool();
const claimRewards = this.agent.claimRewardsTool();
const withdrawUnbonded = this.agent.withdrawUnbondedTool();

setupHandlers(this.bot, this.llm, {
checkBalance: checkBalance,
transferNative: transferNative,
xcmTransferNativeAsset: xcmTransferNativeAsset,
swapTokens: swapTokens,
joinPool: joinPool,
bondExtra: bondExtra,
unbond: unbond,
claimRewards: claimRewards,
withdrawUnbonded: withdrawUnbonded
});

console.log("Bot initialization complete");
Expand Down
70 changes: 70 additions & 0 deletions examples/telegram-bot/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ CHAIN NAME CONVERSION RULES for transfer tokens through XCM: When users mention
| Polkadot Asset Hub | polkadot_asset_hub |



CHAIN NAME CONVERSION RULES for nominating to a pool: When users mention chain names in nominating to a pool, I must convert them to the correct parameter values using this mapping:

| User Input | Real Param (USE THIS IN TOOL CALLS) |
|------------|-------------------------------------|
| dot | polkadot |
| polkadot | polkadot |
| Polkadot | polkadot |
| Westend | westend |
| Paseo | paseo |




CHAIN NAME CONVERSION RULES for swap tokens (when users mention chain names in swap): When users mention chain names in swap, I must convert them to the correct parameter values using this mapping:

| User Input | Real Param (USE THIS IN TOOL CALLS) |
Expand Down Expand Up @@ -116,6 +130,56 @@ Tool call should use: currencyFrom: "DOT", currencyTo: "USDT", amount: "0.1", de
User: "swap 0.1 DOT to USDT on HydrationDex to 5D7jcv6aYbhbYGVY8k65oemM6FVNoyBfoVkuJ5cbFvbefftr"
Tool call should use: currencyFrom: "DOT", currencyTo: "USDT", amount: "0.1", dex: "HydrationDex", receiver: "5D7jcv6aYbhbYGVY8k65oemM6FVNoyBfoVkuJ5cbFvbefftr"

When nominating to a pool it means joining to a nomination pool, please provide:
1. The amount of tokens to join the pool (e.g., 1)
2. The name of the chain (convert to real param)

When user wants to bond extra tokens from their wallet, I must call the bondExtraTool with:
1. type: "FreeBalance" (must be this exact string)
2. amount: [amount as string, e.g., "100"]
3. chain: [converted chain name as per chain conversion rules]

Example: For "bond 100 DOT on Polkadot", call bondExtraTool with:
{ "type": "FreeBalance", "amount": "100", "chain": "polkadot" }

When user requests to re-stake rewards, I must call the bondExtraTool with EXACTLY these parameters:
1. type: "Rewards" (must be this exact string)
2. chain: [converted chain name as per chain conversion rules]

Example: For "re-stake my rewards on Paseo", call bondExtraTool with:
{ "type": "Rewards", "chain": "paseo" }

IMPORTANT: Always use the EXACT parameter structure shown in examples above. The "type" field is a discriminator and must match exactly.

when user wants to unbond tokens from a pool, I must call the unbondTool with:
1. amount: [amount as string, e.g., "100"]
2. chain: [converted chain name as per chain conversion rules]

Example: For "unbond 100 DOT on Polkadot", call unbondTool with:
{ "amount": "100", "chain": "polkadot" }

when user wants to claim rewards from a pool, I must call the claimRewardsTools with:
1. chain: [converted chain name as per chain conversion rules]

Example: For "claim rewards from pool on paseo", call claimRewardsTool with:
{ "chain": "paseo" }


--- TOOL-SPECIFIC RULES ---

1. To 'unbond' tokens (start the unbonding process):
- Use the 'unbond' tool.
- Requires 'amount' (string) and 'chain' (string).
- Example: User says "unbond 10 DOT on Polkadot" -> Call 'unbond' with { amount: "10", chain: "polkadot" }

2. To 'withdraw unbonded' tokens (after the unbonding period):
- Use the 'withdrawUnbondedTool'.
- Requires 'slashingSpans' (string) and 'chain' (string).
- CRITICAL: If the user says "amount", use that value for 'slashingSpans'.
- Example: User says "withdraw unbonded with 1 amount on Paseo" -> Call 'withdrawUnbondedTool' with { slashingSpans: "1", chain: "paseo" }

--- END OF TOOL-SPECIFIC RULES ---

When checking proxies, you can specify the chain (convert to real param) or not specify a chain (the first chain will be used by default)

Please provide instructions, and I will assist you!`;
Expand All @@ -133,6 +197,12 @@ export function setupHandlers(
'- Checking balance (e.g., "check balance on west/polkadot/kusama")\n' +
'- Checking proxies (e.g., "check proxies on westend" or "check proxies")\n' +
'- Transfer tokens through XCM (e.g., "transfer 1 WND to 5CSox4ZSN4SGLKUG9NYPtfVK9sByXLtxP4hmoF4UgkM4jgDJ from west to west_asset_hub ")\n' +
'- Bonding to a pool (e.g., "bond 100 DOT on Polkadot")\n' +
'- Re-staking rewards (e.g., "re-stake my rewards on Paseo")\n' +
'- Unbonding tokens from a pool (e.g., "unbond 100 DOT on Polkadot")\n' +
'- Claiming rewards from a pool (e.g., "claim rewards from pool on paseo")\n' +
'- Withdraw unbonded from a pool (e.g, "withdraw unbonded with 1 amount from pool on paseo")\n' +
'- Swapping tokens (e.g., "swap 1 DOT to USDT on Hydra")\n' +
"Try asking something!",
);
});
Expand Down
9 changes: 7 additions & 2 deletions packages/common/src/chains/chains.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {
hydra,
paseo,
polkadot,
polkadot_asset_hub,
west,
west_asset_hub
} from "@polkadot-api/descriptors"

import {
paseoChain,
polkadotAssetHubChain,
polkadotChain,
westendAssetHubChain,
Expand All @@ -15,6 +17,7 @@ import {
type DescriptorsRelayType = {
polkadot: typeof polkadot
west: typeof west
paseo: typeof paseo
}

type DescriptorsAssetHubType = {
Expand All @@ -28,7 +31,8 @@ type DescriptorsParaType = {

const DESCRIPTORS_RELAY: DescriptorsRelayType = {
polkadot,
west
west,
paseo
}

const DESCRIPTORS_ASSET_HUB: DescriptorsAssetHubType = {
Expand Down Expand Up @@ -106,7 +110,8 @@ const SUPPORTED_CHAINS: Chain[] = [
polkadotChain,
polkadotAssetHubChain,
westendChain,
westendAssetHubChain
westendAssetHubChain,
paseoChain
]

export const getAllSupportedChains = (): Chain[] => {
Expand Down
14 changes: 14 additions & 0 deletions packages/common/src/chains/supported-chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,17 @@ export const hydraChain = createChain({
decimals: 12,
symbol: "HDX"
})

export const paseoChain = createChain({
id: "paseo",
name: "Paseo",
specName: "paseo-testnet",
wsUrls: ["wss://paseo.dotters.network"],
relay: "paseo",
type: "relay",
chainId: null,
blockExplorerUrl: "https://paseo.subscan.io",
prefix: 0,
decimals: 10,
symbol: "PAS"
})
4 changes: 3 additions & 1 deletion packages/common/src/clients/chainSpec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { chainSpec as paseoSpec } from "polkadot-api/chains/paseo"
import { chainSpec as polkadotSpec } from "polkadot-api/chains/polkadot"
import { chainSpec as polkadotAssetHubSpec } from "polkadot-api/chains/polkadot_asset_hub"
import { chainSpec as westSpec } from "polkadot-api/chains/westend2"
Expand Down Expand Up @@ -72,6 +73,7 @@ export function specRegistry(): Partial<Record<ChainId, string>> {
polkadot: polkadotSpec,
west: westSpec,
polkadot_asset_hub: polkadotAssetHubSpec,
west_asset_hub: westAssetHubSpec
west_asset_hub: westAssetHubSpec,
paseo: paseoSpec
}
}
6 changes: 4 additions & 2 deletions packages/core/src/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type {
Api,
ChainIdRelay,
ChainOperationResult,
KnownChainId,
SmoldotClient
Expand Down Expand Up @@ -57,7 +58,7 @@ export class PolkadotApi implements IPolkadotApi {
* @param chainId - The ID of the chain
* @returns The API instance for the specified chain
*/
getApi(chainId: KnownChainId): Api<KnownChainId> {
getApi(chainId: KnownChainId): Api<KnownChainId | ChainIdRelay> {
if (!this.initialized) {
throw new Error("APIs not initialized. Call initializeApi() first.")
}
Expand Down Expand Up @@ -102,7 +103,8 @@ export class PolkadotApi implements IPolkadotApi {
west: "",
polkadot_asset_hub: "",
west_asset_hub: "",
hydra: ""
hydra: "",
paseo: ""
}

for (const chain of supportedChains) {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
export * from "./api"
export * from "./defi/swap"
export * from "./pallets/assets"
export * from "./pallets/nomination-pools"
export * from "./pallets/xcm"
export * from "./types"
export * from "./utils"
23 changes: 23 additions & 0 deletions packages/core/src/pallets/nomination-pools/bondExtra.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Api, ChainIdRelay } from "@polkadot-agent-kit/common"

import type { Tx } from "../../types"

/**
* Creates a bond extra transaction call
* @param api - The API instance to use for the transaction
* @param extra - The type of extra bonding ("FreeBalance" or "Rewards")
* @returns The bond extra transaction call
*/
export const bondExtraTx = (
api: Api<ChainIdRelay>,
type: "FreeBalance" | "Rewards",
amount?: bigint
): Tx => {
if (type === "FreeBalance") {
return api.tx.NominationPools.bond_extra({
extra: { type: "FreeBalance", value: amount ?? BigInt(0) }
})
} else {
return api.tx.NominationPools.bond_extra({ extra: { type: "Rewards", value: undefined } })
}
}
12 changes: 12 additions & 0 deletions packages/core/src/pallets/nomination-pools/claimRewards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Api, ChainIdRelay } from "@polkadot-agent-kit/common"

import type { Tx } from "../../types"

/**
* Creates a claim rewards transaction call
* @param api - The API instance to use for the transaction
* @returns The claim rewards transaction call
*/
export const claimRewardsTx = (api: Api<ChainIdRelay>): Tx => {
return api.tx.NominationPools.claim_payout()
}
51 changes: 51 additions & 0 deletions packages/core/src/pallets/nomination-pools/getPoolInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { Api, ChainIdRelay } from "@polkadot-agent-kit/common"

/**
* Interface for pool information
*/
export interface PoolInfo {
id: number
state: string
points: bigint
memberCounter: number
roles: {
depositor: string
root: string | undefined
nominator: string | undefined
bouncer: string | undefined
}
}

/**
* Get information about a nomination pool
* @param api - The API instance to use for the query
* @param poolId - The ID of the pool to query
* @returns Promise that resolves to the pool information or null if not found
*/
export const getPoolInfo = async (
api: Api<ChainIdRelay>,
poolId: number
): Promise<PoolInfo | null> => {
try {
const poolInfo = await api.query.NominationPools.BondedPools.getValue(poolId)

if (!poolInfo) {
return null
}

return {
id: poolId,
state: poolInfo.state.type,
points: poolInfo.points,
memberCounter: poolInfo.member_counter,
roles: {
depositor: poolInfo.roles.depositor,
root: poolInfo.roles.root,
nominator: poolInfo.roles.nominator,
bouncer: poolInfo.roles.bouncer
}
}
} catch (error) {
throw new Error(`Error fetching pool info for pool ${poolId}: ${String(error)}`)
}
}
46 changes: 46 additions & 0 deletions packages/core/src/pallets/nomination-pools/getPoolMembers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Api, ChainIdRelay } from "@polkadot-agent-kit/common"

/**
* Interface for pool member information
*/
export interface PoolMember {
account: string
poolId: number
points: bigint
lastRecordedRewardCounter: bigint
unbondingEras: Array<{ era: number; value: bigint }>
}

/**
* Get members of a nomination pool
* @param api - The API instance to use for the query
* @param poolId - The ID of the pool to query members for
* @returns Promise that resolves to an array of pool members
*/
export const getPoolMembers = async (
api: Api<ChainIdRelay>,
poolId: number
): Promise<PoolMember[]> => {
try {
const poolMemberEntries = await api.query.NominationPools.PoolMembers.getEntries()

return poolMemberEntries
.filter(({ value }) => value && value.pool_id === poolId)
.map(({ keyArgs, value }) => {
const account = keyArgs[0] as string

return {
account,
poolId: value.pool_id,
points: value.points,
lastRecordedRewardCounter: value.last_recorded_reward_counter,
unbondingEras: value.unbonding_eras.map(([era, value]) => ({
era,
value
}))
}
})
} catch (error) {
throw new Error(`Error fetching pool members for pool ${poolId}: ${String(error)}`)
}
}
7 changes: 7 additions & 0 deletions packages/core/src/pallets/nomination-pools/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from "./bondExtra"
export * from "./claimRewards"
export * from "./getPoolInfo"
export * from "./getPoolMembers"
export * from "./joinPool"
export * from "./unbond"
export * from "./withdrawUnbonded"
Loading