xian-sdk
Build applications on the Xian blockchain using the xian-py Python SDK. Use when developing apps that interact with Xian — wallets, transactions, smart contracts, state queries, token transfers. Covers sync and async patterns.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install openclaw-skills-xian-sdk-skill
Repository
Skill path: skills/endogen/xian-sdk-skill
Build applications on the Xian blockchain using the xian-py Python SDK. Use when developing apps that interact with Xian — wallets, transactions, smart contracts, state queries, token transfers. Covers sync and async patterns.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: openclaw.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install xian-sdk into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/openclaw/skills before adding xian-sdk to shared team environments
- Use xian-sdk for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: xian-sdk
description: Build applications on the Xian blockchain using the xian-py Python SDK. Use when developing apps that interact with Xian — wallets, transactions, smart contracts, state queries, token transfers. Covers sync and async patterns.
---
# Xian SDK Skill
Build applications on [Xian](https://xian.org) using the [xian-py](https://github.com/xian-network/xian-py) Python SDK.
## Installation
```bash
pip install xian-py
# With Ethereum wallet support
pip install "xian-py[eth]"
```
## Quick Reference
```python
from xian_py import Xian, Wallet
wallet = Wallet() # New wallet
xian = Xian('http://node:26657', wallet=wallet)
# Common operations
balance = xian.get_balance(wallet.public_key)
state = xian.get_state('contract', 'variable', 'key')
result = xian.send(amount=100, to_address='recipient')
result = xian.send_tx('contract', 'function', {'arg': 'value'})
result = xian.submit_contract('name', code)
```
## Wallets
### Basic Wallet
```python
from xian_py import Wallet
# Create new wallet (random seed)
wallet = Wallet()
# From existing private key
wallet = Wallet('ed30796abc4ab47a97bfb37359f50a9c362c7b304a4b4ad1b3f5369ecb6f7fd8')
print(wallet.public_key) # Address
print(wallet.private_key) # Keep secret!
```
### HD Wallet (BIP39/BIP32)
```python
from xian_py.wallet import HDWallet
# Create with new 24-word mnemonic
hd = HDWallet()
print(hd.mnemonic_str) # Save this!
# Restore from mnemonic
hd = HDWallet('word1 word2 word3 ... word24')
# Derive Xian wallet
path = [44, 0, 0, 0, 0] # m/44'/0'/0'/0'/0'
wallet = hd.get_wallet(path)
# Derive Ethereum wallet (requires eth extras)
eth_wallet = hd.get_ethereum_wallet(0) # First account
eth_wallet2 = hd.get_ethereum_wallet(1) # Second account
```
### Signing & Verification
```python
wallet = Wallet()
# Sign message
signature = wallet.sign_msg("Hello Xian")
# Verify
is_valid = wallet.verify_msg("Hello Xian", signature)
# Validate key format
Wallet.is_valid_key(wallet.public_key) # True
```
## Blockchain Queries
```python
from xian_py import Xian
xian = Xian('http://node:26657')
# Balance (default: currency contract)
balance = xian.get_balance('address')
# Custom token balance
balance = xian.get_balance('address', contract='token_contract')
# Contract state
state = xian.get_state('contract_name', 'variable', 'key')
# Get contract source
source = xian.get_contract('contract_name', clean=True)
```
## Transactions
### Simple Token Transfer
```python
from xian_py import Xian, Wallet
wallet = Wallet('your_private_key')
xian = Xian('http://node:26657', wallet=wallet)
# Send tokens (auto stamp calculation)
result = xian.send(amount=100, to_address='recipient')
if result['success']:
print(f"TX: {result['tx_hash']}")
```
### Contract Interaction
```python
# Call any contract function
result = xian.send_tx(
contract='currency',
function='transfer',
kwargs={'to': 'recipient', 'amount': 1000}
)
# With custom token
result = xian.send_tx(
contract='my_token',
function='transfer',
kwargs={'to': 'recipient', 'amount': 500}
)
```
### Stamp Estimation
```python
from xian_py.transaction import simulate_tx, get_nonce
# Simulate to get stamp cost
payload = {
"contract": "currency",
"function": "transfer",
"kwargs": {"to": "recipient", "amount": 100},
"sender": wallet.public_key,
}
result = simulate_tx('http://node:26657', payload)
print(f"Stamps needed: {result['stamps_used']}")
```
## Smart Contracts
### Deploy Contract
```python
code = '''
balances = Hash(default_value=0)
@construct
def seed():
balances[ctx.caller] = 1_000_000
@export
def transfer(to: str, amount: float):
assert amount > 0, "Amount must be positive"
assert balances[ctx.caller] >= amount, "Insufficient balance"
balances[ctx.caller] -= amount
balances[to] += amount
@export
def balance_of(address: str) -> float:
return balances[address]
'''
result = xian.submit_contract('my_token', code)
print(f"Deployed: {result['success']}")
```
### Contract Patterns
See `references/contract-patterns.md` for common patterns (tokens, access control, pausable, upgrades).
### Contract Validation
Validate against [Xian standards](https://github.com/xian-network/xian-standard-contracts):
```python
from xian_py.validator import validate_contract, XianStandard
is_valid, errors = validate_contract(code) # XSC001 default
# Specific standard
is_valid, errors = validate_contract(code, standard=XianStandard.XSC001)
if not is_valid:
print(errors)
```
### Read-Only Execution
Query contract without spending stamps:
```python
from xian_py.transaction import simulate_tx
payload = {
"contract": "my_token",
"function": "balance_of",
"kwargs": {"address": "some_address"},
"sender": wallet.public_key,
}
result = simulate_tx('http://node:26657', payload)
print(f"Balance: {result['result']}")
```
## Async Operations
For high-performance applications:
```python
import asyncio
from xian_py import XianAsync, Wallet
async def main():
wallet = Wallet()
async with XianAsync('http://node:26657', wallet=wallet) as xian:
# Concurrent queries
balance, state = await asyncio.gather(
xian.get_balance(wallet.public_key),
xian.get_state('currency', 'balances', 'address')
)
# Send transaction
result = await xian.send(amount=100, to_address='recipient')
asyncio.run(main())
```
### Batch Operations
```python
async def check_balances(addresses: list[str]):
async with XianAsync('http://node:26657') as xian:
balances = await asyncio.gather(*[
xian.get_balance(addr) for addr in addresses
])
return dict(zip(addresses, balances))
```
### Sync Wrapper
Call async from sync code:
```python
from xian_py import XianAsync, run_sync
def get_balance_sync(address: str) -> float:
async def _get():
async with XianAsync('http://node:26657') as xian:
return await xian.get_balance(address)
return run_sync(_get())
balance = get_balance_sync('address')
```
## Encryption
Two-way encrypted messaging:
```python
from xian_py import Wallet
from xian_py.crypto import encrypt, decrypt_as_sender, decrypt_as_receiver
sender = Wallet()
receiver = Wallet()
# Encrypt
encrypted = encrypt(sender.private_key, receiver.public_key, "Secret message")
# Decrypt as sender
msg = decrypt_as_sender(sender.private_key, receiver.public_key, encrypted)
# Decrypt as receiver
msg = decrypt_as_receiver(sender.public_key, receiver.private_key, encrypted)
```
## Error Handling
```python
from xian_py import Xian, XianException
try:
result = xian.send_tx('contract', 'function', {})
except XianException as e:
print(f"Blockchain error: {e}")
```
## Common Patterns
### Token Transfer Service
```python
class TokenService:
def __init__(self, node_url: str, private_key: str):
self.wallet = Wallet(private_key)
self.xian = Xian(node_url, wallet=self.wallet)
def transfer(self, to: str, amount: float, token: str = 'currency'):
balance = self.xian.get_balance(self.wallet.public_key, contract=token)
if balance < amount:
raise ValueError(f"Insufficient: {balance} < {amount}")
return self.xian.send_tx(token, 'transfer', {'to': to, 'amount': amount})
```
### DEX Swap
```python
async def swap(xian, dex: str, token_in: str, token_out: str,
amount: float, min_out: float):
# Approve DEX
await xian.send_tx(token_in, 'approve', {'to': dex, 'amount': amount})
# Execute swap
return await xian.send_tx(dex, 'swap', {
'token_in': token_in,
'token_out': token_out,
'amount_in': amount,
'min_amount_out': min_out
})
```
## Resources
- [xian-py GitHub](https://github.com/xian-network/xian-py) — Full SDK docs
- [Xian Standard Contracts](https://github.com/xian-network/xian-standard-contracts) — Token standards
- [xian.org](https://xian.org) — Project site
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/contract-patterns.md
```markdown
# Xian Contract Patterns
Common patterns for Xian smart contracts written in Python.
## Table of Contents
- [Basic Token (XSC001)](#basic-token-xsc001)
- [Access Control](#access-control)
- [Pausable Contract](#pausable-contract)
- [Upgradeable Pattern](#upgradeable-pattern)
## Basic Token (XSC001)
Minimal fungible token following XSC001 standard:
```python
balances = Hash(default_value=0)
metadata = Hash()
@construct
def seed():
metadata['token_name'] = 'My Token'
metadata['token_symbol'] = 'MTK'
metadata['token_logo_url'] = 'https://example.com/logo.png'
metadata['token_website'] = 'https://example.com'
metadata['operator'] = ctx.caller
# Initial supply to deployer
balances[ctx.caller] = 1_000_000
@export
def transfer(amount: float, to: str):
assert amount > 0, 'Amount must be positive'
assert balances[ctx.caller] >= amount, 'Insufficient balance'
balances[ctx.caller] -= amount
balances[to] += amount
@export
def approve(amount: float, to: str):
balances[ctx.caller, to] = amount
@export
def transfer_from(amount: float, to: str, main_account: str):
assert amount > 0, 'Amount must be positive'
assert balances[main_account, ctx.caller] >= amount, 'Not approved'
assert balances[main_account] >= amount, 'Insufficient balance'
balances[main_account, ctx.caller] -= amount
balances[main_account] -= amount
balances[to] += amount
@export
def balance_of(address: str) -> float:
return balances[address]
```
## Access Control
Owner-only functions:
```python
owner = Variable()
@construct
def seed():
owner.set(ctx.caller)
def only_owner():
assert ctx.caller == owner.get(), 'Only owner'
@export
def admin_function():
only_owner()
# ... privileged logic
@export
def transfer_ownership(new_owner: str):
only_owner()
owner.set(new_owner)
```
Multi-role access:
```python
roles = Hash(default_value=False)
@construct
def seed():
roles['admin', ctx.caller] = True
@export
def grant_role(role: str, account: str):
assert roles['admin', ctx.caller], 'Only admin'
roles[role, account] = True
@export
def revoke_role(role: str, account: str):
assert roles['admin', ctx.caller], 'Only admin'
roles[role, account] = False
@export
def minter_function():
assert roles['minter', ctx.caller], 'Only minter'
# ... minting logic
```
## Pausable Contract
Emergency stop pattern:
```python
paused = Variable()
owner = Variable()
@construct
def seed():
owner.set(ctx.caller)
paused.set(False)
def when_not_paused():
assert not paused.get(), 'Contract is paused'
def only_owner():
assert ctx.caller == owner.get(), 'Only owner'
@export
def pause():
only_owner()
paused.set(True)
@export
def unpause():
only_owner()
paused.set(False)
@export
def transfer(to: str, amount: float):
when_not_paused()
# ... transfer logic
```
## Upgradeable Pattern
Proxy pattern for upgrades:
```python
# Proxy contract
implementation = Variable()
owner = Variable()
@construct
def seed(impl_contract: str):
implementation.set(impl_contract)
owner.set(ctx.caller)
@export
def upgrade(new_impl: str):
assert ctx.caller == owner.get(), 'Only owner'
implementation.set(new_impl)
@export
def execute(function: str, kwargs: dict):
impl = importlib.import_module(implementation.get())
fn = getattr(impl, function)
return fn(**kwargs)
```
## State Patterns
### Mapping with Default
```python
balances = Hash(default_value=0)
# No need to initialize - returns 0 for unknown keys
balance = balances['new_address'] # Returns 0
```
### Nested Mapping
```python
# Allowances: owner -> spender -> amount
allowances = Hash(default_value=0)
allowances[owner, spender] = 100
allowed = allowances[owner, spender]
```
### List-like Storage
```python
items = Hash()
item_count = Variable()
@construct
def seed():
item_count.set(0)
@export
def add_item(data: str):
idx = item_count.get()
items[idx] = data
item_count.set(idx + 1)
@export
def get_item(idx: int) -> str:
assert idx < item_count.get(), 'Index out of bounds'
return items[idx]
```
## Event Logging
Emit events for off-chain indexing:
```python
@export
def transfer(to: str, amount: float):
# ... transfer logic
# Log event (captured by BDS)
return {
'event': 'Transfer',
'from': ctx.caller,
'to': to,
'amount': amount
}
```
## Time-based Logic
```python
import datetime
lock_until = Hash()
@export
def lock_tokens(amount: float, days: int):
unlock_time = datetime.datetime.now() + datetime.timedelta(days=days)
lock_until[ctx.caller] = unlock_time
# ... lock logic
@export
def unlock():
assert datetime.datetime.now() >= lock_until[ctx.caller], 'Still locked'
# ... unlock logic
```
```
---
## Skill Companion Files
> Additional files collected from the skill directory layout.
### _meta.json
```json
{
"owner": "endogen",
"slug": "xian-sdk-skill",
"displayName": "Xian SDK",
"latest": {
"version": "0.1.0",
"publishedAt": 1770511631948,
"commit": "https://github.com/openclaw/skills/commit/8fee4561b39d146598dcbf107398ec4624b4ca03"
},
"history": []
}
```