Skip to content

Commit 58fa8e5

Browse files
authored
feat: complete setup and add relayer to docker compose
feat: complete setup and add relayer to docker compose
2 parents 07d5557 + 0be77af commit 58fa8e5

File tree

11 files changed

+246
-19
lines changed

11 files changed

+246
-19
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
build
44
/target
55
*.bin
6-
bin
6+
bin
7+
8+
**/hyperlane_db

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ start:
8686
@docker compose up --detach
8787
.PHONY: start
8888

89+
## relay-local: Start a local instance of the hyperlane relayer (NOTE: This is temporary and should be removed in favour of Docker).
90+
relay-local:
91+
@echo "--> Starting hyperlane relayer"
92+
@cd local && CONFIG_FILES=./config/config.json ./relayer
93+
.PHONY: relay-local
94+
8995
## setup: Set up the IBC light clients.
9096
setup:
9197
@echo "--> Creating genesis.json for Tendermint light client"

docker-compose.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,22 @@ services:
125125
networks:
126126
- celestia-zkevm-net
127127

128+
# TODO: Determine why this does not work but running a relayer binary locally built from main
129+
# can relay a successful warp transfer.
130+
# relayer:
131+
# image: gcr.io/abacus-labs-dev/hyperlane-agent:agents-v1.4.0
132+
# container_name: relayer
133+
# environment:
134+
# - CONFIG_FILES=/app/config/config.json
135+
# volumes:
136+
# - ./hyperlane/relayer-config.json:/app/config/config.json
137+
# command: "/app/relayer"
138+
# depends_on:
139+
# hyperlane-init:
140+
# condition: service_completed_successfully
141+
# networks:
142+
# - celestia-zkevm-net
143+
128144
volumes:
129145
celestia-app:
130146
celestia-bridge:

hyperlane/Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ FROM node:24-slim
1313
# Install the hyperlane CLI (used for evm deployment)
1414
RUN npm install -g @hyperlane-xyz/cli
1515

16+
# Install system packages and foundry
17+
RUN apt-get update && \
18+
apt-get install -y curl git build-essential pkg-config libssl-dev
19+
20+
RUN curl -L https://foundry.paradigm.xyz | bash && \
21+
~/.foundry/bin/foundryup
22+
23+
ENV PATH="/root/.foundry/bin:$PATH"
24+
1625
COPY --from=go-builder /home/hyperlane/hyp /usr/local/bin/hyp
1726

1827
WORKDIR /home/hyperlane

hyperlane/cmd/hyp/cmd/broadcaster.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"context"
5+
"encoding/hex"
56
"fmt"
67
"log"
78
"time"
@@ -10,11 +11,11 @@ import (
1011
abci "github.com/cometbft/cometbft/abci/types"
1112
"github.com/cosmos/cosmos-sdk/client/tx"
1213
"github.com/cosmos/cosmos-sdk/crypto/hd"
14+
"github.com/cosmos/cosmos-sdk/crypto/keyring"
1315
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
1416
sdk "github.com/cosmos/cosmos-sdk/types"
1517
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
1618
"github.com/cosmos/cosmos-sdk/types/tx/signing"
17-
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
1819
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
1920
"google.golang.org/grpc"
2021
)
@@ -34,7 +35,8 @@ type Broadcaster struct {
3435
txService txtypes.ServiceClient
3536

3637
address sdk.AccAddress
37-
privKey *secp256k1.PrivKey
38+
39+
kr keyring.Keyring
3840
}
3941

4042
func NewBroadcaster(enc encoding.Config, grpcConn *grpc.ClientConn) *Broadcaster {
@@ -48,12 +50,17 @@ func NewBroadcaster(enc encoding.Config, grpcConn *grpc.ClientConn) *Broadcaster
4850
pk := secp256k1.PrivKey{Key: privKey}
4951
signerAddr := sdk.AccAddress(pk.PubKey().Address())
5052

53+
kr := keyring.NewInMemory(enc.Codec)
54+
if err := kr.ImportPrivKeyHex(signerAddr.String(), hex.EncodeToString(pk.Bytes()), pk.Type()); err != nil {
55+
log.Fatalf("key import failed")
56+
}
57+
5158
return &Broadcaster{
5259
enc: enc,
5360
authService: authtypes.NewQueryClient(grpcConn),
5461
txService: txtypes.NewServiceClient(grpcConn),
55-
privKey: &pk,
5662
address: signerAddr,
63+
kr: kr,
5764
}
5865
}
5966

