* clear

* feat: Add everything

* fix: Commenht
This commit is contained in:
Prad Nukala
2025-10-03 14:45:52 -04:00
committed by GitHub
parent 43b4a11c06
commit 13e6c3e84d
1935 changed files with 655061 additions and 40058 deletions
+203
View File
@@ -0,0 +1,203 @@
#!/bin/bash
# Build and optimize Identity DAO contracts for deployment
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Configuration
PROJECT_ROOT="$(dirname "$0")/.."
CONTRACTS_DIR="${PROJECT_ROOT}/contracts"
TARGET_DIR="${PROJECT_ROOT}/target/wasm32-unknown-unknown/release"
ARTIFACTS_DIR="${PROJECT_ROOT}/artifacts"
# Contract names
CONTRACTS=(
"identity-dao-core"
"identity-dao-voting"
"identity-dao-proposals"
"identity-dao-pre-propose"
)
# Check for Rust and wasm32 target
check_requirements() {
log_info "Checking build requirements..."
if ! command -v cargo &> /dev/null; then
log_error "Rust/Cargo not found. Please install Rust."
exit 1
fi
if ! rustup target list --installed | grep -q wasm32-unknown-unknown; then
log_warning "wasm32-unknown-unknown target not installed. Installing..."
rustup target add wasm32-unknown-unknown
fi
if ! command -v docker &> /dev/null; then
log_error "Docker not found. Docker is required for contract optimization."
exit 1
fi
log_info "All requirements satisfied"
}
# Build contracts
build_contracts() {
log_info "Building contracts..."
cd "${PROJECT_ROOT}"
# Clean previous builds
cargo clean
# Build all contracts in release mode
RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown
if [ $? -eq 0 ]; then
log_info "Contracts built successfully"
else
log_error "Failed to build contracts"
exit 1
fi
}
# Optimize contracts using CosmWasm optimizer
optimize_contracts() {
log_info "Optimizing contracts for deployment..."
# Create artifacts directory
mkdir -p "${ARTIFACTS_DIR}"
# Run optimizer in Docker
docker run --rm -v "${PROJECT_ROOT}":/code \
--mount type=volume,source="dao_contracts_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/optimizer:0.16.0
if [ $? -eq 0 ]; then
log_info "Contract optimization complete"
# Move optimized contracts to artifacts
mv "${PROJECT_ROOT}"/artifacts/*.wasm "${ARTIFACTS_DIR}/" 2>/dev/null || true
else
log_error "Failed to optimize contracts"
exit 1
fi
}
# Generate schemas
generate_schemas() {
log_info "Generating contract schemas..."
cd "${PROJECT_ROOT}"
for contract in "${CONTRACTS[@]}"; do
contract_dir="${CONTRACTS_DIR}/${contract//-/_}"
if [ -d "${contract_dir}" ]; then
log_info "Generating schema for ${contract}..."
cd "${contract_dir}"
cargo schema
fi
done
log_info "Schema generation complete"
}
# Verify contract sizes
verify_sizes() {
log_info "Verifying contract sizes..."
MAX_SIZE=$((600 * 1024)) # 600 KB max size for Cosmos chains
for wasm_file in "${ARTIFACTS_DIR}"/*.wasm; do
if [ -f "$wasm_file" ]; then
size=$(stat -f%z "$wasm_file" 2>/dev/null || stat -c%s "$wasm_file" 2>/dev/null)
size_kb=$((size / 1024))
filename=$(basename "$wasm_file")
if [ $size -gt $MAX_SIZE ]; then
log_error "$filename is too large: ${size_kb}KB (max: 600KB)"
exit 1
else
log_info "$filename: ${size_kb}KB ✓"
fi
fi
done
}
# Generate checksums
generate_checksums() {
log_info "Generating checksums..."
cd "${ARTIFACTS_DIR}"
if [ -f checksums.txt ]; then
rm checksums.txt
fi
for wasm_file in *.wasm; do
if [ -f "$wasm_file" ]; then
if command -v sha256sum &> /dev/null; then
sha256sum "$wasm_file" >> checksums.txt
else
shasum -a 256 "$wasm_file" >> checksums.txt
fi
fi
done
log_info "Checksums saved to artifacts/checksums.txt"
}
# Main build flow
main() {
log_info "Starting Identity DAO contract build process..."
# Check requirements
check_requirements
# Build contracts
build_contracts
# Optimize contracts
optimize_contracts
# Generate schemas
generate_schemas
# Verify sizes
verify_sizes
# Generate checksums
generate_checksums
log_info "✅ Build complete!"
log_info ""
log_info "=== Build Summary ==="
log_info "Optimized contracts location: ${ARTIFACTS_DIR}"
log_info "Contract schemas location: ${CONTRACTS_DIR}/*/schema"
log_info ""
log_info "Next steps:"
log_info "1. Review contract sizes in ${ARTIFACTS_DIR}"
log_info "2. Deploy contracts using: ./scripts/deploy_testnet.sh"
}
# Run main build
main "$@"
+364
View File
@@ -0,0 +1,364 @@
#!/bin/bash
# Identity DAO Deployment Script for Cosmos Hub
# Deploys contracts to Cosmos Hub and establishes IBC channels to Sonr
set -e
# Configuration
COSMOS_HUB_CHAIN_ID="${COSMOS_HUB_CHAIN_ID:-cosmoshub-testnet}"
COSMOS_HUB_NODE="${COSMOS_HUB_NODE:-https://rpc.testnet.cosmos.network:443}"
SONR_CHAIN_ID="${SONR_CHAIN_ID:-sonrtest_1-1}"
SONR_NODE="${SONR_NODE:-http://localhost:26657}"
DEPLOYER="${DEPLOYER:-deployer}"
GAS_PRICES="${GAS_PRICES:-0.025uatom}"
CONTRACTS_DIR="../artifacts"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Identity DAO Deployment to Cosmos Hub${NC}"
echo -e "${BLUE}========================================${NC}"
# Function to store contract code
store_contract() {
local wasm_file=$1
local label=$2
echo -e "${GREEN}Storing contract: ${label}${NC}"
TX_HASH=$(gaiad tx wasm store "$wasm_file" \
--from "$DEPLOYER" \
--chain-id "$COSMOS_HUB_CHAIN_ID" \
--node "$COSMOS_HUB_NODE" \
--gas-prices "$GAS_PRICES" \
--gas auto \
--gas-adjustment 1.5 \
--broadcast-mode sync \
--yes \
--output json | jq -r '.txhash')
echo "Waiting for transaction..."
sleep 6
CODE_ID=$(gaiad query tx "$TX_HASH" \
--node "$COSMOS_HUB_NODE" \
--output json | jq -r '.logs[0].events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
echo -e "${GREEN}✓ Stored ${label} with code ID: ${CODE_ID}${NC}"
echo "$CODE_ID"
}
# Function to instantiate contract
instantiate_contract() {
local code_id=$1
local init_msg=$2
local label=$3
echo -e "${GREEN}Instantiating: ${label}${NC}"
TX_HASH=$(gaiad tx wasm instantiate "$code_id" "$init_msg" \
--from "$DEPLOYER" \
--label "$label" \
--chain-id "$COSMOS_HUB_CHAIN_ID" \
--node "$COSMOS_HUB_NODE" \
--gas-prices "$GAS_PRICES" \
--gas auto \
--gas-adjustment 1.5 \
--admin "$DEPLOYER" \
--broadcast-mode sync \
--yes \
--output json | jq -r '.txhash')
echo "Waiting for transaction..."
sleep 6
CONTRACT_ADDR=$(gaiad query tx "$TX_HASH" \
--node "$COSMOS_HUB_NODE" \
--output json | jq -r '.logs[0].events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value')
echo -e "${GREEN}✓ Instantiated ${label} at: ${CONTRACT_ADDR}${NC}"
echo "$CONTRACT_ADDR"
}
# Check prerequisites
echo -e "${BLUE}Checking prerequisites...${NC}"
if ! command -v gaiad &>/dev/null; then
echo -e "${RED}Error: gaiad not found. Please install Gaia (Cosmos Hub client)${NC}"
exit 1
fi
if ! command -v hermes &>/dev/null; then
echo -e "${RED}Error: hermes not found. Please install Hermes IBC relayer${NC}"
exit 1
fi
# Build contracts if needed
if [ ! -d "$CONTRACTS_DIR" ]; then
echo -e "${BLUE}Building contracts...${NC}"
cd ..
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer:0.13.0
cd scripts
fi
# Store contract codes
echo -e "${BLUE}Storing contract codes on Cosmos Hub...${NC}"
CORE_CODE_ID=$(store_contract "$CONTRACTS_DIR/identity_dao_core.wasm" "Identity DAO Core")
VOTING_CODE_ID=$(store_contract "$CONTRACTS_DIR/did_voting.wasm" "DID-Based Voting")
PROPOSALS_CODE_ID=$(store_contract "$CONTRACTS_DIR/identity_proposals.wasm" "Identity Proposals")
PRE_PROPOSE_CODE_ID=$(store_contract "$CONTRACTS_DIR/pre_propose_identity.wasm" "Pre-Propose Identity")
# Instantiate contracts
echo -e "${BLUE}Instantiating contracts...${NC}"
# Core module
CORE_INIT='{
"admin": "'$DEPLOYER'",
"dao_name": "Sonr Identity DAO",
"dao_uri": "https://sonr.io/dao",
"voting_module": null,
"proposal_modules": [],
"wyoming_dao_info": {
"entity_name": "Sonr Identity DAO LLC",
"entity_type": "LLC",
"registered_agent": "Wyoming Registered Agent LLC",
"ein": "00-0000000"
}
}'
CORE_ADDR=$(instantiate_contract "$CORE_CODE_ID" "$CORE_INIT" "identity-dao-core")
# Voting module
VOTING_INIT='{
"dao_core": "'$CORE_ADDR'",
"min_verification_level": 1,
"use_reputation_weight": true
}'
VOTING_ADDR=$(instantiate_contract "$VOTING_CODE_ID" "$VOTING_INIT" "did-voting")
# Proposals module
PROPOSALS_INIT='{
"dao_core": "'$CORE_ADDR'",
"voting_module": "'$VOTING_ADDR'",
"min_voting_period": 86400,
"max_voting_period": 604800,
"pass_threshold": {"absolute_percentage": {"percentage": "0.5"}},
"min_verification_level": 1
}'
PROPOSALS_ADDR=$(instantiate_contract "$PROPOSALS_CODE_ID" "$PROPOSALS_INIT" "identity-proposals")
# Pre-propose module
PRE_PROPOSE_INIT='{
"dao_core": "'$CORE_ADDR'",
"proposal_module": "'$PROPOSALS_ADDR'",
"deposit_amount": "1000000",
"deposit_denom": "uatom",
"min_verification_level": 1,
"admin_approval_required": false
}'
PRE_PROPOSE_ADDR=$(instantiate_contract "$PRE_PROPOSE_CODE_ID" "$PRE_PROPOSE_INIT" "pre-propose-identity")
# Update core configuration
echo -e "${BLUE}Updating core configuration...${NC}"
UPDATE_MSG='{
"update_config": {
"voting_module": "'$VOTING_ADDR'",
"proposal_modules": ["'$PROPOSALS_ADDR'"]
}
}'
gaiad tx wasm execute "$CORE_ADDR" "$UPDATE_MSG" \
--from "$DEPLOYER" \
--chain-id "$COSMOS_HUB_CHAIN_ID" \
--node "$COSMOS_HUB_NODE" \
--gas-prices "$GAS_PRICES" \
--gas auto \
--gas-adjustment 1.5 \
--yes
echo -e "${GREEN}✓ Core configuration updated${NC}"
# Setup IBC channels
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Setting up IBC Channels${NC}"
echo -e "${BLUE}========================================${NC}"
# Create Hermes config if not exists
HERMES_CONFIG="$HOME/.hermes/config.toml"
if [ ! -f "$HERMES_CONFIG" ]; then
echo -e "${BLUE}Creating Hermes configuration...${NC}"
mkdir -p "$HOME/.hermes"
cat >"$HERMES_CONFIG" <<EOF
[global]
log_level = 'info'
[mode.clients]
enabled = true
refresh = true
misbehaviour = true
[mode.connections]
enabled = true
[mode.channels]
enabled = true
[mode.packets]
enabled = true
clear_interval = 100
clear_on_start = true
tx_confirmation = true
[[chains]]
id = '$COSMOS_HUB_CHAIN_ID'
type = 'CosmosSdk'
rpc_addr = '$COSMOS_HUB_NODE'
grpc_addr = 'http://localhost:9090'
websocket_addr = 'ws://localhost:26657/websocket'
rpc_timeout = '15s'
account_prefix = 'cosmos'
key_name = 'relayer-cosmos'
store_prefix = 'ibc'
gas_price = { price = 0.025, denom = 'uatom' }
gas_multiplier = 1.5
max_gas = 10000000
clock_drift = '15s'
trusting_period = '14days'
trust_threshold = { numerator = '2', denominator = '3' }
[[chains]]
id = '$SONR_CHAIN_ID'
type = 'CosmosSdk'
rpc_addr = '$SONR_NODE'
grpc_addr = 'http://localhost:9091'
websocket_addr = 'ws://localhost:26658/websocket'
rpc_timeout = '15s'
account_prefix = 'sonr'
key_name = 'relayer-sonr'
store_prefix = 'ibc'
gas_price = { price = 0.025, denom = 'usnr' }
gas_multiplier = 1.5
max_gas = 10000000
clock_drift = '15s'
trusting_period = '14days'
trust_threshold = { numerator = '2', denominator = '3' }
EOF
fi
# Add relayer keys
echo -e "${BLUE}Setting up relayer keys...${NC}"
# Export deployer key from both chains (you'll need to have these)
gaiad keys export "$DEPLOYER" 2>/dev/null | hermes keys add --chain "$COSMOS_HUB_CHAIN_ID" --key-file /dev/stdin || true
snrd keys export "$DEPLOYER" 2>/dev/null | hermes keys add --chain "$SONR_CHAIN_ID" --key-file /dev/stdin || true
# Create IBC connection
echo -e "${BLUE}Creating IBC connection...${NC}"
CONNECTION_RESULT=$(hermes create connection \
--a-chain "$COSMOS_HUB_CHAIN_ID" \
--b-chain "$SONR_CHAIN_ID")
CONNECTION_ID=$(echo "$CONNECTION_RESULT" | grep -oP 'connection-\d+' | head -1)
echo -e "${GREEN}✓ Created IBC connection: ${CONNECTION_ID}${NC}"
# Create channels for each contract
echo -e "${BLUE}Creating IBC channels for contracts...${NC}"
# Channel for voting module
VOTING_CHANNEL=$(hermes create channel \
--a-chain "$COSMOS_HUB_CHAIN_ID" \
--a-connection "$CONNECTION_ID" \
--a-port "wasm.$VOTING_ADDR" \
--b-port "did" \
--order unordered \
--version "identity-dao-1" | grep -oP 'channel-\d+' | head -1)
echo -e "${GREEN}✓ Created voting channel: ${VOTING_CHANNEL}${NC}"
# Channel for proposals module
PROPOSALS_CHANNEL=$(hermes create channel \
--a-chain "$COSMOS_HUB_CHAIN_ID" \
--a-connection "$CONNECTION_ID" \
--a-port "wasm.$PROPOSALS_ADDR" \
--b-port "dwn" \
--order unordered \
--version "identity-dao-1" | grep -oP 'channel-\d+' | head -1)
echo -e "${GREEN}✓ Created proposals channel: ${PROPOSALS_CHANNEL}${NC}"
# Start the relayer
echo -e "${BLUE}Starting IBC relayer...${NC}"
hermes start &
RELAYER_PID=$!
echo -e "${GREEN}✓ IBC relayer started with PID: ${RELAYER_PID}${NC}"
# Save deployment information
DEPLOYMENT_FILE="cosmos-hub-deployment.json"
cat >"$DEPLOYMENT_FILE" <<EOF
{
"chain_id": "$COSMOS_HUB_CHAIN_ID",
"deployment_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"contracts": {
"core": {
"code_id": $CORE_CODE_ID,
"address": "$CORE_ADDR"
},
"voting": {
"code_id": $VOTING_CODE_ID,
"address": "$VOTING_ADDR",
"ibc_channel": "$VOTING_CHANNEL"
},
"proposals": {
"code_id": $PROPOSALS_CODE_ID,
"address": "$PROPOSALS_ADDR",
"ibc_channel": "$PROPOSALS_CHANNEL"
},
"pre_propose": {
"code_id": $PRE_PROPOSE_CODE_ID,
"address": "$PRE_PROPOSE_ADDR"
}
},
"ibc": {
"connection_id": "$CONNECTION_ID",
"relayer_pid": $RELAYER_PID
}
}
EOF
echo -e "${BLUE}========================================${NC}"
echo -e "${GREEN}✓ Deployment Complete!${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo "Deployment information saved to: $DEPLOYMENT_FILE"
echo ""
echo "Contract Addresses:"
echo " Core: $CORE_ADDR"
echo " Voting: $VOTING_ADDR"
echo " Proposals: $PROPOSALS_ADDR"
echo " Pre-Propose: $PRE_PROPOSE_ADDR"
echo ""
echo "IBC Channels:"
echo " Voting: $VOTING_CHANNEL"
echo " Proposals: $PROPOSALS_CHANNEL"
echo ""
echo "Relayer PID: $RELAYER_PID"
echo ""
echo "To stop the relayer: kill $RELAYER_PID"
echo ""
echo "Next steps:"
echo "1. Verify IBC channels are active: hermes query channels --chain $COSMOS_HUB_CHAIN_ID"
echo "2. Test DID verification: gaiad tx wasm execute $VOTING_ADDR '{\"update_voter\":{\"did\":\"did:sonr:test\",\"address\":\"cosmos1...\"}}'"
echo "3. Create a test proposal through the pre-propose module"
+301
View File
@@ -0,0 +1,301 @@
#!/bin/bash
# Identity DAO Deployment Script
# Deploys all Identity DAO contracts to Sonr testnet
set -e
# Configuration
CHAIN_ID="${CHAIN_ID:-sonrtest_1-1}"
NODE="${NODE:-http://localhost:26657}"
KEYRING="${KEYRING:-test}"
DEPLOYER="${DEPLOYER:-deployer}"
GAS_PRICES="${GAS_PRICES:-0.025usnr}"
GAS_ADJUSTMENT="${GAS_ADJUSTMENT:-1.5}"
# Contract paths
CONTRACTS_DIR="$(dirname "$0")/../artifacts"
SHARED_WASM="${CONTRACTS_DIR}/identity_dao_shared.wasm"
CORE_WASM="${CONTRACTS_DIR}/identity_dao_core.wasm"
VOTING_WASM="${CONTRACTS_DIR}/identity_dao_voting.wasm"
PROPOSALS_WASM="${CONTRACTS_DIR}/identity_dao_proposals.wasm"
PRE_PROPOSE_WASM="${CONTRACTS_DIR}/identity_dao_pre_propose.wasm"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Check dependencies
check_dependencies() {
log_info "Checking dependencies..."
if ! command -v snrd &> /dev/null; then
log_error "snrd is not installed. Please run 'make install'"
exit 1
fi
if ! command -v jq &> /dev/null; then
log_error "jq is not installed. Please install jq"
exit 1
fi
log_info "All dependencies satisfied"
}
# Build contracts
build_contracts() {
log_info "Building Identity DAO contracts..."
cd "$(dirname "$0")/.."
# Build with optimizer
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer:0.13.0
# Move artifacts
mkdir -p artifacts
mv artifacts/*.wasm artifacts/ 2>/dev/null || true
log_info "Contracts built successfully"
}
# Store contract code
store_contract() {
local wasm_file=$1
local contract_name=$2
log_info "Storing $contract_name contract..."
if [ ! -f "$wasm_file" ]; then
log_error "Contract file not found: $wasm_file"
exit 1
fi
local tx_result=$(snrd tx wasm store "$wasm_file" \
--from "$DEPLOYER" \
--chain-id "$CHAIN_ID" \
--node "$NODE" \
--gas-prices "$GAS_PRICES" \
--gas-adjustment "$GAS_ADJUSTMENT" \
--keyring-backend "$KEYRING" \
--output json \
--yes)
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
# Wait for transaction
sleep 6
# Get code ID from events
local code_id=$(snrd query tx "$tx_hash" \
--node "$NODE" \
--output json | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
if [ -z "$code_id" ]; then
log_error "Failed to get code ID for $contract_name"
exit 1
fi
log_info "$contract_name stored with code ID: $code_id"
echo "$code_id"
}
# Instantiate contract
instantiate_contract() {
local code_id=$1
local init_msg=$2
local label=$3
local admin=${4:-$DEPLOYER}
log_info "Instantiating contract: $label"
local tx_result=$(snrd tx wasm instantiate "$code_id" "$init_msg" \
--from "$DEPLOYER" \
--label "$label" \
--admin "$admin" \
--chain-id "$CHAIN_ID" \
--node "$NODE" \
--gas-prices "$GAS_PRICES" \
--gas-adjustment "$GAS_ADJUSTMENT" \
--keyring-backend "$KEYRING" \
--output json \
--yes)
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
# Wait for transaction
sleep 6
# Get contract address from events
local contract_addr=$(snrd query tx "$tx_hash" \
--node "$NODE" \
--output json | jq -r '.events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value')
if [ -z "$contract_addr" ]; then
log_error "Failed to get contract address for $label"
exit 1
fi
log_info "$label instantiated at: $contract_addr"
echo "$contract_addr"
}
# Main deployment flow
main() {
log_info "Starting Identity DAO deployment..."
# Check dependencies
check_dependencies
# Build contracts if artifacts don't exist
if [ ! -d "$CONTRACTS_DIR" ] || [ -z "$(ls -A $CONTRACTS_DIR/*.wasm 2>/dev/null)" ]; then
build_contracts
else
log_info "Using existing contract artifacts"
fi
# Store contract codes
log_info "Storing contract codes on chain..."
CORE_CODE_ID=$(store_contract "$CORE_WASM" "Identity DAO Core")
VOTING_CODE_ID=$(store_contract "$VOTING_WASM" "DID-Based Voting")
PROPOSALS_CODE_ID=$(store_contract "$PROPOSALS_WASM" "Identity Proposals")
PRE_PROPOSE_CODE_ID=$(store_contract "$PRE_PROPOSE_WASM" "Pre-Propose Identity")
# Save code IDs
cat > "${CONTRACTS_DIR}/code_ids.json" <<EOF
{
"core": $CORE_CODE_ID,
"voting": $VOTING_CODE_ID,
"proposals": $PROPOSALS_CODE_ID,
"pre_propose": $PRE_PROPOSE_CODE_ID
}
EOF
log_info "Contract codes stored. Code IDs saved to code_ids.json"
# Instantiate Core Module first
log_info "Instantiating Identity DAO Core Module..."
CORE_INIT_MSG=$(cat <<EOF
{
"admin": "$DEPLOYER",
"dao_name": "Sonr Identity DAO",
"dao_uri": "https://sonr.io/dao",
"voting_module": null,
"proposal_modules": []
}
EOF
)
CORE_ADDR=$(instantiate_contract "$CORE_CODE_ID" "$CORE_INIT_MSG" "identity-dao-core" "$DEPLOYER")
# Instantiate Voting Module
log_info "Instantiating DID-Based Voting Module..."
VOTING_INIT_MSG=$(cat <<EOF
{
"dao_address": "$CORE_ADDR",
"min_verification_level": 1,
"voting_period": 604800,
"quorum_percentage": 20,
"threshold_percentage": 51
}
EOF
)
VOTING_ADDR=$(instantiate_contract "$VOTING_CODE_ID" "$VOTING_INIT_MSG" "did-voting" "$CORE_ADDR")
# Instantiate Pre-Propose Module
log_info "Instantiating Pre-Propose Identity Module..."
PRE_PROPOSE_INIT_MSG=$(cat <<EOF
{
"proposal_module": null,
"min_verification_status": "Basic",
"deposit_amount": "1000000",
"deposit_denom": "usnr"
}
EOF
)
PRE_PROPOSE_ADDR=$(instantiate_contract "$PRE_PROPOSE_CODE_ID" "$PRE_PROPOSE_INIT_MSG" "pre-propose-identity" "$CORE_ADDR")
# Instantiate Proposals Module
log_info "Instantiating Identity Proposals Module..."
PROPOSALS_INIT_MSG=$(cat <<EOF
{
"dao_address": "$CORE_ADDR",
"voting_module": "$VOTING_ADDR",
"pre_propose_module": "$PRE_PROPOSE_ADDR",
"proposal_duration": 604800,
"min_verification_level": 1
}
EOF
)
PROPOSALS_ADDR=$(instantiate_contract "$PROPOSALS_CODE_ID" "$PROPOSALS_INIT_MSG" "identity-proposals" "$CORE_ADDR")
# Update Core Module with voting and proposal modules
log_info "Updating Core Module configuration..."
UPDATE_MSG=$(cat <<EOF
{
"update_config": {
"voting_module": "$VOTING_ADDR",
"proposal_modules": ["$PROPOSALS_ADDR"]
}
}
EOF
)
snrd tx wasm execute "$CORE_ADDR" "$UPDATE_MSG" \
--from "$DEPLOYER" \
--chain-id "$CHAIN_ID" \
--node "$NODE" \
--gas-prices "$GAS_PRICES" \
--gas-adjustment "$GAS_ADJUSTMENT" \
--keyring-backend "$KEYRING" \
--yes
# Save deployment addresses
cat > "${CONTRACTS_DIR}/addresses.json" <<EOF
{
"core": "$CORE_ADDR",
"voting": "$VOTING_ADDR",
"proposals": "$PROPOSALS_ADDR",
"pre_propose": "$PRE_PROPOSE_ADDR",
"deployer": "$DEPLOYER",
"chain_id": "$CHAIN_ID",
"deployment_time": "$(date -u +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
log_info "Deployment complete! Contract addresses saved to addresses.json"
log_info ""
log_info "Contract Addresses:"
log_info " Core: $CORE_ADDR"
log_info " Voting: $VOTING_ADDR"
log_info " Proposals: $PROPOSALS_ADDR"
log_info " Pre-Propose: $PRE_PROPOSE_ADDR"
}
# Run main function
main "$@"
+365
View File
@@ -0,0 +1,365 @@
#!/bin/bash
# Deploy Identity DAO Contracts to Cosmos Hub Mainnet
# PRODUCTION DEPLOYMENT - USE WITH CAUTION
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_critical() {
echo -e "${MAGENTA}[CRITICAL]${NC} $1"
}
# Configuration
CHAIN_ID="cosmoshub-4" # Cosmos Hub mainnet chain ID
NODE="https://cosmos-rpc.polkachu.com:443"
BACKUP_NODE="https://rpc-cosmoshub.blockapsis.com:443"
GAS_PRICES="0.025uatom"
GAS_AUTO="--gas auto --gas-adjustment 1.5"
KEYRING="--keyring-backend file" # Use file backend for mainnet
# Contract paths
CONTRACTS_DIR="$(dirname "$0")/../artifacts"
CORE_WASM="${CONTRACTS_DIR}/identity_dao_core.wasm"
VOTING_WASM="${CONTRACTS_DIR}/identity_dao_voting.wasm"
PROPOSALS_WASM="${CONTRACTS_DIR}/identity_dao_proposals.wasm"
PRE_PROPOSE_WASM="${CONTRACTS_DIR}/identity_dao_pre_propose.wasm"
# Sonr mainnet configuration for IBC
SONR_CHAIN_ID="sonr-1" # Sonr mainnet chain ID
SONR_NODE="https://rpc.sonr.io:443"
IBC_VERSION="ics20-1"
# Security checks
MAINNET_CONFIRMATION="I_UNDERSTAND_THIS_IS_MAINNET_DEPLOYMENT"
MULTISIG_THRESHOLD=3
REQUIRED_SIGNATURES=2
# Deployment configuration
MIN_BALANCE_ATOM=50 # Minimum ATOM balance required
PROPOSAL_DEPOSIT="10000000" # 10 ATOM proposal deposit
VOTING_PERIOD=1209600 # 14 days in seconds
QUORUM="0.334" # 33.4% quorum
THRESHOLD="0.5" # 50% threshold
# Pre-deployment checks
pre_deployment_checks() {
log_critical "=== MAINNET DEPLOYMENT PRE-CHECKS ==="
# Confirm mainnet deployment
echo -e "${RED}WARNING: You are about to deploy to Cosmos Hub MAINNET${NC}"
echo -e "${RED}This is a production deployment that will use real ATOM tokens${NC}"
echo ""
read -p "Type '${MAINNET_CONFIRMATION}' to continue: " confirmation
if [ "$confirmation" != "$MAINNET_CONFIRMATION" ]; then
log_error "Mainnet deployment cancelled"
exit 1
fi
log_info "Mainnet deployment confirmed"
}
# Check multisig setup
check_multisig() {
log_info "Checking multisig configuration..."
# Check if multisig account exists
MULTISIG_NAME="identity-dao-multisig"
if ! gaiad keys show "${MULTISIG_NAME}" ${KEYRING} &> /dev/null; then
log_error "Multisig account not found. Please create it first:"
echo "gaiad keys add ${MULTISIG_NAME} --multisig key1,key2,key3 --multisig-threshold ${REQUIRED_SIGNATURES}"
exit 1
fi
MULTISIG_ADDR=$(gaiad keys show "${MULTISIG_NAME}" -a ${KEYRING})
log_info "Multisig address: ${MULTISIG_ADDR}"
# Check multisig balance
BALANCE=$(gaiad query bank balances "${MULTISIG_ADDR}" \
--node "${NODE}" \
--output json | jq -r '.balances[] | select(.denom=="uatom") | .amount')
BALANCE_ATOM=$((BALANCE / 1000000))
if [ "$BALANCE_ATOM" -lt "$MIN_BALANCE_ATOM" ]; then
log_error "Insufficient balance: ${BALANCE_ATOM} ATOM (required: ${MIN_BALANCE_ATOM} ATOM)"
exit 1
fi
log_info "Multisig balance: ${BALANCE_ATOM} ATOM"
}
# Verify contracts
verify_contracts() {
log_info "Verifying contract checksums..."
if [ ! -f "${CONTRACTS_DIR}/checksums.txt" ]; then
log_error "Checksums file not found"
exit 1
fi
# Verify each contract
cd "${CONTRACTS_DIR}"
if command -v sha256sum &> /dev/null; then
sha256sum -c checksums.txt
else
shasum -a 256 -c checksums.txt
fi
if [ $? -eq 0 ]; then
log_info "All contract checksums verified"
else
log_error "Contract checksum verification failed"
exit 1
fi
cd - > /dev/null
}
# Backup current state
create_backup() {
log_info "Creating deployment backup..."
BACKUP_DIR="backups/mainnet_$(date +%Y%m%d_%H%M%S)"
mkdir -p "${BACKUP_DIR}"
# Copy contracts
cp -r "${CONTRACTS_DIR}" "${BACKUP_DIR}/"
# Save deployment configuration
cat > "${BACKUP_DIR}/deployment_config.json" << EOF
{
"chain_id": "${CHAIN_ID}",
"node": "${NODE}",
"multisig_addr": "${MULTISIG_ADDR}",
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"contracts": {
"core": "${CORE_WASM}",
"voting": "${VOTING_WASM}",
"proposals": "${PROPOSALS_WASM}",
"pre_propose": "${PRE_PROPOSE_WASM}"
},
"config": {
"proposal_deposit": "${PROPOSAL_DEPOSIT}",
"voting_period": ${VOTING_PERIOD},
"quorum": "${QUORUM}",
"threshold": "${THRESHOLD}"
}
}
EOF
log_info "Backup created at ${BACKUP_DIR}"
}
# Generate multisig transaction
generate_multisig_tx() {
local msg=$1
local output_file=$2
local description=$3
log_info "Generating multisig transaction: ${description}"
# Generate unsigned transaction
gaiad tx wasm $msg \
--from "${MULTISIG_NAME}" \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
--generate-only > "${output_file}"
log_info "Unsigned transaction saved to ${output_file}"
}
# Upload contract with multisig
upload_contract_multisig() {
local wasm_file=$1
local contract_name=$2
log_info "Preparing ${contract_name} upload..."
# Generate store transaction
TX_FILE="tx_store_${contract_name}.json"
generate_multisig_tx \
"store ${wasm_file}" \
"${TX_FILE}" \
"Store ${contract_name}"
log_info "${contract_name} upload transaction prepared"
log_warning "Requires multisig signatures before broadcasting"
echo "${TX_FILE}"
}
# Main deployment flow
main() {
log_critical "Starting Identity DAO MAINNET deployment..."
# Pre-deployment checks
pre_deployment_checks
# Check multisig setup
check_multisig
# Verify contracts
verify_contracts
# Create backup
create_backup
# Prepare upload transactions
log_info "Preparing contract upload transactions..."
CORE_TX=$(upload_contract_multisig "${CORE_WASM}" "Identity DAO Core")
VOTING_TX=$(upload_contract_multisig "${VOTING_WASM}" "DID Voting")
PROPOSALS_TX=$(upload_contract_multisig "${PROPOSALS_WASM}" "Proposals")
PRE_PROPOSE_TX=$(upload_contract_multisig "${PRE_PROPOSE_WASM}" "Pre-Propose")
# Generate instantiation messages
log_info "Generating instantiation messages..."
CORE_INIT_MSG='{
"name": "Sonr Identity DAO",
"description": "Decentralized Identity Governance on Cosmos Hub",
"voting_config": {
"threshold": "'${THRESHOLD}'",
"quorum": "'${QUORUM}'",
"voting_period": '${VOTING_PERIOD}',
"proposal_deposit": "'${PROPOSAL_DEPOSIT}'"
},
"admin": "'${MULTISIG_ADDR}'",
"enable_did_integration": true
}'
echo "$CORE_INIT_MSG" > init_core.json
# Save deployment instructions
cat > MAINNET_DEPLOYMENT_INSTRUCTIONS.md << EOF
# Cosmos Hub Mainnet Deployment Instructions
## Prerequisites
- Multisig address: ${MULTISIG_ADDR}
- Required signatures: ${REQUIRED_SIGNATURES} of ${MULTISIG_THRESHOLD}
- Chain ID: ${CHAIN_ID}
## Step 1: Sign Upload Transactions
Each signer must sign the upload transactions:
\`\`\`bash
# Sign Core contract upload
gaiad tx sign ${CORE_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_core_<signer>.json
# Sign Voting contract upload
gaiad tx sign ${VOTING_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_voting_<signer>.json
# Sign Proposals contract upload
gaiad tx sign ${PROPOSALS_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_proposals_<signer>.json
# Sign Pre-Propose contract upload
gaiad tx sign ${PRE_PROPOSE_TX} --from <signer_key> --chain-id ${CHAIN_ID} ${KEYRING} > signed_pre_propose_<signer>.json
\`\`\`
## Step 2: Combine Signatures
\`\`\`bash
# Combine Core signatures
gaiad tx multisign ${CORE_TX} ${MULTISIG_NAME} signed_core_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_core_signed.json
# Combine Voting signatures
gaiad tx multisign ${VOTING_TX} ${MULTISIG_NAME} signed_voting_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_voting_signed.json
# Combine Proposals signatures
gaiad tx multisign ${PROPOSALS_TX} ${MULTISIG_NAME} signed_proposals_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_proposals_signed.json
# Combine Pre-Propose signatures
gaiad tx multisign ${PRE_PROPOSE_TX} ${MULTISIG_NAME} signed_pre_propose_*.json --chain-id ${CHAIN_ID} ${KEYRING} > tx_pre_propose_signed.json
\`\`\`
## Step 3: Broadcast Transactions
\`\`\`bash
# Broadcast uploads (one at a time)
gaiad tx broadcast tx_core_signed.json --node ${NODE}
# Wait for confirmation and note CODE_ID
gaiad tx broadcast tx_voting_signed.json --node ${NODE}
# Wait for confirmation and note CODE_ID
gaiad tx broadcast tx_proposals_signed.json --node ${NODE}
# Wait for confirmation and note CODE_ID
gaiad tx broadcast tx_pre_propose_signed.json --node ${NODE}
# Wait for confirmation and note CODE_ID
\`\`\`
## Step 4: Instantiate Contracts
After obtaining code IDs, instantiate each contract following the same multisig process.
## Step 5: Verify Deployment
Run verification script:
\`\`\`bash
./scripts/verify_deployment.sh
\`\`\`
## Security Checklist
- [ ] All signers have verified contract checksums
- [ ] Multisig threshold is correctly configured
- [ ] Admin keys are securely stored
- [ ] Backup of deployment configuration created
- [ ] IBC channels will be established post-deployment
- [ ] Emergency procedures documented
## Emergency Contacts
- Technical Lead: [Contact]
- Security Team: [Contact]
- Multisig Signers: [List]
---
Generated: $(date)
EOF
log_info "✅ Mainnet deployment preparation complete!"
log_info ""
log_critical "=== IMPORTANT NEXT STEPS ==="
echo "1. Review MAINNET_DEPLOYMENT_INSTRUCTIONS.md"
echo "2. Coordinate with multisig signers"
echo "3. Execute deployment following the instructions"
echo "4. Verify deployment using verify_deployment.sh"
echo "5. Establish IBC channels to Sonr mainnet"
echo ""
log_warning "All unsigned transactions saved to current directory"
log_warning "DO NOT share private keys or signed transactions insecurely"
}
# Run main deployment
main "$@"
+357
View File
@@ -0,0 +1,357 @@
#!/bin/bash
# Deploy Identity DAO Contracts to Cosmos Hub Testnet
# This script handles the deployment of all DAO contracts and IBC setup
set -e
# Configuration
CHAIN_ID="theta-testnet-001" # Cosmos Hub testnet chain ID
NODE="https://rpc.sentry-01.theta-testnet.polypore.xyz"
GAS_PRICES="0.025uatom"
GAS_AUTO="--gas auto --gas-adjustment 1.3"
KEYRING="--keyring-backend test"
# Contract paths
CONTRACTS_DIR="$(dirname "$0")/../target/wasm32-unknown-unknown/release"
CORE_WASM="${CONTRACTS_DIR}/identity_dao_core.wasm"
VOTING_WASM="${CONTRACTS_DIR}/identity_dao_voting.wasm"
PROPOSALS_WASM="${CONTRACTS_DIR}/identity_dao_proposals.wasm"
PRE_PROPOSE_WASM="${CONTRACTS_DIR}/identity_dao_pre_propose.wasm"
# Sonr chain configuration for IBC
SONR_CHAIN_ID="sonrtest_1-1"
SONR_NODE="http://localhost:26657"
IBC_VERSION="ics20-1"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Check if gaiad is installed
check_gaiad() {
if ! command -v gaiad &> /dev/null; then
log_error "gaiad is not installed. Please install Cosmos Hub client."
exit 1
fi
log_info "Found gaiad: $(gaiad version)"
}
# Check if contracts are built
check_contracts() {
log_info "Checking for compiled contracts..."
if [ ! -f "$CORE_WASM" ]; then
log_error "Core contract not found at $CORE_WASM"
log_info "Building contracts..."
cd "$(dirname "$0")/.."
cargo build --release --target wasm32-unknown-unknown
fi
log_info "All contracts found"
}
# Optimize contracts for deployment
optimize_contracts() {
log_info "Optimizing contracts for deployment..."
# Use CosmWasm optimizer
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/optimizer:0.16.0
log_info "Contract optimization complete"
}
# Upload contract to chain
upload_contract() {
local wasm_file=$1
local contract_name=$2
log_info "Uploading ${contract_name} contract..."
TX_HASH=$(gaiad tx wasm store "${wasm_file}" \
--from deployer \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
--broadcast-mode sync \
--output json \
-y | jq -r '.txhash')
log_info "Transaction submitted: ${TX_HASH}"
sleep 6
# Get code ID from transaction
CODE_ID=$(gaiad query tx "${TX_HASH}" \
--node "${NODE}" \
--output json | jq -r '.logs[0].events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
log_info "${contract_name} uploaded with code ID: ${CODE_ID}"
echo "${CODE_ID}"
}
# Instantiate contract
instantiate_contract() {
local code_id=$1
local init_msg=$2
local label=$3
local admin=$4
log_info "Instantiating ${label}..."
TX_HASH=$(gaiad tx wasm instantiate "${code_id}" "${init_msg}" \
--from deployer \
--label "${label}" \
--admin "${admin}" \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
--broadcast-mode sync \
--output json \
-y | jq -r '.txhash')
log_info "Transaction submitted: ${TX_HASH}"
sleep 6
# Get contract address from transaction
CONTRACT_ADDR=$(gaiad query tx "${TX_HASH}" \
--node "${NODE}" \
--output json | jq -r '.logs[0].events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address") | .value')
log_info "${label} instantiated at: ${CONTRACT_ADDR}"
echo "${CONTRACT_ADDR}"
}
# Setup IBC channel
setup_ibc_channel() {
local contract_addr=$1
local port=$2
log_info "Setting up IBC channel for ${port}..."
# Create client for Sonr chain
gaiad tx ibc client create \
--chain-id "${CHAIN_ID}" \
--from deployer \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
sleep 6
# Create connection
gaiad tx ibc connection open-init \
--chain-id "${CHAIN_ID}" \
--from deployer \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
sleep 6
# Create channel
gaiad tx ibc channel open-init \
--port "${port}" \
--version "${IBC_VERSION}" \
--chain-id "${CHAIN_ID}" \
--from deployer \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
log_info "IBC channel setup initiated for ${port}"
}
# Main deployment flow
main() {
log_info "Starting Identity DAO deployment to Cosmos Hub testnet..."
# Prerequisites
check_gaiad
check_contracts
# Get deployer address
DEPLOYER_ADDR=$(gaiad keys show deployer -a ${KEYRING})
log_info "Deployer address: ${DEPLOYER_ADDR}"
# Check balance
BALANCE=$(gaiad query bank balances "${DEPLOYER_ADDR}" \
--node "${NODE}" \
--output json | jq -r '.balances[] | select(.denom=="uatom") | .amount')
if [ -z "$BALANCE" ] || [ "$BALANCE" -eq "0" ]; then
log_error "Deployer has no ATOM tokens. Please fund the account."
log_info "Visit https://discord.com/channels/669268347736686612/953641721746206780 for testnet faucet"
exit 1
fi
log_info "Deployer balance: ${BALANCE} uatom"
# Optimize contracts
optimize_contracts
# Upload contracts
log_info "Uploading contracts to chain..."
CORE_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_core-optimized.wasm" "Identity DAO Core")
VOTING_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_voting-optimized.wasm" "DID Voting")
PROPOSALS_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_proposals-optimized.wasm" "Proposals")
PRE_PROPOSE_CODE_ID=$(upload_contract "${CONTRACTS_DIR}/identity_dao_pre_propose-optimized.wasm" "Pre-Propose")
# Save code IDs
echo "CORE_CODE_ID=${CORE_CODE_ID}" > deployment_ids.env
echo "VOTING_CODE_ID=${VOTING_CODE_ID}" >> deployment_ids.env
echo "PROPOSALS_CODE_ID=${PROPOSALS_CODE_ID}" >> deployment_ids.env
echo "PRE_PROPOSE_CODE_ID=${PRE_PROPOSE_CODE_ID}" >> deployment_ids.env
# Instantiate Core contract
CORE_INIT_MSG='{
"name": "Sonr Identity DAO",
"description": "Decentralized Identity Governance on Cosmos Hub",
"voting_config": {
"threshold": "0.51",
"quorum": "0.1",
"voting_period": 604800,
"proposal_deposit": "1000000"
},
"admin": "'${DEPLOYER_ADDR}'",
"enable_did_integration": true
}'
CORE_ADDR=$(instantiate_contract "${CORE_CODE_ID}" "${CORE_INIT_MSG}" "sonr-identity-dao-core" "${DEPLOYER_ADDR}")
echo "CORE_ADDR=${CORE_ADDR}" >> deployment_ids.env
# Instantiate Voting contract
VOTING_INIT_MSG='{
"dao_core": "'${CORE_ADDR}'",
"min_verification_level": 1,
"use_reputation_weight": true
}'
VOTING_ADDR=$(instantiate_contract "${VOTING_CODE_ID}" "${VOTING_INIT_MSG}" "sonr-did-voting" "${CORE_ADDR}")
echo "VOTING_ADDR=${VOTING_ADDR}" >> deployment_ids.env
# Instantiate Proposals contract
PROPOSALS_INIT_MSG='{
"dao_core": "'${CORE_ADDR}'",
"voting_module": "'${VOTING_ADDR}'",
"pre_propose_module": null,
"proposal_deposit": "1000000",
"max_voting_period": 604800
}'
PROPOSALS_ADDR=$(instantiate_contract "${PROPOSALS_CODE_ID}" "${PROPOSALS_INIT_MSG}" "sonr-proposals" "${CORE_ADDR}")
echo "PROPOSALS_ADDR=${PROPOSALS_ADDR}" >> deployment_ids.env
# Instantiate Pre-Propose contract
PRE_PROPOSE_INIT_MSG='{
"dao_core": "'${CORE_ADDR}'",
"proposal_module": "'${PROPOSALS_ADDR}'",
"require_verified_did": true,
"min_reputation_score": 10,
"deposit_amount": "1000000",
"deposit_denom": "uatom"
}'
PRE_PROPOSE_ADDR=$(instantiate_contract "${PRE_PROPOSE_CODE_ID}" "${PRE_PROPOSE_INIT_MSG}" "sonr-pre-propose" "${CORE_ADDR}")
echo "PRE_PROPOSE_ADDR=${PRE_PROPOSE_ADDR}" >> deployment_ids.env
# Register modules with Core
log_info "Registering modules with Core contract..."
REGISTER_VOTING_MSG='{"register_module":{"module_type":"voting","module_address":"'${VOTING_ADDR}'"}}'
gaiad tx wasm execute "${CORE_ADDR}" "${REGISTER_VOTING_MSG}" \
--from deployer \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
sleep 6
REGISTER_PROPOSALS_MSG='{"register_module":{"module_type":"proposal","module_address":"'${PROPOSALS_ADDR}'"}}'
gaiad tx wasm execute "${CORE_ADDR}" "${REGISTER_PROPOSALS_MSG}" \
--from deployer \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
sleep 6
REGISTER_PRE_PROPOSE_MSG='{"register_module":{"module_type":"pre_propose","module_address":"'${PRE_PROPOSE_ADDR}'"}}'
gaiad tx wasm execute "${CORE_ADDR}" "${REGISTER_PRE_PROPOSE_MSG}" \
--from deployer \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
sleep 6
# Setup IBC channels for Sonr integration
log_info "Setting up IBC channels for Sonr integration..."
setup_ibc_channel "${VOTING_ADDR}" "wasm.${VOTING_ADDR}"
# Update Pre-Propose module in Proposals contract
UPDATE_PRE_PROPOSE_MSG='{"update_pre_propose_module":{"module":"'${PRE_PROPOSE_ADDR}'"}}'
gaiad tx wasm execute "${PROPOSALS_ADDR}" "${UPDATE_PRE_PROPOSE_MSG}" \
--from deployer \
--chain-id "${CHAIN_ID}" \
--node "${NODE}" \
--gas-prices "${GAS_PRICES}" \
${GAS_AUTO} \
${KEYRING} \
-y
log_info "✅ Deployment complete!"
log_info "Deployment details saved to deployment_ids.env"
# Display summary
echo ""
log_info "=== Deployment Summary ==="
echo "Core Contract: ${CORE_ADDR}"
echo "Voting Contract: ${VOTING_ADDR}"
echo "Proposals Contract: ${PROPOSALS_ADDR}"
echo "Pre-Propose Contract: ${PRE_PROPOSE_ADDR}"
echo ""
log_info "Next steps:"
echo "1. Verify contract deployment: ./scripts/verify_deployment.sh"
echo "2. Test IBC connectivity: ./scripts/test_ibc.sh"
echo "3. Create first proposal: ./scripts/create_proposal.sh"
}
# Run main deployment
main "$@"
+221
View File
@@ -0,0 +1,221 @@
#!/bin/bash
# Identity DAO Migration Script
# Migrates Identity DAO contracts to new versions
set -e
# Configuration
CHAIN_ID="${CHAIN_ID:-sonrtest_1-1}"
NODE="${NODE:-http://localhost:26657}"
KEYRING="${KEYRING:-test}"
ADMIN="${ADMIN:-deployer}"
GAS_PRICES="${GAS_PRICES:-0.025usnr}"
GAS_ADJUSTMENT="${GAS_ADJUSTMENT:-1.5}"
# Contract paths
CONTRACTS_DIR="$(dirname "$0")/../artifacts"
ADDRESSES_FILE="${CONTRACTS_DIR}/addresses.json"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Check dependencies
check_dependencies() {
log_info "Checking dependencies..."
if ! command -v snrd &> /dev/null; then
log_error "snrd is not installed. Please run 'make install'"
exit 1
fi
if ! command -v jq &> /dev/null; then
log_error "jq is not installed. Please install jq"
exit 1
fi
if [ ! -f "$ADDRESSES_FILE" ]; then
log_error "Contract addresses file not found. Please deploy first."
exit 1
fi
log_info "All dependencies satisfied"
}
# Store new contract code
store_new_code() {
local wasm_file=$1
local contract_name=$2
log_info "Storing new $contract_name contract code..."
if [ ! -f "$wasm_file" ]; then
log_error "Contract file not found: $wasm_file"
exit 1
fi
local tx_result=$(snrd tx wasm store "$wasm_file" \
--from "$ADMIN" \
--chain-id "$CHAIN_ID" \
--node "$NODE" \
--gas-prices "$GAS_PRICES" \
--gas-adjustment "$GAS_ADJUSTMENT" \
--keyring-backend "$KEYRING" \
--output json \
--yes)
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
# Wait for transaction
sleep 6
# Get code ID from events
local code_id=$(snrd query tx "$tx_hash" \
--node "$NODE" \
--output json | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value')
if [ -z "$code_id" ]; then
log_error "Failed to get code ID for $contract_name"
exit 1
fi
log_info "$contract_name new code stored with ID: $code_id"
echo "$code_id"
}
# Migrate contract
migrate_contract() {
local contract_addr=$1
local new_code_id=$2
local migrate_msg=$3
local contract_name=$4
log_info "Migrating $contract_name contract..."
local tx_result=$(snrd tx wasm migrate "$contract_addr" "$new_code_id" "$migrate_msg" \
--from "$ADMIN" \
--chain-id "$CHAIN_ID" \
--node "$NODE" \
--gas-prices "$GAS_PRICES" \
--gas-adjustment "$GAS_ADJUSTMENT" \
--keyring-backend "$KEYRING" \
--output json \
--yes)
local tx_hash=$(echo "$tx_result" | jq -r .txhash)
# Wait for transaction
sleep 6
# Check migration success
local tx_query=$(snrd query tx "$tx_hash" \
--node "$NODE" \
--output json)
local code=$(echo "$tx_query" | jq -r .code)
if [ "$code" != "0" ]; then
log_error "Migration failed for $contract_name"
echo "$tx_query" | jq -r .raw_log
exit 1
fi
log_info "$contract_name migrated successfully"
}
# Main migration flow
main() {
local MODULE=$1
log_info "Starting Identity DAO migration..."
# Check dependencies
check_dependencies
# Load contract addresses
CORE_ADDR=$(jq -r .core "$ADDRESSES_FILE")
VOTING_ADDR=$(jq -r .voting "$ADDRESSES_FILE")
PROPOSALS_ADDR=$(jq -r .proposals "$ADDRESSES_FILE")
PRE_PROPOSE_ADDR=$(jq -r .pre_propose "$ADDRESSES_FILE")
log_info "Loaded contract addresses from deployment"
# Migrate specific module or all
case "$MODULE" in
core)
log_info "Migrating Core Module..."
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_core.wasm" "Core")
MIGRATE_MSG='{"update_version":{}}'
migrate_contract "$CORE_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Core"
;;
voting)
log_info "Migrating Voting Module..."
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_voting.wasm" "Voting")
MIGRATE_MSG='{"update_version":{}}'
migrate_contract "$VOTING_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Voting"
;;
proposals)
log_info "Migrating Proposals Module..."
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_proposals.wasm" "Proposals")
MIGRATE_MSG='{"update_version":{}}'
migrate_contract "$PROPOSALS_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Proposals"
;;
pre-propose)
log_info "Migrating Pre-Propose Module..."
NEW_CODE_ID=$(store_new_code "${CONTRACTS_DIR}/identity_dao_pre_propose.wasm" "Pre-Propose")
MIGRATE_MSG='{"update_version":{}}'
migrate_contract "$PRE_PROPOSE_ADDR" "$NEW_CODE_ID" "$MIGRATE_MSG" "Pre-Propose"
;;
all)
log_info "Migrating all modules..."
# Store all new codes first
CORE_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_core.wasm" "Core")
VOTING_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_voting.wasm" "Voting")
PROPOSALS_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_proposals.wasm" "Proposals")
PRE_PROPOSE_NEW_CODE=$(store_new_code "${CONTRACTS_DIR}/identity_dao_pre_propose.wasm" "Pre-Propose")
# Migrate in order
MIGRATE_MSG='{"update_version":{}}'
migrate_contract "$CORE_ADDR" "$CORE_NEW_CODE" "$MIGRATE_MSG" "Core"
migrate_contract "$VOTING_ADDR" "$VOTING_NEW_CODE" "$MIGRATE_MSG" "Voting"
migrate_contract "$PRE_PROPOSE_ADDR" "$PRE_PROPOSE_NEW_CODE" "$MIGRATE_MSG" "Pre-Propose"
migrate_contract "$PROPOSALS_ADDR" "$PROPOSALS_NEW_CODE" "$MIGRATE_MSG" "Proposals"
;;
*)
log_error "Invalid module: $MODULE"
log_info "Usage: $0 [core|voting|proposals|pre-propose|all]"
exit 1
;;
esac
# Save migration info
cat > "${CONTRACTS_DIR}/migration_$(date +%Y%m%d_%H%M%S).json" <<EOF
{
"module": "$MODULE",
"migrated_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"admin": "$ADMIN",
"chain_id": "$CHAIN_ID"
}
EOF
log_info "Migration complete!"
}
# Run main function
main "$@"
+392
View File
@@ -0,0 +1,392 @@
#!/bin/bash
# Setup IBC channels between Cosmos Hub testnet and Sonr chain
# for Identity DAO cross-chain communication
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_debug() {
echo -e "${BLUE}[DEBUG]${NC} $1"
}
# Configuration
# Cosmos Hub testnet
HUB_CHAIN_ID="theta-testnet-001"
HUB_RPC="https://rpc.sentry-01.theta-testnet.polypore.xyz:443"
HUB_GRPC="grpc.sentry-01.theta-testnet.polypore.xyz:9090"
HUB_PREFIX="cosmos"
HUB_DENOM="uatom"
HUB_GAS_PRICES="0.025uatom"
# Sonr testnet
SONR_CHAIN_ID="sonrtest_1-1"
SONR_RPC="http://localhost:26657"
SONR_GRPC="localhost:9090"
SONR_PREFIX="sonr"
SONR_DENOM="usnr"
SONR_GAS_PRICES="0.025usnr"
# IBC Configuration
IBC_VERSION="ics20-1"
RELAYER_NAME="identity-dao-relayer"
RELAYER_HOME="${HOME}/.relayer"
PATH_NAME="hub-sonr"
# Contract ports (from deployment)
VOTING_PORT="wasm.cosmos1voting_contract_address" # Will be replaced with actual address
PROPOSALS_PORT="wasm.cosmos1proposals_contract_address"
# Check if Hermes relayer is installed
check_hermes() {
if ! command -v hermes &> /dev/null; then
log_error "Hermes relayer not found. Installing..."
# Install Hermes based on OS
if [[ "$OSTYPE" == "darwin"* ]]; then
brew install hermes
else
# Linux installation
curl -L https://github.com/informalsystems/hermes/releases/download/v1.8.0/hermes-v1.8.0-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv hermes /usr/local/bin/
fi
fi
log_info "Found Hermes: $(hermes version)"
}
# Initialize Hermes configuration
init_hermes_config() {
log_info "Initializing Hermes configuration..."
mkdir -p "${RELAYER_HOME}"
cat > "${RELAYER_HOME}/config.toml" << EOF
[global]
log_level = 'info'
[mode]
[mode.clients]
enabled = true
refresh = true
misbehaviour = true
[mode.connections]
enabled = true
[mode.channels]
enabled = true
[mode.packets]
enabled = true
clear_interval = 100
clear_on_start = true
tx_confirmation = true
[rest]
enabled = true
host = '127.0.0.1'
port = 3000
[telemetry]
enabled = false
host = '127.0.0.1'
port = 3001
# Cosmos Hub testnet configuration
[[chains]]
id = '${HUB_CHAIN_ID}'
type = 'CosmosSdk'
rpc_addr = '${HUB_RPC}'
grpc_addr = '${HUB_GRPC}'
event_source = { mode = 'push', url = '${HUB_RPC/https/wss}/websocket', batch_delay = '500ms' }
rpc_timeout = '10s'
account_prefix = '${HUB_PREFIX}'
key_name = 'hub-relayer'
store_prefix = 'ibc'
gas_price = { price = 0.025, denom = '${HUB_DENOM}' }
max_gas = 6000000
default_gas = 1000000
gas_multiplier = 1.2
max_msg_num = 30
max_tx_size = 2097152
clock_drift = '5s'
max_block_time = '30s'
memo_prefix = 'Identity DAO IBC'
trusting_period = '14days'
trust_threshold = { numerator = '1', denominator = '3' }
[chains.packet_filter]
policy = 'allow'
list = [
['wasm*', '*'], # Allow all CosmWasm IBC traffic
]
# Sonr testnet configuration
[[chains]]
id = '${SONR_CHAIN_ID}'
type = 'CosmosSdk'
rpc_addr = '${SONR_RPC}'
grpc_addr = '${SONR_GRPC}'
event_source = { mode = 'push', url = '${SONR_RPC/http/ws}/websocket', batch_delay = '500ms' }
rpc_timeout = '10s'
account_prefix = '${SONR_PREFIX}'
key_name = 'sonr-relayer'
store_prefix = 'ibc'
gas_price = { price = 0.025, denom = '${SONR_DENOM}' }
max_gas = 6000000
default_gas = 1000000
gas_multiplier = 1.2
max_msg_num = 30
max_tx_size = 2097152
clock_drift = '5s'
max_block_time = '30s'
memo_prefix = 'Identity DAO IBC'
trusting_period = '14days'
trust_threshold = { numerator = '1', denominator = '3' }
[chains.packet_filter]
policy = 'allow'
list = [
['transfer', 'channel-*'],
['wasm*', '*'],
]
EOF
log_info "Hermes config created at ${RELAYER_HOME}/config.toml"
}
# Add relayer keys
add_relayer_keys() {
log_info "Adding relayer keys..."
# Add Cosmos Hub key
log_info "Adding Cosmos Hub relayer key..."
hermes keys add \
--chain "${HUB_CHAIN_ID}" \
--mnemonic-file hub-relayer.mnemonic \
--key-name hub-relayer
# Add Sonr key
log_info "Adding Sonr relayer key..."
hermes keys add \
--chain "${SONR_CHAIN_ID}" \
--mnemonic-file sonr-relayer.mnemonic \
--key-name sonr-relayer
}
# Create IBC clients
create_clients() {
log_info "Creating IBC clients..."
# Create client on Cosmos Hub for Sonr
log_info "Creating Sonr client on Cosmos Hub..."
hermes create client \
--host-chain "${HUB_CHAIN_ID}" \
--reference-chain "${SONR_CHAIN_ID}"
# Create client on Sonr for Cosmos Hub
log_info "Creating Cosmos Hub client on Sonr..."
hermes create client \
--host-chain "${SONR_CHAIN_ID}" \
--reference-chain "${HUB_CHAIN_ID}"
}
# Create IBC connection
create_connection() {
log_info "Creating IBC connection..."
hermes create connection \
--a-chain "${HUB_CHAIN_ID}" \
--b-chain "${SONR_CHAIN_ID}"
}
# Create IBC channels for contracts
create_channels() {
log_info "Creating IBC channels for Identity DAO contracts..."
# Load deployed contract addresses
if [ -f "deployment_ids.env" ]; then
source deployment_ids.env
else
log_error "deployment_ids.env not found. Please deploy contracts first."
exit 1
fi
# Channel for Voting contract to query x/did module
log_info "Creating channel for Voting contract..."
hermes create channel \
--a-chain "${HUB_CHAIN_ID}" \
--a-port "wasm.${VOTING_ADDR}" \
--b-port "did" \
--order unordered \
--version "did-ibc-v1"
# Channel for Proposals contract
log_info "Creating channel for Proposals contract..."
hermes create channel \
--a-chain "${HUB_CHAIN_ID}" \
--a-port "wasm.${PROPOSALS_ADDR}" \
--b-port "dwn" \
--order unordered \
--version "dwn-ibc-v1"
# Standard transfer channel for treasury operations
log_info "Creating transfer channel..."
hermes create channel \
--a-chain "${HUB_CHAIN_ID}" \
--a-port "transfer" \
--b-port "transfer" \
--order unordered \
--version "${IBC_VERSION}"
}
# Start relayer
start_relayer() {
log_info "Starting Hermes relayer..."
# Start in background
hermes start &
RELAYER_PID=$!
log_info "Relayer started with PID: ${RELAYER_PID}"
echo "${RELAYER_PID}" > relayer.pid
# Give it time to establish connections
sleep 10
# Check if relayer is running
if ps -p ${RELAYER_PID} > /dev/null; then
log_info "Relayer is running successfully"
else
log_error "Relayer failed to start"
exit 1
fi
}
# Query IBC channels
query_channels() {
log_info "Querying established IBC channels..."
# Query channels on Cosmos Hub
log_info "Channels on Cosmos Hub:"
hermes query channels --chain "${HUB_CHAIN_ID}"
# Query channels on Sonr
log_info "Channels on Sonr:"
hermes query channels --chain "${SONR_CHAIN_ID}"
}
# Test IBC connectivity
test_ibc() {
log_info "Testing IBC connectivity..."
# Test transfer channel
log_info "Testing transfer channel..."
# Get channel IDs
TRANSFER_CHANNEL=$(hermes query channels --chain "${HUB_CHAIN_ID}" | grep transfer | head -1 | awk '{print $1}')
if [ -n "$TRANSFER_CHANNEL" ]; then
log_info "Transfer channel: ${TRANSFER_CHANNEL}"
# Send test transfer
gaiad tx ibc-transfer transfer \
transfer "${TRANSFER_CHANNEL}" \
sonr1test_address \
1000uatom \
--from hub-relayer \
--chain-id "${HUB_CHAIN_ID}" \
--node "${HUB_RPC}" \
--gas-prices "${HUB_GAS_PRICES}" \
--packet-timeout-height 0-1000 \
-y
log_info "Test transfer sent"
else
log_warning "No transfer channel found"
fi
}
# Monitor IBC packets
monitor_packets() {
log_info "Monitoring IBC packet flow..."
hermes query packet pending \
--chain "${HUB_CHAIN_ID}" \
--port transfer \
--channel "${TRANSFER_CHANNEL}"
}
# Main IBC setup flow
main() {
log_info "Starting IBC setup for Identity DAO..."
# Check requirements
check_hermes
# Initialize configuration
init_hermes_config
# Check if keys exist or need to be created
if [ ! -f "hub-relayer.mnemonic" ] || [ ! -f "sonr-relayer.mnemonic" ]; then
log_error "Relayer mnemonics not found. Please create:"
log_info "1. hub-relayer.mnemonic - Funded account on Cosmos Hub testnet"
log_info "2. sonr-relayer.mnemonic - Funded account on Sonr testnet"
exit 1
fi
# Add keys
add_relayer_keys
# Create IBC infrastructure
create_clients
create_connection
create_channels
# Start relayer
start_relayer
# Query established channels
query_channels
# Test connectivity
test_ibc
# Monitor packets
monitor_packets
log_info "✅ IBC setup complete!"
log_info ""
log_info "=== IBC Summary ==="
log_info "Relayer PID: $(cat relayer.pid)"
log_info "Config: ${RELAYER_HOME}/config.toml"
log_info ""
log_info "Next steps:"
log_info "1. Monitor relayer logs: hermes start"
log_info "2. Query channels: hermes query channels --chain ${HUB_CHAIN_ID}"
log_info "3. Test cross-chain queries: ./scripts/test_did_query.sh"
}
# Run main IBC setup
main "$@"
+245
View File
@@ -0,0 +1,245 @@
#!/bin/bash
# Test script for Identity DAO IBC Integration
# Validates cross-chain DID verification between Cosmos Hub and Sonr
set -e
# Configuration
DEPLOYMENT_FILE="${1:-cosmos-hub-deployment.json}"
TEST_DID="did:sonr:test123"
TEST_ADDRESS="cosmos1test..."
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Identity DAO IBC Integration Tests${NC}"
echo -e "${BLUE}========================================${NC}"
# Load deployment info
if [ ! -f "$DEPLOYMENT_FILE" ]; then
echo -e "${RED}Error: Deployment file not found: $DEPLOYMENT_FILE${NC}"
exit 1
fi
# Extract contract addresses
VOTING_ADDR=$(jq -r '.contracts.voting.address' "$DEPLOYMENT_FILE")
PROPOSALS_ADDR=$(jq -r '.contracts.proposals.address' "$DEPLOYMENT_FILE")
VOTING_CHANNEL=$(jq -r '.contracts.voting.ibc_channel' "$DEPLOYMENT_FILE")
CHAIN_ID=$(jq -r '.chain_id' "$DEPLOYMENT_FILE")
echo "Using contracts from deployment:"
echo " Voting: $VOTING_ADDR (Channel: $VOTING_CHANNEL)"
echo " Proposals: $PROPOSALS_ADDR"
echo ""
# Function to run test
run_test() {
local test_name=$1
local test_cmd=$2
echo -ne "${YELLOW}Testing: ${test_name}...${NC}"
if eval "$test_cmd" > /dev/null 2>&1; then
echo -e " ${GREEN}${NC}"
return 0
else
echo -e " ${RED}${NC}"
return 1
fi
}
# Test 1: Check IBC channel status
echo -e "${BLUE}1. Checking IBC Channel Status${NC}"
CHANNEL_STATUS=$(hermes query channel end \
--chain "$CHAIN_ID" \
--port "wasm.$VOTING_ADDR" \
--channel "$VOTING_CHANNEL" \
2>/dev/null | jq -r '.state')
if [ "$CHANNEL_STATUS" = "Open" ]; then
echo -e "${GREEN}✓ Channel is OPEN${NC}"
else
echo -e "${RED}✗ Channel status: $CHANNEL_STATUS${NC}"
exit 1
fi
# Test 2: Query Sonr chain for DIDs
echo -e "${BLUE}2. Querying Sonr DIDs via IBC${NC}"
# Send IBC packet to query DID
QUERY_MSG='{
"send_did_query": {
"did": "'$TEST_DID'",
"channel": "'$VOTING_CHANNEL'"
}
}'
TX_HASH=$(gaiad tx wasm execute "$VOTING_ADDR" "$QUERY_MSG" \
--from deployer \
--chain-id "$CHAIN_ID" \
--gas-prices 0.025uatom \
--gas auto \
--gas-adjustment 1.5 \
--yes \
--output json 2>/dev/null | jq -r '.txhash')
echo "Query transaction: $TX_HASH"
sleep 6
# Check if packet was acknowledged
PACKET_ACK=$(hermes query packet acks \
--chain "$CHAIN_ID" \
--port "wasm.$VOTING_ADDR" \
--channel "$VOTING_CHANNEL" \
2>/dev/null | jq -r '.acks | length')
if [ "$PACKET_ACK" -gt 0 ]; then
echo -e "${GREEN}✓ IBC packet acknowledged${NC}"
else
echo -e "${YELLOW}⚠ No acknowledgment yet (may be pending)${NC}"
fi
# Test 3: Update voter with DID verification
echo -e "${BLUE}3. Testing Voter Update with DID${NC}"
UPDATE_MSG='{
"update_voter": {
"did": "'$TEST_DID'",
"address": "'$TEST_ADDRESS'"
}
}'
UPDATE_TX=$(gaiad tx wasm execute "$VOTING_ADDR" "$UPDATE_MSG" \
--from deployer \
--chain-id "$CHAIN_ID" \
--gas-prices 0.025uatom \
--gas auto \
--gas-adjustment 1.5 \
--yes \
--output json 2>/dev/null | jq -r '.txhash')
echo "Update transaction: $UPDATE_TX"
sleep 6
# Query voter info
VOTER_QUERY='{
"voter_info": {
"did": "'$TEST_DID'"
}
}'
VOTER_INFO=$(gaiad query wasm contract-state smart "$VOTING_ADDR" "$VOTER_QUERY" \
--output json 2>/dev/null | jq -r '.data')
if [ "$VOTER_INFO" != "null" ]; then
echo -e "${GREEN}✓ Voter registered successfully${NC}"
echo "Voter info: $VOTER_INFO"
else
echo -e "${RED}✗ Voter not found${NC}"
fi
# Test 4: Create proposal through IBC
echo -e "${BLUE}4. Testing Proposal Creation${NC}"
PROPOSAL_MSG='{
"propose": {
"title": "Test IBC Proposal",
"description": "Testing cross-chain governance",
"msgs": [],
"proposer_did": "'$TEST_DID'"
}
}'
PROPOSAL_TX=$(gaiad tx wasm execute "$PROPOSALS_ADDR" "$PROPOSAL_MSG" \
--from deployer \
--chain-id "$CHAIN_ID" \
--gas-prices 0.025uatom \
--gas auto \
--gas-adjustment 1.5 \
--yes \
--output json 2>/dev/null | jq -r '.txhash')
echo "Proposal transaction: $PROPOSAL_TX"
sleep 6
# Query proposals
PROPOSALS_QUERY='{"list_proposals": {"limit": 10}}'
PROPOSALS=$(gaiad query wasm contract-state smart "$PROPOSALS_ADDR" "$PROPOSALS_QUERY" \
--output json 2>/dev/null | jq -r '.data.proposals | length')
if [ "$PROPOSALS" -gt 0 ]; then
echo -e "${GREEN}✓ Proposal created successfully${NC}"
echo "Total proposals: $PROPOSALS"
else
echo -e "${RED}✗ No proposals found${NC}"
fi
# Test 5: Check relayer metrics
echo -e "${BLUE}5. Checking Relayer Health${NC}"
RELAYER_STATUS=$(hermes health-check 2>/dev/null | grep -c "OK" || true)
if [ "$RELAYER_STATUS" -gt 0 ]; then
echo -e "${GREEN}✓ Relayer is healthy${NC}"
else
echo -e "${YELLOW}⚠ Relayer may need attention${NC}"
fi
# Test 6: Packet flow statistics
echo -e "${BLUE}6. IBC Packet Statistics${NC}"
echo "Channel: $VOTING_CHANNEL"
# Get packet commitments
PENDING_PACKETS=$(hermes query packet commitments \
--chain "$CHAIN_ID" \
--port "wasm.$VOTING_ADDR" \
--channel "$VOTING_CHANNEL" \
2>/dev/null | jq -r '.commitments | length')
echo "Pending packets: $PENDING_PACKETS"
# Get packet acknowledgments
TOTAL_ACKS=$(hermes query packet acks \
--chain "$CHAIN_ID" \
--port "wasm.$VOTING_ADDR" \
--channel "$VOTING_CHANNEL" \
2>/dev/null | jq -r '.acks | length')
echo "Total acknowledgments: $TOTAL_ACKS"
# Summary
echo ""
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE}Test Summary${NC}"
echo -e "${BLUE}========================================${NC}"
TESTS_PASSED=0
TESTS_TOTAL=6
[ "$CHANNEL_STATUS" = "Open" ] && ((TESTS_PASSED++))
[ "$PACKET_ACK" -gt 0 ] && ((TESTS_PASSED++))
[ "$VOTER_INFO" != "null" ] && ((TESTS_PASSED++))
[ "$PROPOSALS" -gt 0 ] && ((TESTS_PASSED++))
[ "$RELAYER_STATUS" -gt 0 ] && ((TESTS_PASSED++))
[ "$PENDING_PACKETS" -eq 0 ] && ((TESTS_PASSED++))
if [ "$TESTS_PASSED" -eq "$TESTS_TOTAL" ]; then
echo -e "${GREEN}✓ All tests passed! ($TESTS_PASSED/$TESTS_TOTAL)${NC}"
else
echo -e "${YELLOW}⚠ Some tests failed ($TESTS_PASSED/$TESTS_TOTAL)${NC}"
fi
echo ""
echo "Next steps:"
echo "1. Monitor packet relay: hermes query packet pending --chain $CHAIN_ID"
echo "2. Check channel balance: hermes query channel balance --chain $CHAIN_ID"
echo "3. View relayer logs: hermes start --log-level debug"
+68
View File
@@ -0,0 +1,68 @@
{
"cosmos_hub_testnet": {
"chain_id": "theta-testnet-001",
"rpc_endpoints": [
"https://rpc.sentry-01.theta-testnet.polypore.xyz",
"https://rpc.sentry-02.theta-testnet.polypore.xyz"
],
"grpc_endpoints": [
"grpc.sentry-01.theta-testnet.polypore.xyz:9090",
"grpc.sentry-02.theta-testnet.polypore.xyz:9090"
],
"explorer": "https://explorer.theta-testnet.polypore.xyz",
"faucet": "https://discord.com/channels/669268347736686612/953697793476821092"
},
"sonr_testnet": {
"chain_id": "sonrtest_1-1",
"rpc_endpoints": [
"http://localhost:26657",
"https://testnet-rpc.sonr.io"
],
"grpc_endpoints": [
"localhost:9090",
"testnet-grpc.sonr.io:443"
]
},
"ibc_config": {
"connection_version": "1",
"channel_version": "identity-dao-1",
"packet_timeout": "10m",
"ports": {
"voting": "wasm.identity_dao_voting",
"proposals": "wasm.identity_dao_proposals",
"core": "wasm.identity_dao_core"
},
"sonr_ports": {
"did": "did",
"dwn": "dwn",
"svc": "svc"
}
},
"deployment_params": {
"gas_prices": {
"cosmos_hub": "0.025uatom",
"sonr": "0.025usnr"
},
"gas_adjustment": 1.5,
"deposit_amount": "1000000",
"min_verification_level": 1,
"voting_periods": {
"min_seconds": 86400,
"max_seconds": 604800
},
"pass_threshold": {
"percentage": "0.5"
}
},
"relayer_config": {
"type": "hermes",
"version": "1.7.0",
"clear_interval": 100,
"packet_timeout": "10m",
"trusting_period": "14days",
"trust_threshold": {
"numerator": 2,
"denominator": 3
}
}
}
+356
View File
@@ -0,0 +1,356 @@
#!/bin/bash
# Verify Identity DAO deployment and IBC connectivity
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Helper functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_success() {
echo -e "${GREEN}[✓]${NC} $1"
}
log_fail() {
echo -e "${RED}[✗]${NC} $1"
}
# Configuration
CHAIN_ID="theta-testnet-001"
NODE="https://rpc.sentry-01.theta-testnet.polypore.xyz"
# Load deployment addresses
load_deployment() {
if [ -f "deployment_ids.env" ]; then
source deployment_ids.env
log_info "Loaded deployment configuration"
else
log_error "deployment_ids.env not found. Please deploy contracts first."
exit 1
fi
}
# Verify contract deployment
verify_contract() {
local addr=$1
local name=$2
log_info "Verifying ${name}..."
# Query contract info
CONTRACT_INFO=$(gaiad query wasm contract "${addr}" \
--node "${NODE}" \
--output json 2>/dev/null || echo "{}")
if [ "$CONTRACT_INFO" != "{}" ]; then
CODE_ID=$(echo "$CONTRACT_INFO" | jq -r '.contract_info.code_id')
CREATOR=$(echo "$CONTRACT_INFO" | jq -r '.contract_info.creator')
ADMIN=$(echo "$CONTRACT_INFO" | jq -r '.contract_info.admin')
log_success "${name} deployed at ${addr}"
echo " Code ID: ${CODE_ID}"
echo " Creator: ${CREATOR}"
echo " Admin: ${ADMIN}"
return 0
else
log_fail "${name} not found at ${addr}"
return 1
fi
}
# Query contract state
query_contract_state() {
local addr=$1
local query=$2
local name=$3
log_info "Querying ${name} state..."
RESULT=$(gaiad query wasm contract-state smart "${addr}" "${query}" \
--node "${NODE}" \
--output json 2>/dev/null || echo "{}")
if [ "$RESULT" != "{}" ]; then
echo "$RESULT" | jq '.'
return 0
else
log_error "Failed to query ${name}"
return 1
fi
}
# Test Core contract
test_core_contract() {
log_info "Testing Core contract functionality..."
# Query config
CONFIG_QUERY='{"get_config":{}}'
if query_contract_state "${CORE_ADDR}" "${CONFIG_QUERY}" "Core Config"; then
log_success "Core config query successful"
fi
# Query modules
MODULES_QUERY='{"get_modules":{}}'
if query_contract_state "${CORE_ADDR}" "${MODULES_QUERY}" "Core Modules"; then
log_success "Core modules query successful"
fi
# Query treasury
TREASURY_QUERY='{"get_treasury":{}}'
if query_contract_state "${CORE_ADDR}" "${TREASURY_QUERY}" "Core Treasury"; then
log_success "Core treasury query successful"
fi
}
# Test Voting contract
test_voting_contract() {
log_info "Testing Voting contract functionality..."
# Query total voting power
POWER_QUERY='{"get_total_power":{}}'
if query_contract_state "${VOTING_ADDR}" "${POWER_QUERY}" "Total Voting Power"; then
log_success "Voting power query successful"
fi
# Query voters list
VOTERS_QUERY='{"list_voters":{"limit":10}}'
if query_contract_state "${VOTING_ADDR}" "${VOTERS_QUERY}" "Voters List"; then
log_success "Voters list query successful"
fi
}
# Test Proposals contract
test_proposals_contract() {
log_info "Testing Proposals contract functionality..."
# Query proposal count
COUNT_QUERY='{"get_proposal_count":{}}'
if query_contract_state "${PROPOSALS_ADDR}" "${COUNT_QUERY}" "Proposal Count"; then
log_success "Proposal count query successful"
fi
# Query proposals list
LIST_QUERY='{"list_proposals":{"limit":10}}'
if query_contract_state "${PROPOSALS_ADDR}" "${LIST_QUERY}" "Proposals List"; then
log_success "Proposals list query successful"
fi
}
# Test Pre-Propose contract
test_pre_propose_contract() {
log_info "Testing Pre-Propose contract functionality..."
# Query config
CONFIG_QUERY='{"get_config":{}}'
if query_contract_state "${PRE_PROPOSE_ADDR}" "${CONFIG_QUERY}" "Pre-Propose Config"; then
log_success "Pre-propose config query successful"
fi
# Query deposit info
DEPOSIT_QUERY='{"get_deposit_info":{}}'
if query_contract_state "${PRE_PROPOSE_ADDR}" "${DEPOSIT_QUERY}" "Deposit Info"; then
log_success "Deposit info query successful"
fi
}
# Check IBC channels
check_ibc_channels() {
log_info "Checking IBC channels..."
# Query all channels
CHANNELS=$(gaiad query ibc channel channels \
--node "${NODE}" \
--output json 2>/dev/null || echo '{"channels":[]}')
CHANNEL_COUNT=$(echo "$CHANNELS" | jq '.channels | length')
if [ "$CHANNEL_COUNT" -gt 0 ]; then
log_success "Found ${CHANNEL_COUNT} IBC channel(s)"
# Display channel details
echo "$CHANNELS" | jq -r '.channels[] | " Channel \(.channel_id): \(.state) (\(.port_id))"'
else
log_fail "No IBC channels found"
fi
}
# Check IBC clients
check_ibc_clients() {
log_info "Checking IBC clients..."
# Query all clients
CLIENTS=$(gaiad query ibc client states \
--node "${NODE}" \
--output json 2>/dev/null || echo '{"client_states":[]}')
CLIENT_COUNT=$(echo "$CLIENTS" | jq '.client_states | length')
if [ "$CLIENT_COUNT" -gt 0 ]; then
log_success "Found ${CLIENT_COUNT} IBC client(s)"
# Display client details
echo "$CLIENTS" | jq -r '.client_states[] | " Client \(.client_id): \(.client_state.chain_id)"'
else
log_fail "No IBC clients found"
fi
}
# Test cross-chain query
test_cross_chain_query() {
log_info "Testing cross-chain DID query..."
# Prepare IBC query for x/did module
DID_QUERY='{"query_did_via_ibc":{"did":"did:sonr:test123"}}'
# Execute query through Voting contract
RESULT=$(gaiad query wasm contract-state smart "${VOTING_ADDR}" "${DID_QUERY}" \
--node "${NODE}" \
--output json 2>/dev/null || echo '{"error":"IBC query failed"}')
if echo "$RESULT" | jq -e '.error' > /dev/null; then
log_fail "Cross-chain query failed"
echo "$RESULT" | jq '.'
else
log_success "Cross-chain query successful"
echo "$RESULT" | jq '.'
fi
}
# Generate deployment report
generate_report() {
log_info "Generating deployment report..."
REPORT_FILE="deployment_report_$(date +%Y%m%d_%H%M%S).md"
cat > "$REPORT_FILE" << EOF
# Identity DAO Deployment Report
**Date:** $(date)
**Chain:** Cosmos Hub Testnet (${CHAIN_ID})
**Node:** ${NODE}
## Deployed Contracts
| Contract | Address | Code ID | Status |
|----------|---------|---------|--------|
| Core | ${CORE_ADDR} | ${CORE_CODE_ID} | ✓ |
| Voting | ${VOTING_ADDR} | ${VOTING_CODE_ID} | ✓ |
| Proposals | ${PROPOSALS_ADDR} | ${PROPOSALS_CODE_ID} | ✓ |
| Pre-Propose | ${PRE_PROPOSE_ADDR} | ${PRE_PROPOSE_CODE_ID} | ✓ |
## IBC Configuration
- Clients: ${CLIENT_COUNT}
- Channels: ${CHANNEL_COUNT}
- Relayer Status: $([ -f "relayer.pid" ] && echo "Running (PID: $(cat relayer.pid))" || echo "Not running")
## Test Results
- Core Contract: ✓
- Voting Contract: ✓
- Proposals Contract: ✓
- Pre-Propose Contract: ✓
- IBC Connectivity: $([ "$CHANNEL_COUNT" -gt 0 ] && echo "✓" || echo "✗")
## Next Steps
1. Fund DAO treasury
2. Register initial DID voters
3. Create first governance proposal
4. Monitor IBC packet flow
## Commands
\`\`\`bash
# Query DAO config
gaiad query wasm contract-state smart ${CORE_ADDR} '{"get_config":{}}' --node ${NODE}
# Query voting power
gaiad query wasm contract-state smart ${VOTING_ADDR} '{"get_total_power":{}}' --node ${NODE}
# List proposals
gaiad query wasm contract-state smart ${PROPOSALS_ADDR} '{"list_proposals":{"limit":10}}' --node ${NODE}
\`\`\`
---
Generated by verify_deployment.sh
EOF
log_success "Report saved to ${REPORT_FILE}"
}
# Main verification flow
main() {
log_info "Starting Identity DAO deployment verification..."
# Load deployment configuration
load_deployment
# Verify all contracts
CONTRACTS_OK=true
verify_contract "${CORE_ADDR}" "Core Contract" || CONTRACTS_OK=false
verify_contract "${VOTING_ADDR}" "Voting Contract" || CONTRACTS_OK=false
verify_contract "${PROPOSALS_ADDR}" "Proposals Contract" || CONTRACTS_OK=false
verify_contract "${PRE_PROPOSE_ADDR}" "Pre-Propose Contract" || CONTRACTS_OK=false
if [ "$CONTRACTS_OK" = false ]; then
log_error "Some contracts are not deployed correctly"
exit 1
fi
echo ""
# Test contract functionality
test_core_contract
echo ""
test_voting_contract
echo ""
test_proposals_contract
echo ""
test_pre_propose_contract
echo ""
# Check IBC setup
check_ibc_clients
echo ""
check_ibc_channels
echo ""
# Test cross-chain functionality
test_cross_chain_query
echo ""
# Generate report
generate_report
log_info "✅ Verification complete!"
log_info ""
log_info "=== Summary ==="
if [ "$CONTRACTS_OK" = true ]; then
log_success "All contracts deployed successfully"
fi
if [ "$CHANNEL_COUNT" -gt 0 ]; then
log_success "IBC channels established"
else
log_fail "IBC channels not yet established"
fi
log_info ""
log_info "View detailed report: cat ${REPORT_FILE}"
}
# Run main verification
main "$@"