2026-03-02 12:14:09 -08:00
#!/usr/bin/env bash
# E2E live test: lock on 138 -> submit claim on mainnet -> (after 30 min) finalize -> release bond.
# Run from a host that can reach RPC_URL_138. Requires .env in smom-dbis-138 repo root.
# Best: cd /path/to/smom-dbis-138 then ./scripts/deployment/run-e2e-trustless-live-test.sh
#
# Usage:
# ./scripts/deployment/run-e2e-trustless-live-test.sh # run step 1 (lock), then print steps 2– 3
# ./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH> # print DEPOSIT_ID from lock tx
# DEPOSIT_ID=0x... AMOUNT_WEI=1000000000000000 ./scripts/deployment/run-e2e-trustless-live-test.sh claim # run step 2 only
# DEPOSIT_ID=0x... ./scripts/deployment/run-e2e-trustless-live-test.sh finalize # run step 3 only
set -euo pipefail
# Resolve repo root from script path so this works from any cwd (use full path to script when invoking)
SCRIPT_PATH = " ${ BASH_SOURCE [0] } "
[ [ -z " $SCRIPT_PATH " ] ] && SCRIPT_PATH = " $0 "
SCRIPT_DIR = " $( cd " $( dirname " $SCRIPT_PATH " ) " && pwd ) "
REPO_ROOT = " $( cd " $SCRIPT_DIR /../.. " && pwd ) "
2026-03-27 19:02:30 -07:00
# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source.
if [ [ -f " $SCRIPT_DIR /../lib/deployment/dotenv.sh " ] ] ; then
# shellcheck disable=SC1090
source " $SCRIPT_DIR /../lib/deployment/dotenv.sh "
load_deployment_env --repo-root " ${ PROJECT_ROOT :- $REPO_ROOT } "
elif [ [ -n " ${ PROJECT_ROOT :- } " && -f " $PROJECT_ROOT /.env " ] ] ; then
set -a
# shellcheck disable=SC1090
source " $PROJECT_ROOT /.env "
set +a
elif [ [ -n " ${ REPO_ROOT :- } " && -f " $REPO_ROOT /.env " ] ] ; then
set -a
# shellcheck disable=SC1090
source " $REPO_ROOT /.env "
set +a
fi
2026-03-02 12:14:09 -08:00
if [ [ ! -d " $REPO_ROOT " ] ] ; then
echo " Error: REPO_ROOT not found: $REPO_ROOT . Run from smom-dbis-138 repo, e.g. cd /path/to/smom-dbis-138 && ./scripts/deployment/run-e2e-trustless-live-test.sh "
exit 1
fi
cd " $REPO_ROOT " || { echo " Error: cannot cd to $REPO_ROOT " ; exit 1; }
# Use _MAINNET variants if unsuffixed not set (for .env that only has _MAINNET)
export BOND_MANAGER = " ${ BOND_MANAGER :- ${ BOND_MANAGER_MAINNET :- } } "
export CHALLENGE_MANAGER = " ${ CHALLENGE_MANAGER :- ${ CHALLENGE_MANAGER_MAINNET :- } } "
export INBOX_ETH = " ${ INBOX_ETH :- ${ INBOX_ETH_MAINNET :- } } "
export LOCKBOX_138 = " ${ LOCKBOX_138 :- } "
export RPC_URL_138 = " ${ RPC_URL_138 :- ${ CHAIN_138_RPC_URL :- } } "
export ETHEREUM_MAINNET_RPC = " ${ ETHEREUM_MAINNET_RPC :- } "
# Require key and RPCs so we fail with a clear message instead of "Invalid params"
[ [ -n " ${ PRIVATE_KEY :- } " ] ] || { echo "PRIVATE_KEY not set in .env" ; exit 1; }
RECIPIENT = $( cast wallet address " $PRIVATE_KEY " )
NONCE = $( cast keccak " e2e- $( date +%s) " | tr -d '\n\r' )
# 0.001 ether in wei
AMOUNT_WEI = " ${ AMOUNT_WEI :- 1000000000000000 } "
case " ${ 1 :- } " in
get-deposit-id)
[ [ -n " ${ RPC_URL_138 :- } " ] ] || { echo "RPC_URL_138 not set" ; exit 1; }
LOCK_TX = " ${ 2 :- } "
[ [ -n " $LOCK_TX " ] ] || { echo " Usage: $0 get-deposit-id <LOCK_TX_HASH> " ; exit 1; }
# Deposit event: first indexed param is depositId (topics[1])
DEPOSIT_ID_HEX = $( cast receipt " $LOCK_TX " --rpc-url " $RPC_URL_138 " -j 2>/dev/null | jq -r '.logs[0].topics[1] // empty' )
if [ [ -z " $DEPOSIT_ID_HEX " ] ] ; then
echo " No Deposit log in tx or jq failed. Try: cast logs $LOCK_TX \"Deposit(uint256,address,uint256,address,bytes32,address,uint256)\" --rpc-url \$RPC_URL_138 "
exit 1
fi
# cast expects uint256 as decimal or 0x; topics are 32-byte hex (0x + 64 chars)
echo " $DEPOSIT_ID_HEX "
exit 0
; ;
claim)
[ [ -n " ${ ETHEREUM_MAINNET_RPC :- } " ] ] || { echo "ETHEREUM_MAINNET_RPC not set" ; exit 1; }
[ [ -n " ${ INBOX_ETH :- } " && -n " ${ BOND_MANAGER :- } " ] ] || { echo "INBOX_ETH and BOND_MANAGER must be set for claim" ; exit 1; }
if [ [ -z " ${ DEPOSIT_ID :- } " ] ] ; then
echo " Set DEPOSIT_ID (from step 1 lock tx Deposit event). Example: DEPOSIT_ID=0x... $0 claim "
echo "To get DEPOSIT_ID from lock tx: cast logs <LOCK_TX_HASH> \"Deposit(uint256,address,uint256,address,bytes32,address,uint256)\" --rpc-url \$RPC_URL_138"
echo " Use the first decoded arg (depositId) as DEPOSIT_ID. Do NOT use AMOUNT_WEI as DEPOSIT_ID."
exit 1
fi
# Avoid common mistake: DEPOSIT_ID must be the event's depositId (large/hash), not the amount
if [ [ " ${ DEPOSIT_ID :- } " = = "1000000000000000" ] ] || [ [ " ${ DEPOSIT_ID :- } " = = " $AMOUNT_WEI " ] ] ; then
echo "Error: DEPOSIT_ID looks like AMOUNT_WEI (0.001 ether). Set DEPOSIT_ID to the depositId from the Deposit event, not the amount."
exit 1
fi
BOND = $( cast call " $BOND_MANAGER " "getRequiredBond(uint256)(uint256)" " $AMOUNT_WEI " --rpc-url " $ETHEREUM_MAINNET_RPC " )
# cast may append " [1e18]" etc.; use only the numeric part for --value
BOND = " ${ BOND %% * } "
echo " BOND (required for claim): $BOND wei "
cast send " $INBOX_ETH " "submitClaim(uint256,address,uint256,address,bytes)" \
" $DEPOSIT_ID " 0x0000000000000000000000000000000000000000 " $AMOUNT_WEI " " $RECIPIENT " 0x \
--value " $BOND " --rpc-url " $ETHEREUM_MAINNET_RPC " --private-key " $PRIVATE_KEY "
echo " Claim submitted. Wait ~30 min then run: DEPOSIT_ID= $DEPOSIT_ID $0 finalize "
exit 0
; ;
finalize)
[ [ -n " ${ ETHEREUM_MAINNET_RPC :- } " ] ] || { echo "ETHEREUM_MAINNET_RPC not set" ; exit 1; }
[ [ -n " ${ CHALLENGE_MANAGER :- } " && -n " ${ BOND_MANAGER :- } " ] ] || { echo "CHALLENGE_MANAGER and BOND_MANAGER must be set for finalize" ; exit 1; }
if [ [ -z " ${ DEPOSIT_ID :- } " ] ] ; then
echo " Set DEPOSIT_ID. Example: DEPOSIT_ID=0x... $0 finalize "
exit 1
fi
cast send " $CHALLENGE_MANAGER " "finalizeClaim(uint256)" " $DEPOSIT_ID " \
--rpc-url " $ETHEREUM_MAINNET_RPC " --private-key " $PRIVATE_KEY "
cast send " $BOND_MANAGER " "releaseBond(uint256)" " $DEPOSIT_ID " \
--rpc-url " $ETHEREUM_MAINNET_RPC " --private-key " $PRIVATE_KEY "
echo "Finalized and bond released."
exit 0
; ;
esac
# Step 1: Lock on 138
[ [ -n " ${ RPC_URL_138 :- } " ] ] || { echo "RPC_URL_138 not set (required for lock on 138)" ; exit 1; }
[ [ -n " ${ LOCKBOX_138 :- } " ] ] || { echo "LOCKBOX_138 not set in .env" ; exit 1; }
# Fail fast if RPC is not Chain 138 (avoids -32602 Invalid params from wrong chain)
CHAIN_ID = $( curl -s -m 5 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' " $RPC_URL_138 " 2>/dev/null | sed -n 's/.*"result":"\([^"]*\)".*/\1/p' )
if [ [ " $CHAIN_ID " != "0x8a" && " $CHAIN_ID " != "0x8A" ] ] ; then
echo " Error: RPC_URL_138 ( $RPC_URL_138 ) returned chainId= $CHAIN_ID ; expected 0x8a (138). Fix .env and retry. "
exit 1
fi
echo " Step 1: Lock 0.001 ether on Chain 138 (LOCKBOX_138= $LOCKBOX_138 ) "
echo " RECIPIENT= $RECIPIENT NONCE= $NONCE "
# Use explicit --gas-limit to avoid eth_estimateGas -32602 Invalid params on some Chain 138 (Besu) nodes
cast send " $LOCKBOX_138 " "depositNative(address,bytes32)" " $RECIPIENT " " $NONCE " \
--value 0.001ether --rpc-url " $RPC_URL_138 " --private-key " $PRIVATE_KEY " \
--legacy --gas-price " ${ GAS_PRICE_138 :- 1000000000 } " --gas-limit " ${ GAS_LIMIT_138 :- 200000 } "
echo ""
echo "Get DEPOSIT_ID from the lock tx (run with the tx hash from above):"
echo " export DEPOSIT_ID=\$(./scripts/deployment/run-e2e-trustless-live-test.sh get-deposit-id <LOCK_TX_HASH>)"
echo " AMOUNT_WEI= $AMOUNT_WEI $0 claim "
echo "Or manually: cast logs <LOCK_TX_HASH> \"Deposit(uint256,address,uint256,address,bytes32,address,uint256)\" --rpc-url \$RPC_URL_138 (use first decoded arg)"
echo "Note: DEPOSIT_ID is the event's depositId, NOT the amount. Required bond for 0.001 ether is 1 ETH (min bond)."