@@ -76,21 +83,16 @@ func (b *Broadcaster) BroadcastTx(ctx context.Context, msgs ...sdk.Msg) *sdk.TxR
7683
txBuilder.SetGasLimit(gasLimit)
7784
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewInt64Coin(denom, feeAmount)))
7885

79-
signerData := authsigning.SignerData{
80-
Address: b.address.String(),
81-
ChainID: chainID,
82-
AccountNumber: acc.AccountNumber,
83-
Sequence: acc.Sequence,
84-
PubKey: b.privKey.PubKey(),
85-
}
86-
87-
sigv2, err := tx.SignWithPrivKey(ctx, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON, signerData, txBuilder, b.privKey, b.enc.TxConfig, acc.Sequence)
88-
if err != nil {
89-
log.Fatalf("sign tx failed: %v", err)
90-
}
86+
factory := tx.Factory{}.
87+
WithKeybase(b.kr).
88+
WithSignMode(signing.SignMode_SIGN_MODE_DIRECT).
89+
WithTxConfig(b.enc.TxConfig).
90+
WithChainID(chainID).
91+
WithAccountNumber(acc.AccountNumber).
92+
WithSequence(acc.Sequence)
9193

92-
if err := txBuilder.SetSignatures(sigv2); err != nil {
93-
log.Fatalf("set signatures failed: %v", err)
94+
if err := tx.Sign(ctx, factory, b.address.String(), txBuilder, false); err != nil {
95+
log.Fatalf("failed to sign tx: %v", err)
9496
}
9597

9698
txBytes, err := b.enc.TxConfig.TxEncoder()(txBuilder.GetTx())

hyperlane/cmd/hyp/cmd/cmd.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"encoding/json"
55
"log"
66
"os"
7+
"strconv"
78

9+
"cosmossdk.io/math"
810
"github.com/bcp-innovations/hyperlane-cosmos/util"
911
ismtypes "github.com/bcp-innovations/hyperlane-cosmos/x/core/01_interchain_security/types"
1012
hooktypes "github.com/bcp-innovations/hyperlane-cosmos/x/core/02_post_dispatch/types"
@@ -36,6 +38,7 @@ func NewRootCmd() *cobra.Command {
3638
}
3739

3840
rootCmd.AddCommand(getDeployCmd())
41+
rootCmd.AddCommand(getEnrollRouterCmd())
3942
return rootCmd
4043
}
4144

