mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
10 KiB
10 KiB
IBC Integration for Identity DAO
Overview
The Identity DAO will be deployed on Cosmos Hub and communicate with Sonr chain modules via IBC (Inter-Blockchain Communication). This document outlines the IBC integration architecture and implementation details.
Architecture
graph LR
subgraph "Cosmos Hub"
A[Identity DAO Contracts]
B[IBC Light Client]
end
subgraph "IBC Channel"
C[Relayer]
end
subgraph "Sonr Chain"
D[x/did Module]
E[x/dwn Module]
F[x/svc Module]
end
A -->|IBC Query| B
B <-->|Packets| C
C <-->|Packets| D
C <-->|Packets| E
C <-->|Packets| F
IBC Channel Configuration
Channel Setup
# Create IBC channel between Cosmos Hub and Sonr
hermes create channel \
--a-chain cosmoshub-4 \
--b-chain sonr-1 \
--a-port wasm.cosmos1... \
--b-port did \
--order unordered \
--version ics20-1
Connection Parameters
{
"channel_id": "channel-xxx",
"port_id": "wasm.cosmos1abc...",
"counterparty_channel_id": "channel-yyy",
"counterparty_port_id": "did",
"connection_id": "connection-xxx",
"version": "ics20-1"
}
Contract Modifications for IBC
1. IBC Entry Points
Add IBC entry points to each contract:
// contracts/core/src/ibc.rs
use cosmwasm_std::{
entry_point, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg,
IbcChannelOpenMsg, IbcChannelOpenResponse, IbcPacketAckMsg, IbcPacketReceiveMsg,
IbcPacketTimeoutMsg, IbcReceiveResponse, Never,
};
#[entry_point]
pub fn ibc_channel_open(
_deps: DepsMut,
_env: Env,
msg: IbcChannelOpenMsg,
) -> Result<IbcChannelOpenResponse, ContractError> {
// Validate channel parameters
validate_channel(&msg.channel)?;
Ok(None)
}
#[entry_point]
pub fn ibc_channel_connect(
deps: DepsMut,
_env: Env,
msg: IbcChannelConnectMsg,
) -> Result<IbcBasicResponse, ContractError> {
// Store channel info
let channel = msg.channel();
CHANNEL_INFO.save(deps.storage, &channel.endpoint, &channel)?;
Ok(IbcBasicResponse::new()
.add_attribute("method", "ibc_channel_connect")
.add_attribute("channel_id", channel.endpoint.channel_id))
}
#[entry_point]
pub fn ibc_packet_receive(
deps: DepsMut,
env: Env,
msg: IbcPacketReceiveMsg,
) -> Result<IbcReceiveResponse, Never> {
// Handle incoming IBC packets
let packet = msg.packet;
let res = handle_packet(deps, env, packet)?;
Ok(IbcReceiveResponse::new()
.set_ack(res.acknowledgement)
.add_attributes(res.attributes))
}
2. Cross-Chain DID Queries
Replace Stargate queries with IBC queries:
// contracts/voting/src/ibc_query.rs
use cosmwasm_std::{to_binary, Binary, Deps, Env, IbcMsg, IbcTimeout};
pub fn query_did_via_ibc(
deps: Deps,
env: Env,
did: String,
) -> Result<IbcMsg, ContractError> {
let channel = CHANNEL_INFO.load(deps.storage)?;
let query_msg = DIDQuery {
query_type: "get_did_document",
did,
};
let packet = IbcMsg::SendPacket {
channel_id: channel.endpoint.channel_id,
data: to_binary(&query_msg)?,
timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(60)),
};
Ok(packet)
}
pub fn handle_did_response(
deps: DepsMut,
response: Binary,
) -> Result<(), ContractError> {
let did_doc: DIDDocumentResponse = from_binary(&response)?;
// Cache DID document for voting power calculation
DID_CACHE.save(
deps.storage,
&did_doc.document.id,
&did_doc,
)?;
Ok(())
}
3. Asynchronous Voting Power
Since IBC queries are asynchronous, modify voting to handle this:
// contracts/voting/src/state.rs
pub struct PendingVote {
pub voter: Addr,
pub proposal_id: u64,
pub vote: Vote,
pub did_query_id: String,
}
pub const PENDING_VOTES: Map<String, PendingVote> = Map::new("pending_votes");
// contracts/voting/src/contract.rs
pub fn execute_vote(
deps: DepsMut,
env: Env,
info: MessageInfo,
proposal_id: u64,
vote: Vote,
) -> Result<Response, ContractError> {
// Check if we have cached DID info
let did = format!("did:sonr:{}", info.sender);
if let Some(did_doc) = DID_CACHE.may_load(deps.storage, &did)? {
// Process vote immediately
process_vote(deps, env, info.sender, proposal_id, vote, did_doc)
} else {
// Queue vote and query DID via IBC
let query_id = generate_query_id(&env, &info.sender);
PENDING_VOTES.save(
deps.storage,
&query_id,
&PendingVote {
voter: info.sender,
proposal_id,
vote,
did_query_id: query_id.clone(),
},
)?;
let ibc_msg = query_did_via_ibc(deps.as_ref(), env, did)?;
Ok(Response::new()
.add_message(ibc_msg)
.add_attribute("action", "vote_pending")
.add_attribute("query_id", query_id))
}
}
IBC Packet Types
DID Query Packet
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct DIDQueryPacket {
pub query_type: String,
pub did: String,
pub requester: String,
pub callback_id: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct DIDResponsePacket {
pub callback_id: String,
pub did_document: Option<DIDDocument>,
pub verification_status: VerificationStatus,
pub error: Option<String>,
}
Cross-Chain Proposal Packet
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct CrossChainProposalPacket {
pub proposal_type: String,
pub target_module: String, // "did", "dwn", or "svc"
pub action: String,
pub params: Binary,
pub proposer_did: String,
}
Deployment Scripts Update
Cosmos Hub Deployment
#!/bin/bash
# deploy_cosmoshub.sh
# Cosmos Hub configuration
CHAIN_ID="cosmoshub-4"
NODE="https://rpc.cosmos.network:443"
DEPLOYER="cosmos1..."
GAS_PRICES="0.025uatom"
# Deploy contracts
gaiad tx wasm store artifacts/identity_dao_core.wasm \
--from $DEPLOYER \
--chain-id $CHAIN_ID \
--node $NODE \
--gas-prices $GAS_PRICES \
--broadcast-mode block
# Instantiate with IBC configuration
INIT_MSG=$(cat <<EOF
{
"admin": "$DEPLOYER",
"dao_name": "Sonr Identity DAO",
"dao_uri": "https://sonr.io/dao",
"ibc_config": {
"sonr_channel": "channel-xxx",
"sonr_port": "did",
"timeout_seconds": 60
}
}
EOF
)
gaiad tx wasm instantiate $CODE_ID "$INIT_MSG" \
--from $DEPLOYER \
--label "identity-dao-core" \
--admin $DEPLOYER
IBC Channel Setup
#!/bin/bash
# setup_ibc.sh
# Install Hermes relayer
cargo install ibc-relayer-cli --version 1.0.0
# Configure relayer
hermes config init
# Add chains
hermes chains add cosmoshub-4
hermes chains add sonr-1
# Create client, connection, and channel
hermes create channel \
--a-chain cosmoshub-4 \
--b-chain sonr-1 \
--a-port "wasm.$DAO_CONTRACT" \
--b-port "did" \
--order unordered
# Start relayer
hermes start
Testing IBC Integration
Local Testing with IBC
// tests/e2e/ibc_test.go
func TestIBCDIDQuery(t *testing.T) {
// Setup two chains
cosmosHub := setupCosmosHub()
sonrChain := setupSonrChain()
// Create IBC channel
channel := createIBCChannel(cosmosHub, sonrChain)
// Deploy DAO on Cosmos Hub
daoAddr := deployDAO(cosmosHub)
// Create DID on Sonr
did := createDID(sonrChain, "test-user")
// Query DID via IBC from DAO
response := queryDIDViaIBC(daoAddr, did, channel)
assert.NotNil(t, response)
assert.Equal(t, did, response.Document.ID)
}
Integration Test Script
#!/bin/bash
# test_ibc_integration.sh
# Start local chains
ignite chain serve -c cosmoshub &
COSMOS_PID=$!
ignite chain serve -c sonr &
SONR_PID=$!
# Wait for chains
sleep 10
# Setup IBC
bash setup_ibc.sh
# Deploy contracts
bash deploy_cosmoshub.sh
# Run test transactions
echo "Testing IBC DID query..."
gaiad tx wasm execute $DAO_ADDR \
'{"query_did_ibc":{"did":"did:sonr:test123"}}' \
--from tester
# Check results
gaiad query wasm contract-state smart $DAO_ADDR \
'{"get_cached_did":{"did":"did:sonr:test123"}}'
# Cleanup
kill $COSMOS_PID $SONR_PID
Security Considerations
IBC-Specific Security
- Channel Authentication: Verify channel is connected to correct Sonr chain
- Packet Validation: Validate all incoming IBC packets
- Timeout Handling: Handle packet timeouts gracefully
- Replay Protection: Ensure packets cannot be replayed
Trust Assumptions
- Relayer Trust: Relayers cannot forge packets but can censor
- Light Client Security: Depends on IBC light client security
- Cross-Chain Atomicity: No atomicity guarantees across chains
Gas Costs
IBC Operations Gas Estimates
| Operation | Gas Cost |
|---|---|
| IBC Channel Open | 150,000 |
| IBC Packet Send | 80,000 |
| IBC Packet Receive | 100,000 |
| IBC Acknowledgement | 60,000 |
| DID Query via IBC | 180,000 |
Migration from Stargate to IBC
Before (Stargate)
let query = QueryRequest::Stargate {
path: "/sonr.did.Query/GetDIDDocument".to_string(),
data: Binary::from(query_data),
};
let response: DIDDocumentResponse = deps.querier.query(&query)?;
After (IBC)
let ibc_msg = IbcMsg::SendPacket {
channel_id: channel.id,
data: to_binary(&DIDQueryPacket {
query_type: "get_did_document".to_string(),
did: did.clone(),
requester: info.sender.to_string(),
callback_id: generate_callback_id(),
})?,
timeout: IbcTimeout::with_timestamp(env.block.time.plus_seconds(60)),
};
// Response handled asynchronously in ibc_packet_receive
Monitoring and Maintenance
Metrics to Track
- IBC packet success rate
- Average query latency
- Channel uptime
- Relayer performance
Maintenance Tasks
- Update relayer configuration
- Monitor channel health
- Handle stuck packets
- Upgrade IBC client
Conclusion
IBC integration enables the Identity DAO on Cosmos Hub to securely interact with Sonr chain modules. The asynchronous nature of IBC requires architectural changes but provides better security and decentralization compared to direct module access.