cd sdk.ts
npm install dotenv ts-node
cp .env.example .envEdit .env:
SELENDRA_WS_URL=wss://rpc-testnet.selendra.org
SUBSTRATE_ADDRESS=5Gjd...
SENDER_URI=//Alice
EVM_PRIVATE_KEY=0x... # Optional, for custom claimingnpm run build# Check if address has mapping
npm run unified:check-mapping
# Check eligibility and costs
npm run unified:check-eligibility
# Claim default EVM address (simplest)
npm run unified:claim-default
# Or claim with derived key (same key material)
npm run unified:claim-derived
# Or claim with custom EVM key (separate key)
npm run unified:claim-customimport { createSDK, ChainType } from '@selendrajs/sdk';
const sdk = createSDK({
endpoint: 'wss://rpc-testnet.selendra.org',
chainType: ChainType.Substrate,
});
await sdk.connect();
// Check if address has mapping
const info = await sdk.unifiedAccounts.getMappingInfo(address);
if (info.isMapped) {
console.log('Mapped to:', info.mappedTo);
} else {
console.log('No mapping. Default would be:', info.defaultMapping);
}import { Keyring } from '@polkadot/api';
import { cryptoWaitReady } from '@polkadot/util-crypto';
await cryptoWaitReady();
const keyring = new Keyring({ type: 'sr25519' });
const account = keyring.addFromUri('//Alice');
// Claim default EVM address (no signature needed)
const result = await sdk.unifiedAccounts.claimDefaultEvmAddress(account);
console.log('Claimed!');
console.log('Substrate:', result.mapping.substrate);
console.log('EVM:', result.mapping.evm);
console.log('Cost:', result.fee.total, 'planck');const evmPrivateKey = '0xabcdef...';
// Claim with custom EVM key
const result = await sdk.unifiedAccounts.claimEvmAddress(
account,
evmPrivateKey,
{ waitForFinalization: true }
);
console.log('Claimed with custom key!');
console.log('EVM address:', result.mapping.evm);// Always check eligibility first
const check = await sdk.unifiedAccounts.checkClaimEligibility(address);
if (!check.eligible) {
console.log('Cannot claim:', check.reasons.join(', '));
return;
}
// Estimate costs
const estimate = await sdk.unifiedAccounts.estimateClaimCost();
console.log('Total cost:', estimate.estimatedTotal, 'planck');
// Proceed with claim...When: You don't care about the specific EVM address
await sdk.unifiedAccounts.claimDefaultEvmAddress(account);Pros: Simplest, no signature
Cons: Cannot choose address
When: You want same key for both chains
await sdk.unifiedAccounts.claimEvmAddress(account);
// Automatically derives EVM key via //evm pathPros: Same key material, can sign both chains
Cons: EVM address is derived, not chosen
When: You have an existing EVM wallet to link
const evmKey = '0x...'; // Your MetaMask key, etc.
await sdk.unifiedAccounts.claimEvmAddress(account, evmKey);Pros: Full control, use existing wallets
Cons: Must manage two keys
const result = await sdk.unifiedAccounts.getEvmAddressForSubstrate('5Gjd...');const result = await sdk.unifiedAccounts.getSubstrateAddressForEvm('0x1234...');const defaultEvm = sdk.unifiedAccounts.getDefaultEvmAddress('5Gjd...');
const defaultSub = sdk.unifiedAccounts.getDefaultSubstrateAddress('0x1234...');const fee = await sdk.unifiedAccounts.getStorageFee();
console.log(`Fee: ${fee} planck (${Number(fee) / 1e18} SEL)`);-
One Claim Per Account
- Each Substrate account can only claim once
- Choose your method carefully!
- Cannot change mapping after claiming
-
Storage Fee
- Fee is burned (not sent to treasury)
- One-time cost when claiming
- Check cost:
estimateClaimCost()
-
Testnet First!
- Always test on testnet before mainnet
- Testnet:
wss://rpc-testnet.selendra.org - Get test tokens from faucet
-
Security
- Never commit private keys
- Use
.envfiles (in.gitignore) - Backup both Substrate and EVM keys
- Full API Docs: docs/UNIFIED_ACCOUNTS.md
- Examples: examples/unified/README.md
- Implementation Plan: UNIFIED_ACCOUNTS_PLAN.md
- Completion Summary: IMPLEMENTATION_COMPLETE.md
npm run clean
npm install
npm run build- Make sure you're connected to a Substrate chain
- Check:
sdk.chainType === ChainType.Substrate
- Account already claimed
- Check:
await sdk.unifiedAccounts.isMapped(address)
- Need more tokens for storage fee
- Check:
await sdk.unifiedAccounts.checkClaimEligibility(address)
Before claiming:
- Connected to correct network (testnet/mainnet)
- Have sufficient balance
- Checked eligibility
- Estimated costs
- Chose claiming approach
- Backed up private keys
- Verified addresses
Ready to start? Run:
npm run unified:check-eligibilityThen choose your claiming method! π