At the time of writing, Exocore's testnet (exocoretestnet_233-6) supports exoETH and wstETH on Sepolia for staking. To participate in consensus, validators don't need both of these tokens; only one token type is sufficient.
ETH on Sepolia can be obtained from faucets provided by Alchemy or Infura.
Purpose: ETH is used to pay for gas on the Ethereum testnet.
exoETH on Sepolia can be obtained from the faucet.
Purpose: exoETH is used for staking on Exocore testnet.
wstETH on Sepolia can be obtained by sending Sepolia ETH to the wstETH address 0xB82381A3fBD3FaFA77B3a7bE693342618240067b.
Purpose: wstETH is Lido’s liquid staking token and is used for restaking.
exo, which is the native token on Exocore, can be obtained from the testnet faucet. Similar to ETH and wei, the smaller unit of exo is hua such that 1 exo = 1e18 hua.
Purpose: exo is used to pay for gas on Exocore.
Among the tokens listed above, only exo is present on the Exocore chain while others live on Sepolia.
Deposit Tokens
The contract which accepts deposits is currently deployed on Ethereum, which means the Ethereum private key ($ETH_PRIVATE_KEY) is needed.
## Script constantsEXO_ETH_ADDR=0x83E6850591425e3C1E263c054f4466838B9Bd9e4WST_ETH_ADDR=0xB82381A3fBD3FaFA77B3a7bE693342618240067bGATEWAY_ADDR=0xDf9caDCfb027d9f6264Ecd5eAEc839a8335d8520## User choices# Enter your Ethereum testnet private keyETH_PRIVATE_KEY=0xabcde.....# Enter the address corresponding to the keyETH_ADDRESS=0x123....# Obtain the token as described above, and choose the one you intend to deposit.# For most validators, this default works. However, others can still bring in # their `wstETH` (or another supported token) to participate.TOKEN=$EXO_ETH_ADDR# Quantity of token to deposit (without the 1e18 multiplier)# Decimal values are supportedQUANTITY=25# Endpoint for Ethereum RPCETHEREUM_RPC_URL=https://rpc.ankr.com/eth_sepolia# Approve the deposit by VaultVAULT_ADDR=$(castcall--rpc-url $ETHEREUM_RPC_URL $GATEWAY_ADDR "tokenToVault(address) returns (address)" $TOKEN)castsend--rpc-url $ETHEREUM_RPC_URL \ $TOKEN \"approve(address,uint256)" \ $VAULT_ADDR \"$(castmaxu)" \--private-key $ETH_PRIVATE_KEYBOOTSTRAPPED=$(castcall--rpc-url $ETHEREUM_RPC_URL $GATEWAY_ADDR "bootstrapped() returns (bool)")if [ "$BOOTSTRAPPED"="true" ]; then# Generate the LZ messsage to calculate the fees DEPOSIT_PREFIX="0x00" TOKEN_B32=$(cast2b $TOKEN) ETH_ADDRESS_B32=$(cast2b $ETH_ADDRESS) QUANTITY_B32=$(printf"%064s" $(cast2h $(cast2w $QUANTITY) |cut-c3-) |tr' ''0') # left padding LZ_MESSAGE=$(castch $DEPOSIT_PREFIX $TOKEN_B32 $ETH_ADDRESS_B32 $QUANTITY_B32) VALUE=$(castcall--rpc-url $ETHEREUM_RPC_URL $GATEWAY_ADDR "quote(bytes)" $LZ_MESSAGE)else# No fees VALUE=0fi# Execute the transactioncastsend--rpc-url $ETHEREUM_RPC_URL \ $GATEWAY_ADDR \"deposit(address,uint256)" \ $TOKEN \ $(cast2w $QUANTITY) \--private-key $ETH_PRIVATE_KEY \--value $(cast2d $VALUE)
The expected output of the commands should look similar to below:
If the above transaction is executed post network launch, LayerZeroScan may be used to check whether the Deposit message, sent from Ethereum to Exocore, was executed on the destination chain successfully. Once it is executed, the deposited amount can be queried from Exocore.
ETH_LZ_ID=40161# Sepolia, where our $GATEWAY_ADDR livesSTAKER_ID=$(echo"${ETH_ADDRESS}"|tr'[:upper:]''[:lower:]')_$(printf'0x%x\n'"${ETH_LZ_ID}")# our public endpoint is available below, but you can use your own node tooEXOCORE_COS_GRPC_URL=https://api-cosmos-grpc.exocore-restaking.com:443exocoredqueryassetsQueStakerAssetInfos \ $STAKER_ID --node $EXOCORE_COS_GRPC_URL \--outputjson|jq
The expected output of this will represent the quantity of tokens deposited, multiplied by 1e18.
{"asset_infos": [ {// the `asset_id` will vary depending on $TOKEN chosen// the `_0x9ce1` represents that hex value of the ETH_LZ_ID, a unique ID// assigned by LayerZero to the Sepolia network"asset_id":"0xb82381a3fbd3fafa77b3a7be693342618240067b_0x9ce1","info": {// Represents a quantity of 0.5 * 1e18"total_deposit_amount":"500000000000000000",// The below amount is "free" as in not deleted to an operator"withdrawable_amount":"500000000000000000",// The below amount is currently "unbonding""pending_undelegation_amount":"0" } } ]}