#!/usr/bin/env bash # instantiate-subdao.sh — stand up a 1-of-1 agent sub-DAO on juno-1. # # Wraps the three-contract dance (DaoDaoCore + dao-voting-cw4 + dao-proposal-single # with VetoConfig) described in references/dao-dao.md §Create. Use this when you # want a fresh sub-DAO and don't want to assemble nested base64-encoded sub-msgs # by hand each time. # # Usage: # instantiate-subdao.sh \ # --name "My Agent DAO" \ # --description "Sub-DAO for the X agent" \ # --member juno1agent... \ # --vetoer juno1stewards... \ # --key my-key \ # --keyring-dir /workspace/.my-keyring \ # [--voting-period 86400] \ # [--timelock 172800] \ # [--rpc https://juno-rpc.publicnode.com:443] \ # [--chain-id juno-1] \ # [--dry-run] # # All durations are in seconds (time-based). The script enforces unit-match between # max_voting_period and timelock_duration — dao-proposal-single rejects mixed # height/time units with TimelockDurationUnitMismatch. # # Code IDs are pinned to juno-1 dao-contracts v2.7.0. Update CORE_ID etc. if you're # on a different version or chain. set -euo pipefail CORE_ID=4862 # dao-dao-core VOTING_CW4_ID=4872 # dao-voting-cw4 CW4_GROUP_ID=1992 # cw4-group (spawned inside voting module) PROP_SINGLE_ID=4869 # dao-proposal-single NAME="" DESCRIPTION="" MEMBER="" VETOER="" KEY="" KEYRING_DIR="" KEYRING_BACKEND="test" VOTING_PERIOD_S=86400 # 24h default TIMELOCK_S=172800 # 48h default RPC="https://juno-rpc.publicnode.com:443" CHAIN_ID="juno-1" DRY_RUN=0 usage() { sed -n '2,30p' "$0" | sed 's/^# \{0,1\}//' ; exit "${1:-0}" ; } while [ $# -gt 0 ]; do case "$1" in --name) NAME="$2"; shift 2 ;; --description) DESCRIPTION="$2"; shift 2 ;; --member) MEMBER="$2"; shift 2 ;; --vetoer) VETOER="$2"; shift 2 ;; --key) KEY="$2"; shift 2 ;; --keyring-dir) KEYRING_DIR="$2"; shift 2 ;; --keyring-backend) KEYRING_BACKEND="$2"; shift 2 ;; --voting-period) VOTING_PERIOD_S="$2"; shift 2 ;; --timelock) TIMELOCK_S="$2"; shift 2 ;; --rpc) RPC="$2"; shift 2 ;; --chain-id) CHAIN_ID="$2"; shift 2 ;; --dry-run) DRY_RUN=1; shift ;; -h|--help) usage 0 ;; *) echo "unknown flag: $1" >&2; usage 1 ;; esac done for required in NAME DESCRIPTION MEMBER VETOER KEY KEYRING_DIR ; do if [ -z "${!required}" ]; then echo "missing required: --${required,,}" >&2 usage 1 fi done WORK=$(mktemp -d) trap 'rm -rf "$WORK"' EXIT # --- voting submsg: dao-voting-cw4 with a 1-of-1 cw4-group --- cat > "$WORK/voting.json" < "$WORK/proposal.json" < "$WORK/dao.json" < assembled InstantiateMsg at $WORK/dao.json" if [ "$DRY_RUN" -eq 1 ]; then echo " --dry-run set; not broadcasting. Inspect with: jq . $WORK/dao.json" cat "$WORK/dao.json" exit 0 fi echo "==> broadcasting to $CHAIN_ID via $RPC" junod tx wasm instantiate "$CORE_ID" "$(cat "$WORK/dao.json")" \ --label "$NAME" \ --no-admin \ --from "$KEY" \ --keyring-backend "$KEYRING_BACKEND" \ --keyring-dir "$KEYRING_DIR" \ --chain-id "$CHAIN_ID" \ --node "$RPC" \ --gas auto --gas-adjustment 1.5 \ --gas-prices 0.075ujuno \ --yes \ -o json | tee "$WORK/broadcast.json" | jq '.txhash, .code, .raw_log' TXHASH=$(jq -r '.txhash' "$WORK/broadcast.json") echo echo "==> broadcast txhash: $TXHASH" echo " poll with: junod query tx $TXHASH --node $RPC -o json | jq" echo " or: verify-tx.sh --txhash $TXHASH --rpc $RPC" echo " the first _contract_address in the instantiate events is the DAO core."