Advanced Topics
Lux Integration
Blockchain anchoring and staking on Lux Network
Lux Network Integration
ZAP integrates with the Lux blockchain for identity anchoring, staking, and on-chain verification.
Overview
Lux Network provides:
- DID Anchoring: Immutable identity records
- Stake Registry: Economic security for agents
- On-chain Verification: Trustless identity validation
- Cross-chain: Interoperability with other chains
did:lux Method
The did:lux method anchors DIDs on the Lux blockchain:
did:lux:0x1234567890abcdef1234567890abcdef12345678Resolution
use zap_protocol::lux::{LuxResolver, ChainConfig};
// Configure Lux connection
let config = ChainConfig {
rpc_url: "https://rpc.lux.network",
chain_id: 1,
registry_address: "0x...",
};
let resolver = LuxResolver::new(config)?;
// Resolve DID
let doc = resolver.resolve("did:lux:0x1234...").await?;Creation
use zap_protocol::lux::{LuxRegistry, CreateOptions};
let registry = LuxRegistry::connect(config).await?;
// Create DID (submits transaction)
let did = registry.create(
&public_key,
CreateOptions {
services: vec![...],
stake: Some(1000), // Initial stake
}
).await?;
println!("Created: {} (tx: {})", did.did, did.tx_hash);Stake Registry
ZAP uses Lux for stake-based security:
Stake Structure
struct StakeEntry {
did @0 :Did;
amount @1 :UInt64;
timestamp @2 :Timestamp;
}Staking Operations
use zap_protocol::lux::StakeRegistry;
let stake_registry = StakeRegistry::connect(config).await?;
// Get stake
let stake = stake_registry.get_stake(&did).await?;
println!("Stake: {} LUX", stake);
// Increase stake
let tx = stake_registry.stake(&did, 1000, &private_key).await?;
println!("Staked: tx {}", tx);
// Withdraw stake (subject to unbonding period)
let tx = stake_registry.unstake(&did, 500, &private_key).await?;Stake Benefits
| Stake Level | Benefits |
|---|---|
| 0 | Basic participation |
| 100+ | Consensus voting eligibility |
| 1000+ | Ringtail party eligibility |
| 10000+ | Coordinator eligibility |
Chain Configuration
Mainnet
let config = ChainConfig {
rpc_url: "https://rpc.lux.network",
chain_id: 1,
registry_address: "0xDIDRegistry...",
stake_address: "0xStakeRegistry...",
};Testnet
let config = ChainConfig {
rpc_url: "https://testnet.rpc.lux.network",
chain_id: 888,
registry_address: "0xTestDIDRegistry...",
stake_address: "0xTestStakeRegistry...",
};Smart Contract Interfaces
DID Registry Contract
interface IDIDRegistry {
function resolve(string calldata did) external view returns (DIDDocument memory);
function create(bytes calldata publicKey, Service[] calldata services) external returns (string memory);
function update(string calldata did, DIDDocument calldata doc, bytes calldata sig) external;
function deactivate(string calldata did, bytes calldata sig) external;
}Stake Registry Contract
interface IStakeRegistry {
function getStake(string calldata did) external view returns (uint256);
function stake(string calldata did) external payable;
function unstake(string calldata did, uint256 amount) external;
function getUnbondingPeriod() external view returns (uint256);
}Integration Examples
Agent Registration with Stake
use zap_protocol::{Coordinator, NodeIdentity};
use zap_protocol::lux::{LuxRegistry, StakeRegistry};
// Create identity
let identity = NodeIdentity::generate()?;
// Register DID on Lux
let lux = LuxRegistry::connect(config).await?;
let did = lux.create(&identity.public_key, CreateOptions::default()).await?;
// Stake for consensus eligibility
let stake = StakeRegistry::connect(config).await?;
stake.stake(&did.did, 1000, &identity.private_key).await?;
// Register with ZAP coordinator
let coordinator = Coordinator::connect("zap://coordinator:9001").await?;
coordinator.register(&AgentInfo {
id: did.did.to_string(),
name: "my-agent".into(),
capabilities: vec!["tools".into()],
metadata: Default::default(),
}).await?;Verified Tool Calls
// Caller provides stake proof
let proof = stake_registry.get_proof(&caller_did).await?;
// Server verifies stake before processing
if !stake_registry.verify_proof(&proof, min_stake) {
return Err("Insufficient stake");
}
// Process tool call
let result = process_tool(call).await?;Consensus with Stake Weighting
use zap_protocol::consensus::{AgentConsensus, StakeWeightedConfig};
let consensus = AgentConsensus::new_stake_weighted(
StakeWeightedConfig {
stake_registry: stake_registry.clone(),
min_stake: 100,
weight_by_stake: true,
}
);
// Responses weighted by stake
consensus.submit_response(&query_id, &agent_did, response, signature).await?;Transaction Monitoring
use zap_protocol::lux::TransactionMonitor;
let monitor = TransactionMonitor::new(config)?;
// Watch for DID updates
monitor.watch_did_updates(&did, |update| {
println!("DID updated: {:?}", update);
}).await?;
// Watch for stake changes
monitor.watch_stake_changes(&did, |change| {
println!("Stake changed: {} -> {}", change.old, change.new);
}).await?;Gas Optimization
Tips for minimizing transaction costs:
- Batch Operations: Combine multiple updates
- Off-chain Signatures: Use EIP-712 typed data
- State Channels: For frequent updates
- L2 Options: Use Lux subnets for lower fees
// Batch update
let tx = lux.batch_update(vec![
UpdateOp::AddService(service1),
UpdateOp::AddKey(key1),
UpdateOp::RemoveService(old_service_id),
]).await?;Error Handling
use zap_protocol::lux::LuxError;
match lux.create(&public_key, options).await {
Ok(did) => println!("Created: {}", did),
Err(LuxError::InsufficientFunds) => {
println!("Need more LUX for gas");
}
Err(LuxError::AlreadyExists) => {
println!("DID already registered");
}
Err(LuxError::NetworkError(e)) => {
println!("RPC error: {}", e);
}
Err(e) => return Err(e.into()),
}Security Considerations
- Key Security: Never expose private keys
- Transaction Signing: Use hardware wallets for high-value operations
- Stake Locking: Consider unbonding period for slashing protection
- Contract Audits: Verify registry contract addresses
Resources
Last updated on