@@ -123,3 +126,51 @@ func getDeployCmd() *cobra.Command {
123126
}
124127
return deployCmd
125128
}
129+
130+
func getEnrollRouterCmd() *cobra.Command {
131+
deployCmd := &cobra.Command{
132+
Use: "enroll-remote-router [grpc-addr] [token-id] [remote-domain] [remote-contract]",
133+
Short: "Enroll the remote router contract address for a cosmosnative hyperlane warp route",
134+
Args: cobra.ExactArgs(4),
135+
Run: func(cmd *cobra.Command, args []string) {
136+
ctx := cmd.Context()
137+
enc := encoding.MakeConfig(app.ModuleEncodingRegisters...)
138+
139+
grpcAddr := args[0]
140+
141+
grpcConn, err := grpc.NewClient(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
142+
if err != nil {
143+
log.Fatalf("failed to connect to gRPC: %v", err)
144+
}
145+
defer grpcConn.Close()
146+
147+
broadcaster := NewBroadcaster(enc, grpcConn)
148+
149+
tokenID, err := util.DecodeHexAddress(args[1])
150+
if err != nil {
151+
log.Fatalf("failed to parse token id: %v", err)
152+
}
153+
154+
domain, err := strconv.ParseUint(args[2], 10, 32)
155+
if err != nil {
156+
log.Fatalf("failed to parse remote domain: %v", err)
157+
}
158+
159+
msgEnrollRemoteRouter := warptypes.MsgEnrollRemoteRouter{
160+
Owner: broadcaster.address.String(),
161+
TokenId: tokenID,
162+
RemoteRouter: &warptypes.RemoteRouter{
163+
ReceiverDomain: uint32(domain),
164+
ReceiverContract: args[3],
165+
Gas: math.ZeroInt(),
166+
},
167+
}
168+
169+
res := broadcaster.BroadcastTx(ctx, &msgEnrollRemoteRouter)
170+
recvContract := parseReceiverContractFromEvents(res.Events)
171+
172+
cmd.Printf("successfully registered remote router on Hyperlane cosmosnative: \n%s", recvContract)
173+
},
174+
}
175+
return deployCmd
176+
}

hyperlane/cmd/hyp/cmd/events.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,22 @@ func parseCollateralTokenIDFromEvents(events []abci.Event) util.HexAddress {
8888

8989
return tokenID
9090
}
91+
92+
func parseReceiverContractFromEvents(events []abci.Event) string {
93+
var recvContract string
94+
for _, evt := range events {
95+
if evt.GetType() == proto.MessageName(&warptypes.EventEnrollRemoteRouter{}) {
96+
event, err := sdk.ParseTypedEvent(evt)
97+
if err != nil {
98+
log.Fatalf("failed to parse typed event: %v", err)
99+
}
100+
101+
if enrollEvent, ok := event.(*warptypes.EventEnrollRemoteRouter); ok {
102+
log.Printf("successfully enrolled remote router: %s\n", enrollEvent)
103+
recvContract = enrollEvent.ReceiverContract
104+
}
105+
}
106+
}
107+
108+
return recvContract
109+
}

hyperlane/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ replace (
1212
)
1313

1414
require (
15+
cosmossdk.io/math v1.5.3
1516
github.com/bcp-innovations/hyperlane-cosmos v1.0.0
1617
github.com/celestiaorg/celestia-app/v4 v4.0.0-arabica
1718
github.com/cometbft/cometbft v0.38.17
@@ -37,7 +38,6 @@ require (
3738
cosmossdk.io/depinject v1.1.0 // indirect
3839
cosmossdk.io/errors v1.0.2 // indirect
3940
cosmossdk.io/log v1.5.1 // indirect
40-
cosmossdk.io/math v1.5.3 // indirect
4141
cosmossdk.io/store v1.1.2 // indirect
4242
cosmossdk.io/x/circuit v0.1.1 // indirect
4343
cosmossdk.io/x/evidence v0.1.1 // indirect

hyperlane/scripts/docker-entrypoint.sh

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ if [[ ! -f "$CONFIG_FILE" ]]; then
1818

1919
echo "Deploying Hyperlane on cosmosnative..."
2020
hyp deploy celestia-validator:9090
21+
22+
echo "Configuring remote router for warp route on EVM..."
23+
cast send 0xa7578551baE89a96C3365b93493AD2D4EBcbAe97 \
24+
"enrollRemoteRouter(uint32,bytes32)" \
25+
69420 0x726f757465725f61707000000000000000000000000000010000000000000000 \
26+
--private-key $HYP_KEY \
27+
--rpc-url http://reth:8545
28+
29+
router_addr=$(cast call 0xa7578551baE89a96C3365b93493AD2D4EBcbAe97 \
30+
"routers(uint32)(bytes32)" 69420 \
31+
--rpc-url http://reth:8545)
32+
33+
echo "Successfully registered remote router address for domain 69420: $router_addr"
34+
35+
echo "Configuring remote router for warp route on cosmosnative..."
36+
hyp enroll-remote-router celestia-validator:9090 0x726f757465725f61707000000000000000000000000000010000000000000000 1234 0x000000000000000000000000a7578551baE89a96C3365b93493AD2D4EBcbAe97
2137
else
2238
echo "Skipping deployment: $CONFIG_FILE already exists."
2339
fi

local/config/config.json

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
{
2+
"chains": {
3+
"rethlocal": {
4+
"blocks": {
5+
"confirmations": 1,
6+
"estimateBlockTime": 3,
7+
"reorgPeriod": 0
8+
},
9+
"chainId": 1234,
10+
"displayName": "Reth",
11+
"domainId": 1234,
12+
"isTestnet": true,
13+
"name": "rethlocal",
14+
"nativeToken": {
15+
"decimals": 18,
16+
"name": "Ether",
17+
"symbol": "ETH"
18+
},
19+
"protocol": "ethereum",
20+
"rpcUrls": [
21+
{
22+
"http": "http://127.0.0.1:8545"
23+
}
24+
],
25+
"signer": {
26+
"type": "hexKey",
27+
"key": "0x82bfcfadbf1712f6550d8d2c00a39f05b33ec78939d0167be2a737d691f33a6a"
28+
},
29+
"aggregationHook": "0xe53275A1FcA119e1c5eeB32E7a72e54835A63936",
30+
"domainRoutingIsm": "0xE2c1756b8825C54638f98425c113b51730cc47f6",
31+
"fallbackRoutingHook": "0xE2c1756b8825C54638f98425c113b51730cc47f6",
32+
"interchainGasPaymaster": "0x1D957dA7A6988f5a9d2D2454637B4B7fea0Aeea5",
33+
"interchainSecurityModule": "0xa05915fD6E32A1AA7E67d800164CaCB12487142d",
34+
"mailbox": "0xb1c938F5BA4B3593377F399e12175e8db0C787Ff",
35+
"merkleTreeHook": "0xFCb1d485ef46344029D9E8A7925925e146B3430E",
36+
"protocolFee": "0x8A93d247134d91e0de6f96547cB0204e5BE8e5D8",
37+
"proxyAdmin": "0x7e7aD18Adc99b94d4c728fDf13D4dE97B926A0D8",
38+
"storageGasOracle": "0x457cCf29090fe5A24c19c1bc95F492168C0EaFdb",
39+
"testRecipient": "0xd7958B336f0019081Ad2279B2B7B7c3f744Bce0a",
40+
"validatorAnnounce": "0x79ec7bF05AF122D3782934d4Fb94eE32f0C01c97"
41+
},
42+
"celestia": {
43+
"bech32Prefix": "celestia",
44+
"blocks": {
45+
"confirmations": 1,
46+
"estimateBlockTime": 6,
47+
"reorgPeriod": 1
48+
},
49+
"canonicalAsset": "utia",
50+
"chainId": "celestia-zkevm-testnet",
51+
"contractAddressBytes": 32,
52+
"deployer": {
53+
"name": "Damian",
54+
"url": "https://github.com/damiannolan"
55+
},
56+
"displayName": "Celestia ZKEVM Testnet",
57+
"domainId": 69420,
58+
"gasPrice": {
59+
"denom": "utia",
60+
"amount": "0.002"
61+
},
62+
"index": {
63+
"from": 1150,
64+
"chunk": 10
65+
},
66+
"isTestnet": true,
67+
"name": "celestia",
68+
"nativeToken": {
69+
"decimals": 6,
70+
"denom": "utia",
71+
"name": "TIA",
72+
"symbol": "TIA"
73+
},
74+
"protocol": "cosmosnative",
75+
"restUrls": [
76+
{
77+
"http": "http://127.0.0.1:1317"
78+
}
79+
],
80+
"rpcUrls": [
81+
{
82+
"http": "http://127.0.0.1:26657"
83+
}
84+
],
85+
"signer": {
86+
"type": "cosmosKey",
87+
"key": "0x748bcf364b62ac9b74c2bc13e2d429c5b85a3b3ddd8089b873369c1e38fcb10e",
88+
"prefix": "celestia"
89+
},
90+
"slip44": 118,
91+
"technicalStack": "other",
92+
"interchainSecurityModule": "0x726f757465725f69736d00000000000000000000000000000000000000000000",
93+
"mailbox": "0x68797065726c616e650000000000000000000000000000000000000000000000",
94+
"interchainGasPaymaster": "0x726f757465725f706f73745f6469737061746368000000000000000000000000",
95+
"merkleTreeHook": "0x726f757465725f706f73745f6469737061746368000000030000000000000001",
96+
"validatorAnnounce": "0x68797065726c616e650000000000000000000000000000000000000000000000",
97+
"grpcUrls": [
98+
{
99+
"http": "http://127.0.0.1:9090"
100+
}
101+
]
102+
}
103+
},
104+
"defaultRpcConsensusType": "fallback",
105+
"relayChains": "rethlocal,celestia"
106+
}

0 commit comments

Comments
 (0)