### Run Development Server Source: https://github.com/galacticcouncil/sdk/blob/master/CONTRIBUTING.md Navigate to the examples directory and run the web dev server using this command. This is useful for testing SDK playground examples. ```sh npm run dev ``` -------------------------------- ### Install and Build Packages Source: https://github.com/galacticcouncil/sdk/blob/master/CLAUDE.md Commands for installing dependencies, building all packages, watching for changes, cleaning build artifacts, and linking packages locally. ```sh npm ci # Install (use --ignore-scripts in CI) npm run build # Build all packages (turbo) npm run build:watch # Watch mode with hot reloading npm run clean # Remove all build/ dirs npm run link # npm link all packages for local dev npm run test # Run all tests (sequential, --concurrency=1) ``` -------------------------------- ### Install Galactic SDK Next Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/README.md Install the SDK using npm. This command adds the necessary package to your project dependencies. ```bash npm install @galacticcouncil/sdk-next ``` -------------------------------- ### Install Galactic SDK Packages Source: https://github.com/galacticcouncil/sdk/blob/master/README.md Install the necessary packages for trading or cross-chain transfers using npm. ```bash # Trading SDK npm i @galacticcouncil/sdk-next # Cross-chain transfers npm i @galacticcouncil/xc ``` -------------------------------- ### Initialize Changeset Source: https://github.com/galacticcouncil/sdk/blob/master/CONTRIBUTING.md Run this command to start the changeset process for versioning and summarizing changes. It's recommended to run this for each package separately. ```sh npm run changeset ``` -------------------------------- ### Get Supported Assets Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/README.md Retrieves a list of all supported assets with their metadata from the registry. Assumes SDK client initialization. ```typescript const { client } = sdk; const assets = await client.asset.getSupported(); console.log(assets); ``` -------------------------------- ### Create XC Context Source: https://github.com/galacticcouncil/sdk/blob/master/packages/xc/README.md Use `createXcContext` to initialize all necessary components for cross-chain transfers. This factory handles setup for config, wallet, and bridge integrations. ```typescript import { createXcContext } from '@galacticcouncil/xc'; const ctx = await createXcContext(); const { config, wallet } = ctx; ``` -------------------------------- ### TradeRouter Initial Load Flow Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/docs/SOR_SPEC.md Illustrates the sequence of calls starting from TradeRouter.withCtx() to retrieve pool data, including conditional logic for ready states and asynchronous fetching. ```typescript TradeRouter.withCtx() -> Router.getPools() -> ctx.getPools() -> PoolContextProvider.getPools() if (isReady): return pools.values() // O(n) Map iteration else: Promise.all(activeClients.map(c => c.getPools())) -> PoolClient.getPools() -> memoize1(mem) -> loadPools() // TLRU 6s TTL -> filter(hasValidAssets) isReady = true return flat pools ``` -------------------------------- ### Commit Message Conventions Source: https://github.com/galacticcouncil/sdk/blob/master/CLAUDE.md Examples of commit messages following the 'scope: description' format, used for tracking changes across packages. ```sh sdk: fix native mint cfg xc: support solana native mint & claim desc: update to latest metadata ``` -------------------------------- ### Initialize XC SDK Wallet Source: https://github.com/galacticcouncil/sdk/blob/master/packages/xc-sdk/README.md Set up the ConfigService with asset, chain, and route mappings. Then, initialize the Wallet with the config service and transfer validations. ```typescript // Import import { assetsMap, chainsMap, routesMap, dex, validations, } from '@galacticcouncil/xc-cfg'; import { ConfigService, EvmParachain } from '@galacticcouncil/xc-core'; import { Wallet, Call } from '@galacticcouncil/xc-sdk'; // Initialize config service const configService = new ConfigService({ assets: assetsMap, chains: chainsMap, routes: routesMap, }); // Initialize wallet const wallet = new Wallet({ configService: configService, transferValidations: validations, }); ``` -------------------------------- ### Initialize SDK Context Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/README.md Set up the SDK context by creating a Polkadot client and passing it to `createSdkContext`. Remember to clean up resources using `sdk.destroy()` when done. ```typescript import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const client = createClient(provider); const sdk = await createSdkContext(client); // Don't forget to cleanup resources when DONE sdk.destroy(); ``` -------------------------------- ### Initialize Solo Trading SDK (sdk-next) Source: https://github.com/galacticcouncil/sdk/blob/master/README.md Initialize the sdk-next context for solo trading. Requires a Polkadot API client connected to a Hydration RPC endpoint. ```typescript import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const client = createClient(provider); const sdk = await createSdkContext(client); ``` -------------------------------- ### Get Staking Pot Balance Source: https://context7.com/galacticcouncil/sdk/llms.txt Retrieves the current balance of the staking reward pot, indicating the total transferable amount available for rewards. ```typescript const { api: sdkApi } = sdk; // Pot (reward pool) balance const pot = await sdkApi.staking.getPotBalance(); console.log('Pot transferable:', pot.transferable); ``` -------------------------------- ### Get Spot Price Between Assets Source: https://context7.com/galacticcouncil/sdk/llms.txt Queries the current spot price between two specified assets. Returns null if no direct or indirect route is available. ```typescript // --- Spot price between two assets --- const spot = await sdkApi.router.getSpotPrice(5, 0); if (spot) { console.log('Spot price (18 decimals):', spot.amount, spot.decimals); } ``` -------------------------------- ### Initialize Combined SDK (sdk-next + xc) Source: https://github.com/galacticcouncil/sdk/blob/master/README.md Initialize both sdk-next for trading and xc for cross-chain transfers, sharing the pool context for efficiency. ```typescript import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createXcContext } from '@galacticcouncil/xc'; import { createClient } from 'polkadot-api'; const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const client = createClient(provider); const sdk = await createSdkContext(client); // Shared pool context const xc = await createXcContext(sdk.ctx.pool); ``` -------------------------------- ### Initialize SDK Context with createSdkContext Source: https://context7.com/galacticcouncil/sdk/llms.txt Initializes all SDK-Next components from a PolkadotClient. Remember to call `sdk.destroy()` for cleanup. ```typescript import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; // Connect via WebSocket const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const client = createClient(provider); // Bootstrap all SDK components in one call const sdk = await createSdkContext(client); // sdk.api.router — TradeRouter // sdk.api.scheduler — TradeScheduler (DCA / TWAP) // sdk.api.aave — AaveUtils // sdk.api.staking — StakingApi // sdk.api.farm — LiquidityMiningApi // sdk.client.asset — AssetClient // sdk.client.balance — BalanceClient // sdk.client.evm — EvmClient // sdk.ctx.pool — PoolContextProvider // sdk.tx — TxBuilderFactory // Cleanup when done sdk.destroy(); ``` -------------------------------- ### Get Best Sell Trade Route Source: https://context7.com/galacticcouncil/sdk/llms.txt Finds the optimal route to sell a specified amount of one asset for another. Supports both bigint and string amounts. ```typescript const { api: sdkApi } = sdk; // --- Sell: swap 1 DOT (assetId=5) for HDX (assetId=0) --- const sellTrade = await sdkApi.router.getBestSell(5, 0, '1'); console.log(sellTrade.toHuman()); // { // type: 'Sell', // amountIn: '1', // DOT (human) // amountOut: '1234.56', // HDX (human) // spotPrice: '...', // tradeFeePct: 0.3, // priceImpactPct: -0.12, // swaps: [...] // } ``` -------------------------------- ### Release Packages Source: https://github.com/galacticcouncil/sdk/blob/master/CONTRIBUTING.md This command builds the project, publishes the NPM packages, and pushes the necessary references to the origin. It should be run after version bumping. ```sh npm run release ``` -------------------------------- ### Build Packages Source: https://github.com/galacticcouncil/sdk/blob/master/CONTRIBUTING.md Commands to build the project packages. Use 'build' for distribution with types, or 'build:watch' for JavaScript-only with hot reloading. ```sh npm run build ``` ```sh npm run build:watch ``` -------------------------------- ### Get Best Buy Trade Route Source: https://context7.com/galacticcouncil/sdk/llms.txt Calculates the optimal route to acquire a specific amount of an asset by selling another. Amounts can be specified as native units or human-readable strings. ```typescript // --- Buy: acquire exactly 500 HDX, find required DOT input --- const buyTrade = await sdkApi.router.getBestBuy(5, 0, '500'); console.log(buyTrade.toHuman()); ``` -------------------------------- ### Enumerate Chains and Assets with XC Config Source: https://context7.com/galacticcouncil/sdk/llms.txt Demonstrates how to retrieve chain and asset information using the configuration object obtained from the cross-chain context. Shows fetching details for specific chains and assets. ```typescript const { config } = xc; // Assuming xc is an initialized cross-chain context // Enumerate available chains and assets const hydration = config.getChain('hydration'); const ethereum = config.getChain('ethereum'); const ethAsset = config.getAsset('eth'); console.log('Hydration parachain ID:', hydration.parachainId); ``` -------------------------------- ### createSdkContext — SDK-Next context factory Source: https://context7.com/galacticcouncil/sdk/llms.txt Initializes all SDK-Next components, including pool context, trade router, and transaction builder, from a single PolkadotClient. Remember to call `sdk.destroy()` to clean up subscriptions. ```APIDOC ## `createSdkContext` — SDK-Next context factory Initializes all SDK-Next components (pool context, trade router, scheduler, balance client, asset client, Aave utilities, staking, liquidity mining, and transaction builder) from a single `PolkadotClient`. Returns an `SdkCtx` object grouping all subsystems. Always call `sdk.destroy()` to clean up subscriptions. ```typescript import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; // Connect via WebSocket const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const client = createClient(provider); // Bootstrap all SDK components in one call const sdk = await createSdkContext(client); // sdk.api.router — TradeRouter // sdk.api.scheduler — TradeScheduler (DCA / TWAP) // sdk.api.aave — AaveUtils // sdk.api.staking — StakingApi // sdk.api.farm — LiquidityMiningApi // sdk.client.asset — AssetClient // sdk.client.balance — BalanceClient // sdk.client.evm — EvmClient // sdk.ctx.pool — PoolContextProvider // sdk.tx — TxBuilderFactory // Cleanup when done sdk.destroy(); ``` ``` -------------------------------- ### Perform and Monitor Cross-Chain Transfer Source: https://github.com/galacticcouncil/sdk/blob/master/packages/xc-sdk/README.md Define transfer parameters, subscribe to balance updates, get transfer data, validate, estimate fees, and build the call. Unsubscribe from balance updates when done. ```typescript // Define transfer const srcChain = configService.getChain('ethereum'); const destChain = configService.getChain('hydration'); const asset = configService.getAsset('eth'); // Define source & dest accounts const srcAddr = 'INSERT_ADDRESS'; const destAddr = 'INSERT_ADDRESS'; // Subscribe source chain token balance const balanceObserver = (balances: AssetAmount[]) => console.log(balances); const balanceSubscription = await wallet.subscribeBalance( srcAddr, srcChain, balanceObserver ); // Get transfer data const transfer = await wallet.transfer( asset, srcAddr, srcChain, destAddr, destChain ); // Validate transfer const status = await transfer.validate(); // Estimate fee & construct calldata with transfer amount (1 ETH) const fee: AssetAmount = await transfer.estimateFee('1'); const feeInfo = [ 'Estimated fee:', fee.toDecimal(fee.decimals), fee.originSymbol, ].join(' '); const call: Call = await transfer.buildCall('1'); // Dump transfer info console.log(transfer); console.log(status); console.log(feeInfo); console.log(call); // Unsubscribe source chain balance balanceSubscription.unsubscribe(); ``` -------------------------------- ### Create WebSocket and Light Client Providers with api.getWs/api.getSm Source: https://context7.com/galacticcouncil/sdk/llms.txt Use `getWs` for WebSocket providers (single or multiple endpoints) or `getSm` for a trustless light client provider using smoldot. ```typescript import { api } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; // WebSocket — single or multiple endpoints for failover const wsProvider = api.getWs( 'wss://rpc.hydration.cloud,wss://hydradx-rpc.dwellir.com', { onStatusChanged: (s) => { if (s.type === 1) console.log('[WS] connected to', s.uri); if (s.type === 3) console.error('[WS] error', s); }, } ); const client = createClient(wsProvider); // Light client (smoldot) — trustless, no external RPC needed const { chainSpec } = await import('@polkadot-api/chains/hydration'); const smProvider = await api.getSm(chainSpec); const smClient = createClient(smProvider); ``` -------------------------------- ### Get HDX Staking Account State Source: https://context7.com/galacticcouncil/sdk/llms.txt Retrieves the current staking status for a given account, including total stake, position ID, and detailed stake position information such as governance votes and action points. ```typescript const { api: sdkApi } = sdk; const ACCOUNT = '7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'; // Current staking state for an account const stake = await sdkApi.staking.getStake(ACCOUNT); console.log('Total stake pool:', stake.totalStake); console.log('Position ID:', stake.positionId); console.log('Stake position:', stake.stakePosition); // stakePosition.votes — governance votes affecting action points // stakePosition.actionPoints — current accumulated action points ``` -------------------------------- ### Initialize Solo Cross-Chain SDK (xc) Source: https://github.com/galacticcouncil/sdk/blob/master/README.md Initialize the xc context for solo cross-chain transfers. This can be done independently. ```typescript import { createXcContext } from '@galacticcouncil/xc'; const xc = await createXcContext(); ``` -------------------------------- ### Determine Max Withdrawable Amount from Aave Source: https://context7.com/galacticcouncil/sdk/llms.txt Calculates the maximum amount of a specific asset that can be safely withdrawn from an Aave position without negatively impacting the health factor. Also provides functionality to get max withdrawable amounts for all reserves. ```typescript const { api: sdkApi } = sdk; const USER = '0xYOUR_EVM_ADDRESS_OR_SS58'; // Max safe withdrawable amount for a reserve const maxWithdraw = await sdkApi.aave.getMaxWithdraw(USER, 10); // assetId=10 USDT console.log('Max USDT withdraw:', maxWithdraw.amount, 'decimals:', maxWithdraw.decimals); // Max withdrawable for all reserves at once const allMaxWithdraws = await sdkApi.aave.getMaxWithdrawAll(USER); // { [reserveId]: { amount: bigint, decimals: number } } ``` -------------------------------- ### Data Flow for Route Suggestion Source: https://github.com/galacticcouncil/sdk/blob/master/crates/route-suggester/SPEC.md Details the step-by-step process from fetching pools to finding all acyclic paths using BFS, culminating in the final route structure. ```rust 1. P::get_all_pools(&state) → Vec │ (runtime destructures SimulatorSet::State, │ extracts tradeable asset lists from each AMM snapshot) │ 2. strategy::suggest_routes(A, B, pools) │ ├── Partition: trusted[], isolated[] ├── Check: A in trusted? B in trusted? ├── Select pool subset │ ├── graph::build_graph(selected_pools) → AdjacencyMap │ └── bfs::find_all_paths(adjacency, A, B) │ ├── Queue ← [PathNode { asset: A }] │ └── While queue not empty: │ path = queue.pop_front() ├── path.last == B? → results.push(path_to_route(path)); continue ├── trade_count > 9? → continue └── For each edge from path.last.asset: ├── is_valid_extension? (no asset revisit, no pool reuse) └── Yes → queue.push(path + edge) 3. Return: Vec> (BoundedVec, ConstU32<9>> — directly compatible with pallet-route-executor and AMMInterface::sell/buy) ``` -------------------------------- ### Get Aave Lending Position Summary Source: https://context7.com/galacticcouncil/sdk/llms.txt Retrieves a comprehensive summary of a user's Aave v3 lending position, including health factor, collateral, debt, and reserve details. Requires an EVM address or SS58 encoded address. ```typescript const { api: sdkApi } = sdk; const USER = '0xYOUR_EVM_ADDRESS_OR_SS58'; // Full Aave market summary for a user const summary = await sdkApi.aave.getSummary(USER); console.log('HF:', summary.healthFactor); console.log('Total collateral:', summary.totalCollateral); console.log('Total debt:', summary.totalDebt); summary.reserves.forEach((r) => { console.log(`Reserve ${r.reserveId}: aBalance=${r.aTokenBalance}, collateral=${r.isCollateral}`); }); ``` -------------------------------- ### Initialize Substrate Signer Source: https://github.com/galacticcouncil/sdk/blob/master/packages/xc-sdk/README.md Instantiate a SubstrateSigner with chain and polkadotSigner. Use signAndSend to submit transactions with callbacks for transaction status. ```typescript import { SubstrateSigner } from '@galacticcouncil/xc-sdk'; const signer = new SubstrateSigner(chain, polkadotSigner); signer.signAndSend(call, { onTransactionSend: (hash) => console.log('TxHash:', hash), onFinalized: (event) => console.log('Finalized:', event), onError: (error) => console.error(error), }); ``` -------------------------------- ### Build and Manage Cross-chain Transfers with Wallet Source: https://context7.com/galacticcouncil/sdk/llms.txt Use the Wallet class to initiate cross-chain transfers. Subscribe to balances, build transfer objects, validate conditions, estimate fees, and construct the final transaction call. Ensure necessary configurations and assets are loaded. ```typescript import { assetsMap, chainsMap, routesMap, validations, HydrationConfigService, } from '@galacticcouncil/xc-cfg'; import { Wallet } from '@galacticcouncil/xc-sdk'; import { AssetAmount } from '@galacticcouncil/xc-core'; const config = new HydrationConfigService({ assets: assetsMap, chains: chainsMap, routes: routesMap }); const wallet = new Wallet({ configService: config, transferValidations: validations }); const srcChain = config.getChain('ethereum'); const dstChain = config.getChain('hydration'); const asset = config.getAsset('eth'); const SRC_ADDR = '0xYOUR_ETH_ADDRESS'; const DST_ADDR = '7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'; // Subscribe source-chain balances (real-time) const sub = await wallet.subscribeBalance(SRC_ADDR, srcChain, (balances: AssetAmount[]) => { balances.forEach((b) => console.log(b.originSymbol, b.toDecimal(b.decimals))); }); // Build transfer data const transfer = await wallet.transfer(asset, SRC_ADDR, srcChain, DST_ADDR, dstChain); // source contains: balance, fee, feeBalance, destinationFee, max, min console.log('Sending max:', transfer.source.max.toDecimal(transfer.source.max.decimals)); // Validate: checks sufficient balance, min amount, etc. const report = await transfer.validate(); report.forEach((r) => console.log(r.type, r.isOk)); // Estimate fee for sending 0.1 ETH const fee = await transfer.estimateFee('0.1'); console.log('Fee:', fee.toDecimal(fee.decimals), fee.originSymbol); // Build the call (returns a Call object with dryRun support) const call = await transfer.buildCall('0.1'); console.log('Dry run result:', await call.dryRun()); sub.unsubscribe(); ``` -------------------------------- ### Link Local Modules Source: https://github.com/galacticcouncil/sdk/blob/master/CONTRIBUTING.md Run this command to link local modules for development. ```sh npm run link ``` -------------------------------- ### Calculate Omnipool Farm Rewards with LiquidityMiningApi Source: https://context7.com/galacticcouncil/sdk/llms.txt Use the LiquidityMiningApi to fetch oracle prices, list active Omnipool farms, and estimate claimable rewards for a given account and block number. Ensure the SDK is initialized. ```typescript const { api: sdkApi } = sdk; // Oracle price between reward currency and incentivized asset const oraclePrice = await sdkApi.farm.getOraclePrice( 0, // rewardCurrency = HDX (assetId=0) 5 // incentivizedAsset = DOT (assetId=5) ); console.log('Oracle price (fixed-point):', oraclePrice); // Get all active Omnipool farms const farms = await sdkApi.farm.getOmnipoolFarms(); farms.forEach((farm) => { console.log(`Farm id=${farm.globalFarmId} reward=${farm.rewardCurrency}`); }); // Compute estimated rewards for a yield farm entry const ACCOUNT = '7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'; const CURRENT_BLOCK = 5000000n; const rewardEstimates = await sdkApi.farm.getOmnipoolFarmRewards( ACCOUNT, CURRENT_BLOCK ); rewardEstimates.forEach((r) => { console.log(`Claimable ${r.rewardSymbol}: ${r.rewardAmount}`); }); ``` -------------------------------- ### TxBuilderFactory - Transaction construction Source: https://context7.com/galacticcouncil/sdk/llms.txt Builds and signs Substrate extrinsics for sell, sell-all, and buy trades. Automatically selects direct Omnipool vs. Router path, applies slippage, and wraps Aave debt positions with extra gas. ```APIDOC ## `TxBuilderFactory` — Transaction construction Builds and signs Substrate extrinsics for sell, sell-all, and buy trades. Automatically selects direct Omnipool vs. Router path, applies slippage, and wraps Aave debt positions with extra gas. ```typescript const { api: sdkApi, tx } = sdk; const BENEFICIARY = '7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'; // Sell 1 DOT → HDX with 5% slippage const trade = await sdkApi.router.getBestSell(5, 0, '1'); const tradeTx = await tx .trade(trade) .withBeneficiary(BENEFICIARY) .withSlippage(5) // default is 1% .build(); const encodedCall = await tradeTx.get().getEncodedData(); console.log('Encoded call:', encodedCall.asHex()); // Build a DCA order transaction const order = await sdkApi.scheduler.getDcaOrder(5, 0, '100', 7 * 24 * 60 * 60 * 1000); const orderTx = await tx .order(order) .withBeneficiary(BENEFICIARY) .build(); ``` ``` -------------------------------- ### createXcContext — Cross-chain context factory Source: https://context7.com/galacticcouncil/sdk/llms.txt Wires together `xc-cfg` route configurations, `xc-sdk` Wallet, Wormhole bridge clients, and DEX integrations (Hydration + AssetHub) in one call. Optionally accepts a shared `PoolContextProvider` from `sdk-next` to reuse live pool data. ```APIDOC ## `createXcContext` — Cross-chain context factory Wires together `xc-cfg` route configurations, `xc-sdk` Wallet, Wormhole bridge clients, and DEX integrations (Hydration + AssetHub) in one call. Optionally accepts a shared `PoolContextProvider` from `sdk-next` to reuse live pool data. ```typescript import { createXcContext } from '@galacticcouncil/xc'; import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; // Standalone XC context const xc = await createXcContext(); const { config, wallet, wormhole } = xc; // Combo: share pool context from sdk-next (avoids double RPC subscriptions) const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const sdk = await createSdkContext(createClient(provider)); const xcShared = await createXcContext({ poolCtx: sdk.ctx.pool }); // Enumerate available chains and assets const hydration = config.getChain('hydration'); const ethereum = config.getChain('ethereum'); const ethAsset = config.getAsset('eth'); console.log('Hydration parachain ID:', hydration.parachainId); ``` ``` -------------------------------- ### Create Standalone Cross-Chain Context Source: https://context7.com/galacticcouncil/sdk/llms.txt Initializes a cross-chain context using `createXcContext` without sharing any external context. This sets up wallet, configuration, and bridge clients independently. ```typescript import { createXcContext } from '@galacticcouncil/xc'; // Standalone XC context const xc = await createXcContext(); const { config, wallet, wormhole } = xc; ``` -------------------------------- ### Add route-suggester Dependency to Cargo.toml Source: https://github.com/galacticcouncil/sdk/blob/master/crates/route-suggester/SPEC.md Integrate the route-suggester crate into your project by adding it to the `[dependencies]` section of your `Cargo.toml` file. Ensure to configure features, especially `std`, as needed. ```toml [dependencies] route-suggester = { git = "https://github.com/galacticcouncil/sdk", subdirectory = "crates/route-suggester", default-features = false } [features] std = ["route-suggester/std"] ``` -------------------------------- ### AssetClient Methods Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/README.md Provides methods for retrieving asset information from the registry. ```APIDOC ## AssetClient ### getSupported Returns assets with metadata from the registry. Optionally include invalid assets or external assets. #### Method `getSupported(includeInvalid?: boolean, external?: ExternalAsset[]): Promise` ``` -------------------------------- ### ConfigService and ConfigBuilder — Route configuration Source: https://context7.com/galacticcouncil/sdk/llms.txt `ConfigService` holds the full asset/chain/route registry. `ConfigBuilder` provides a fluent API to discover valid source and destination chains for a given asset and direction. ```APIDOC ## `ConfigService` / `ConfigBuilder` — Route configuration `ConfigService` holds the full asset/chain/route registry. `ConfigBuilder` provides a fluent API to discover which source chains and destination chains are valid for a given asset+direction combination. ```typescript import { assetsMap, chainsMap, routesMap, HydrationConfigService, } from '@galacticcouncil/xc-cfg'; import { ConfigBuilder } from '@galacticcouncil/xc-core'; const config = new HydrationConfigService({ assets: assetsMap, chains: chainsMap, routes: routesMap }); const dotAsset = config.getAsset('dot'); // All chains that can send DOT somewhere const { sourceChains } = ConfigBuilder(config).assets().asset(dotAsset); console.log('DOT source chains:', sourceChains.map((c) => c.key)); // Destinations reachable from Polkadot const polkadotChain = config.getChain('polkadot'); const { destinationChains } = ConfigBuilder(config) .assets().asset(dotAsset) .source(polkadotChain); console.log('From Polkadot, DOT can go to:', destinationChains.map((c) => c.key)); // Check supported protocols on a chain import { tags } from '@galacticcouncil/xc-cfg'; const ethChain = config.getChain('ethereum'); // ethChain supports Wormhole (MRL) and Snowbridge routes ``` ``` -------------------------------- ### Bump Version and Create Commit Source: https://github.com/galacticcouncil/sdk/blob/master/CONTRIBUTING.md Execute this command after running 'changeset' to bump package versions, update the lockfile, and generate a commit message for the changes. ```sh npm run changeset:version ``` -------------------------------- ### Subscribe to Account Balance Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/README.md Subscribes to real-time updates of an account's balance. Requires the SDK client to be initialized. ```typescript const { client } = sdk; const account = "7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1" const subscription = client.balance .watch(account) .subscribe((balances) => { console.log(balances); }); ``` -------------------------------- ### BalanceClient - Real-time account balance subscriptions Source: https://context7.com/galacticcouncil/sdk/llms.txt Subscribes to native (HDX), token, and ERC-20 asset balances using papi's reactive storage watchers. Emits delta updates (only changed balances) after the initial full snapshot. Built on RxJS Observables. ```APIDOC ## `BalanceClient` — Real-time account balance subscriptions Subscribes to native (HDX), token, and ERC-20 asset balances using papi's reactive storage watchers. Emits delta updates (only changed balances) after the initial full snapshot. Built on RxJS Observables. ```typescript import { firstValueFrom } from 'rxjs'; const { client } = sdk; const ACCOUNT = '7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'; // Subscribe all balances (system + tokens + ERC-20) — emits deltas const subscription = client.balance.watchBalance(ACCOUNT).subscribe((balances) => { balances.forEach(({ id, balance }) => { console.log(`Asset ${id}: transferable=${balance.transferable}, total=${balance.total}`); }); }); // Subscribe only native HDX balance client.balance.watchSystemBalance(ACCOUNT).subscribe(({ id, balance }) => { console.log('HDX free:', balance.free, 'frozen:', balance.frozen); }); // Subscribe a specific token (e.g. USDT assetId=10) client.balance.watchTokenBalance(ACCOUNT, 10).subscribe(({ balance }) => { console.log('USDT transferable:', balance.transferable); }); // One-shot balance read const hdxBalance = await client.balance.getSystemBalance(ACCOUNT); console.log('HDX total:', hdxBalance.total); // Unsubscribe subscription.unsubscribe(); ``` ``` -------------------------------- ### Changesets for Versioning and Releasing Source: https://github.com/galacticcouncil/sdk/blob/master/CLAUDE.md Commands for managing package versions and releases using Changesets, including creating a changeset, applying version bumps, and publishing to npm. ```sh npm run changeset # Create changeset (specify version bump + summary) npm run changeset:version # Apply version bumps, update lockfile, create commit npm run release # Build + publish to npm + push tags ``` -------------------------------- ### api.getWs / api.getSm — Provider factories Source: https://context7.com/galacticcouncil/sdk/llms.txt `getWs` creates a WebSocket provider with legacy compatibility, accepting a URL or comma-separated list of endpoints. `getSm` creates a light-client provider for a given chain spec without relying on a centralized RPC. ```APIDOC ## `api.getWs` / `api.getSm` — Provider factories `getWs` creates a WebSocket provider (with legacy compatibility shim) accepting a single URL or comma-separated list of endpoints. `getSm` creates a light-client (smoldot) provider for a given chain spec without relying on a centralized RPC. ```typescript import { api } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; // WebSocket — single or multiple endpoints for failover const wsProvider = api.getWs( 'wss://rpc.hydration.cloud,wss://hydradx-rpc.dwellir.com', { onStatusChanged: (s) => { if (s.type === 1) console.log('[WS] connected to', s.uri); if (s.type === 3) console.error('[WS] error', s); }, } ); const client = createClient(wsProvider); // Light client (smoldot) — trustless, no external RPC needed const { chainSpec } = await import('@polkadot-api/chains/hydration'); const smProvider = await api.getSm(chainSpec); const smClient = createClient(smProvider); ``` ``` -------------------------------- ### Manage Stateful Pool Subscriptions with PoolContextProvider Source: https://context7.com/galacticcouncil/sdk/llms.txt PoolContextProvider maintains live subscriptions to on-chain pool states. It can be optionally extended with `withLbp()` or `withHsm()` and shared with other contexts like XC. ```typescript import { api, createSdkContext } from '@galacticcouncil/sdk-next'; import { createClient } from 'polkadot-api'; const provider = api.getWs('wss://hydradx-rpc.dwellir.com'); const client = createClient(provider); const sdk = await createSdkContext(client); // ctx.pool is already initialized with Aave + Omnipool + Stableswap + XYK // Optionally enable additional pools manually: // sdk.ctx.pool.withLbp().withHsm() const pools = await sdk.ctx.pool.getPools(); // pools: PoolBase[] — each has address, type (PoolType), tokens[], limits pools.forEach((p) => { console.log(p.type, p.address, p.tokens.map((t) => t.id)); }); // Share the pool context with XC to avoid redundant subscriptions import { createXcContext } from '@galacticcouncil/xc'; const xc = await createXcContext({ poolCtx: sdk.ctx.pool }); ``` -------------------------------- ### LiquidityMiningApi Source: https://context7.com/galacticcouncil/sdk/llms.txt Computes APR, claimable rewards, and farming position data for Omnipool yield farms using WASM math and on-chain oracle prices. ```APIDOC ## `LiquidityMiningApi` — Farm reward calculations Computes APR, claimable rewards, and farming position data for Omnipool yield farms using WASM math (`math-liquidity-mining`) and on-chain oracle prices. ### Methods #### `getOraclePrice(rewardCurrency: AssetId, incentivizedAsset: AssetId): Promise` Retrieves the oracle price between a reward currency and an incentivized asset. * **Parameters** * `rewardCurrency` (AssetId) - The asset ID of the reward currency. * `incentivizedAsset` (AssetId) - The asset ID of the incentivized asset. ### `getOmnipoolFarms(): Promise` Fetches all active Omnipool farms. * **Returns** * `Farm[]` - An array of active farm objects. ### `getOmnipoolFarmRewards(account: string, currentBlock: bigint): Promise` Computes estimated rewards for a yield farm entry for a given account and block number. * **Parameters** * `account` (string) - The account ID for which to estimate rewards. * `currentBlock` (bigint) - The current block number. * **Returns** * `RewardEstimate[]` - An array of estimated reward objects. ``` -------------------------------- ### List All Possible Sell Routes Source: https://context7.com/galacticcouncil/sdk/llms.txt Generates a list of all potential sell routes for a given asset pair and amount, useful for UI selection. ```typescript // --- All possible sell routes (for route selection UI) --- const allSells = await sdkApi.router.getSells(5, 0, '1'); allSells.forEach((t) => console.log(t.toHuman())); ``` -------------------------------- ### Liquidity Mining Fixed-Point Conversion Source: https://context7.com/galacticcouncil/sdk/llms.txt Convert a rational number (numerator, denominator) into a fixed-point representation using `fixed_from_rational` from `@galacticcouncil/math-liquidity-mining`. This is useful for on-chain calculations. ```typescript import { fixed_from_rational } from '@galacticcouncil/math-liquidity-mining'; const oracleFixed = fixed_from_rational('3', '10'); // 0.3 in fixed-point ``` -------------------------------- ### Real-time Updates with EventSource Source: https://github.com/galacticcouncil/sdk/blob/master/examples/xc-transfer/public/transfer/index.html This snippet sets up an EventSource to listen for 'change' events from the '/esbuild' endpoint. Upon receiving an event, it reloads the current location. ```javascript new EventSource('/esbuild').addEventListener('change', () => location.reload() ); ``` -------------------------------- ### Standalone Route Discovery Source: https://github.com/galacticcouncil/sdk/blob/master/crates/route-suggester/SPEC.md Use `get_routes` for standalone route discovery, such as in tests, RPC calls, or off-chain workers. Provide a vector of `PoolEdge` to define the available liquidity. ```rust use route_suggester::{get_routes, types::PoolEdge}; use hydradx_traits::router::PoolType; let pools = vec![ PoolEdge { pool_type: PoolType::Omnipool, assets: vec![0, 1, 2, 5, 10] }, PoolEdge { pool_type: PoolType::Stableswap(100), assets: vec![10, 11, 12] }, PoolEdge { pool_type: PoolType::XYK, assets: vec![20, 5] }, ]; let routes = get_routes(20, 12, pools); // Returns: [ // Route [XYK 20→5, Omnipool 5→10, Stableswap(100) 10→12], // ... other viable paths // ] ``` -------------------------------- ### BalanceClient Methods Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/README.md Provides methods to subscribe to various account balance types. These methods return an Observable that emits AssetAmount objects. ```APIDOC ## BalanceClient ### watchBalance Subscribe to an account's balance. #### Method `watchBalance(address: string): Observable` ### watchSystemBalance Subscribe to an account's native balance. #### Method `watchSystemBalance(address: string): Observable` ### watchTokenBalance Subscribe to a specific token's balance for an account. #### Method `watchTokenBalance(address: string, assetId: number): Observable` ### watchTokensBalance Subscribe to all token balances for an account. #### Method `watchTokensBalance(address: string): Observable` ### watchErc20Balance Subscribe to ERC20 asset balances for an account, with an option to filter. #### Method `watchErc20Balance(address: string, includeOnly?: number[]): Observable` ``` -------------------------------- ### Configure Routes with ConfigService and ConfigBuilder Source: https://context7.com/galacticcouncil/sdk/llms.txt Manage asset, chain, and route registries using `HydrationConfigService`. Use `ConfigBuilder` to fluently discover source and destination chains for assets and check supported protocols on specific chains. ```typescript import { assetsMap, chainsMap, routesMap, HydrationConfigService, } from '@galacticcouncil/xc-cfg'; import { ConfigBuilder } from '@galacticcouncil/xc-core'; const config = new HydrationConfigService({ assets: assetsMap, chains: chainsMap, routes: routesMap }); const dotAsset = config.getAsset('dot'); // All chains that can send DOT somewhere const { sourceChains } = ConfigBuilder(config).assets().asset(dotAsset); console.log('DOT source chains:', sourceChains.map((c) => c.key)); // Destinations reachable from Polkadot const polkadotChain = config.getChain('polkadot'); const { destinationChains } = ConfigBuilder(config) .assets().asset(dotAsset) .source(polkadotChain); console.log('From Polkadot, DOT can go to:', destinationChains.map((c) => c.key)); // Check supported protocols on a chain import { tags } from '@galacticcouncil/xc-cfg'; const ethChain = config.getChain('ethereum'); // ethChain supports Wormhole (MRL) and Snowbridge routes ``` -------------------------------- ### Wallet.transfer — Cross-chain transfer pipeline Source: https://context7.com/galacticcouncil/sdk/llms.txt The Wallet class is the primary entry point for cross-chain transfers. The `transfer()` method builds a `Transfer` object that contains source/destination balances, fees, min/max amounts, and methods to validate, estimate fees, and construct the final call data. ```APIDOC ## `Wallet.transfer` / `Transfer` — Cross-chain transfer pipeline The `Wallet` class is the primary entry point for cross-chain transfers. `transfer()` builds a `Transfer` object containing source/destination balances, fees, min/max amounts, and methods to validate, estimate fees, and construct the final call data. ```typescript import { assetsMap, chainsMap, routesMap, validations, HydrationConfigService, } from '@galacticcouncil/xc-cfg'; import { Wallet } from '@galacticcouncil/xc-sdk'; import { AssetAmount } from '@galacticcouncil/xc-core'; const config = new HydrationConfigService({ assets: assetsMap, chains: chainsMap, routes: routesMap }); const wallet = new Wallet({ configService: config, transferValidations: validations }); const srcChain = config.getChain('ethereum'); const dstChain = config.getChain('hydration'); const asset = config.getAsset('eth'); const SRC_ADDR = '0xYOUR_ETH_ADDRESS'; const DST_ADDR = '7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'; // Subscribe source-chain balances (real-time) const sub = await wallet.subscribeBalance(SRC_ADDR, srcChain, (balances: AssetAmount[]) => { balances.forEach((b) => console.log(b.originSymbol, b.toDecimal(b.decimals))); }); // Build transfer data const transfer = await wallet.transfer(asset, SRC_ADDR, srcChain, DST_ADDR, dstChain); // source contains: balance, fee, feeBalance, destinationFee, max, min console.log('Sending max:', transfer.source.max.toDecimal(transfer.source.max.decimals)); // Validate: checks sufficient balance, min amount, etc. const report = await transfer.validate(); report.forEach((r) => console.log(r.type, r.isOk)); // Estimate fee for sending 0.1 ETH const fee = await transfer.estimateFee('0.1'); console.log('Fee:', fee.toDecimal(fee.decimals), fee.originSymbol); // Build the call (returns a Call object with dryRun support) const call = await transfer.buildCall('0.1'); console.log('Dry run result:', await call.dryRun()); sub.unsubscribe(); ``` ``` -------------------------------- ### Query On-Chain Assets with AssetClient Source: https://context7.com/galacticcouncil/sdk/llms.txt Fetches supported assets from the Hydration Asset Registry. Optionally include external asset overrides or all entries including invalid metadata for debugging. ```typescript const { client } = sdk; // Fetch all supported assets (filters out invalid/missing metadata) const assets = await client.asset.getSupported(); assets.forEach((a) => { console.log(`[${a.id}] ${a.symbol} (${a.type}) decimals=${a.decimals}`); }); // [0] HDX (Token) decimals=12 // [2] DAI (External) decimals=18 // [101] 2-Pool (StableSwap) decimals=18 // ... // Include external asset overrides (e.g. from an off-chain registry) const externalAssets = [ { id: 'DOT', origin: 0, name: 'Polkadot', symbol: 'DOT', decimals: 10, internalId: 5 }, ]; const enriched = await client.asset.getSupported(false, externalAssets); // Include assets with missing/invalid metadata (useful for debugging) const all = await client.asset.getSupported(true); console.log('Total registry entries:', all.length); ``` -------------------------------- ### Pre-fetch Pool Fees in Parallel Source: https://github.com/galacticcouncil/sdk/blob/master/packages/sdk-next/docs/SOR_AUDIT.md Optimize multi-hop routes by pre-fetching fees for all hops concurrently before sequential calculation. This avoids sequential RPC round-trips and reduces microtask scheduling. ```typescript private async toSellSwaps(amountIn, path, poolsMap): Promise { // Pre-fetch all fees in parallel const feePromises = path.map(hop => { const pool = poolsMap.get(hop.poolAddress)! const poolPair = pool.parsePair(hop.assetIn, hop.assetOut) return this.ctx.getPoolFees(poolPair, pool) }) const allFees = await Promise.all(feePromises) // Now run sequential calculation with pre-fetched fees const swaps: SellSwap[] = [] for (let i = 0; i < path.length; i++) { // ... use allFees[i] instead of await this.ctx.getPoolFees(...) } return swaps } ``` -------------------------------- ### Integration Tests Source: https://github.com/galacticcouncil/sdk/blob/master/CLAUDE.md Commands to run integration tests, specifically for call data verification and end-to-end cross-chain transfers. ```sh cd integration-tests/xc-test npm run spec:calldata # Call data verification npm run spec:e2e # E2E cross-chain transfers (needs Chopsticks) ``` -------------------------------- ### Shared Utility Functions from @galacticcouncil/common Source: https://context7.com/galacticcouncil/sdk/llms.txt Utilize shared functions for BigInt/decimal conversions, EVM address manipulation, ERC-20 to asset ID mapping, and Substrate account helpers. Import specific modules as needed. ```typescript import { big, h160, erc20, acc } from '@galacticcouncil/common'; // Convert between decimal strings and native bigint const native = big.toBigInt('1.5', 12); // 1_500_000_000_000n (12 decimals) const human = big.toDecimal(native, 12); // '1.5' // Convert between decimal precisions const converted = big.convertDecimals('1000000', 6, 18); // 6→18 decimal shift // EVM address helpers const evmAddr = h160.H160.fromAny('7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'); const ss58 = h160.H160.toSS58(evmAddr); // ERC-20 <-> registry asset ID mapping const { ERC20 } = erc20; const assetId = ERC20.toAssetId('0xda10009cbd5d07dd0cecc66161fc93d7c9000da1'); // DAI const evmToken = ERC20.fromAssetId(assetId); // Account utilities const { SubstrateAddr } = acc; const accountId = SubstrateAddr.toAccountId('7L53bUTBbfuj14UpdCNPwmgzzHSsrsTWBHX5pys32mVWM3C1'); ```