Skip to content

feat: kas bridge #1883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 48 commits into from
Jun 13, 2025
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
69b9482
use local hyperlane
danwt Jun 3, 2025
3a75d99
go sum
danwt Jun 3, 2025
e0d08c5
add a copy of some sequencer proto files to a kas module dir
danwt Jun 3, 2025
83b495a
rename paths
danwt Jun 3, 2025
4aa25e1
strip down
danwt Jun 3, 2025
127196b
generate some foo kas types (query events genesis tx)
danwt Jun 3, 2025
84db222
adds more module files, copied from sequencer
danwt Jun 3, 2025
6a43da1
strip down (not building)
danwt Jun 3, 2025
875788c
regen protos
danwt Jun 3, 2025
ffaf84e
strips down - confirms builds. module still unregistered
danwt Jun 3, 2025
556d903
add module registry, including to upgrade new store
danwt Jun 3, 2025
470b0d4
add TransactionOutpoint proto
danwt Jun 3, 2025
82610ee
add protos and pb go for withdrawal status query
danwt Jun 3, 2025
bb5da2b
add query for withdrawal status
danwt Jun 3, 2025
38ae1e5
add indicate progress rpc proto def
danwt Jun 3, 2025
62b73d7
broken - start implementing progress indication
danwt Jun 3, 2025
152dffc
doing more logic for the update
danwt Jun 3, 2025
3c0afec
untested - simplify and finish the update method
danwt Jun 3, 2025
24d36f7
builds
danwt Jun 3, 2025
1ad958a
start to add the bootstrap stuff
danwt Jun 4, 2025
32e011c
working on the bootstrap tx
danwt Jun 4, 2025
37dff03
build passes
danwt Jun 4, 2025
1769dc2
build passes
danwt Jun 4, 2025
47793dd
add tx outpoint to query
danwt Jun 4, 2025
af18eec
cp
danwt Jun 4, 2025
74d835e
doc
danwt Jun 4, 2025
8db8a02
add genesis protos
danwt Jun 4, 2025
252aa39
add genesis - test fails, something about store reg
danwt Jun 4, 2025
c992bee
add a query for outpoint
danwt Jun 4, 2025
660e735
add events
danwt Jun 4, 2025
32cc086
add store key
danwt Jun 4, 2025
47a8fdc
go mod tidy
danwt Jun 4, 2025
9bc593b
codec
danwt Jun 4, 2025
2fcaab2
fmt
danwt Jun 4, 2025
93ceae7
proto fmt and regen
danwt Jun 4, 2025
7e357d9
buggy: adds a sanity check for token bridged supply on second bootstr…
danwt Jun 4, 2025
119a7b6
revert sanity check for token bridges supply on second bootstrap: its…
danwt Jun 4, 2025
957e4f8
use hyperlane cosmos fork main-dym
danwt Jun 12, 2025
d44c9b9
merge main, fix module reg conflicts
danwt Jun 12, 2025
2a4197e
merge main with manual go mod conflict resolution
danwt Jun 13, 2025
ddc2b27
progress checkpoint: code might be broken
danwt Jun 13, 2025
dbabff6
Update proto/dymensionxyz/dymension/kas/d.proto
danwt Jun 13, 2025
059c326
simplify module
danwt Jun 13, 2025
6f61217
remove unused
danwt Jun 13, 2025
fa4cf82
todo in genesis test
danwt Jun 13, 2025
bd51049
comments
danwt Jun 13, 2025
51ad747
fix comments, tests pass
danwt Jun 13, 2025
0f64f2b
proto fmt
danwt Jun 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion app/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ import (
hypercoretypes "github.com/bcp-innovations/hyperlane-cosmos/x/core/types"
hyperwarpkeeper "github.com/bcp-innovations/hyperlane-cosmos/x/warp/keeper"
hyperwarptypes "github.com/bcp-innovations/hyperlane-cosmos/x/warp/types"
kaskeeper "github.com/dymensionxyz/dymension/v3/x/kas/keeper"
kastypes "github.com/dymensionxyz/dymension/v3/x/kas/types"

forward "github.com/dymensionxyz/dymension/v3/x/forward"
forwardtypes "github.com/dymensionxyz/dymension/v3/x/forward/types"
Expand Down Expand Up @@ -173,6 +175,7 @@ type AppKeepers struct {

HyperCoreKeeper hypercorekeeper.Keeper
HyperWarpKeeper hyperwarpkeeper.Keeper
KasKeeper *kaskeeper.Keeper

Forward *forward.Forward

Expand All @@ -191,7 +194,6 @@ func (a *AppKeepers) InitKeepers(
moduleAccountAddrs map[string]bool,
appOpts servertypes.AppOptions,
) {

govModuleAddress := authtypes.NewModuleAddress(govtypes.ModuleName).String()

// get skipUpgradeHeights from the app options
Expand Down Expand Up @@ -539,6 +541,13 @@ func (a *AppKeepers) InitKeepers(
hyperwarpkeeper.NewMsgServerImpl(a.HyperWarpKeeper),
)

a.KasKeeper = kaskeeper.NewKeeper(
appCodec,
runtime.NewKVStoreService(a.keys[kastypes.ModuleName]),
govModuleAddress,
&a.HyperCoreKeeper,
)

a.HyperWarpKeeper.SetHook(a.Forward)

a.DelayedAckKeeper.SetCompletionHooks(map[string]delayedackkeeper.CompletionHookInstance{
Expand Down
12 changes: 8 additions & 4 deletions app/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
txfeestypes "github.com/osmosis-labs/osmosis/v15/x/txfees/types"

irotypes "github.com/dymensionxyz/dymension/v3/x/iro/types"
kastypes "github.com/dymensionxyz/dymension/v3/x/kas/types"

dymnstypes "github.com/dymensionxyz/dymension/v3/x/dymns/types"

Expand Down Expand Up @@ -129,18 +130,21 @@ var KVStoreKeys = storetypes.NewKVStoreKeys(
delayedacktypes.StoreKey,
eibcmoduletypes.StoreKey,
dymnstypes.StoreKey,
lightcliendmoduletypes.StoreKey,
grouptypes.StoreKey,
hypercoretypes.ModuleName,
hyperwarptypes.ModuleName,
kastypes.ModuleName,

// ethermint keys
evmtypes.StoreKey,
feemarkettypes.StoreKey,

// osmosis keys
lockuptypes.StoreKey,
epochstypes.StoreKey,
gammtypes.StoreKey,
poolmanagertypes.StoreKey,
incentivestypes.StoreKey,
txfeestypes.StoreKey,
lightcliendmoduletypes.StoreKey,
grouptypes.StoreKey,
hypercoretypes.ModuleName,
hyperwarptypes.ModuleName,
)
7 changes: 7 additions & 0 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ import (

dymnsmodule "github.com/dymensionxyz/dymension/v3/x/dymns"
dymnstypes "github.com/dymensionxyz/dymension/v3/x/dymns/types"
"github.com/dymensionxyz/dymension/v3/x/kas"
kastypes "github.com/dymensionxyz/dymension/v3/x/kas/types"

delayedackmodule "github.com/dymensionxyz/dymension/v3/x/delayedack"
denommetadatamodule "github.com/dymensionxyz/dymension/v3/x/denommetadata"
Expand Down Expand Up @@ -154,6 +156,7 @@ func (app *App) SetupModules(
// Hyperlane modules
hypercore.NewAppModule(appCodec, &app.HyperCoreKeeper),
hyperwarp.NewAppModule(appCodec, app.HyperWarpKeeper),
kas.NewAppModule(appCodec, app.KasKeeper),
}
}

Expand Down Expand Up @@ -197,6 +200,7 @@ var maccPerms = map[string][]string{
irotypes.ModuleName: {authtypes.Minter, authtypes.Burner},
hypertypes.ModuleName: nil,
hyperwarptypes.ModuleName: {authtypes.Minter, authtypes.Burner},
kastypes.ModuleName: nil,
}

var PreBlockers = []string{
Expand Down Expand Up @@ -245,6 +249,7 @@ var BeginBlockers = []string{
grouptypes.ModuleName,
hypertypes.ModuleName,
hyperwarptypes.ModuleName,
kastypes.ModuleName,
}

var EndBlockers = []string{
Expand Down Expand Up @@ -289,6 +294,7 @@ var EndBlockers = []string{
grouptypes.ModuleName,
hypertypes.ModuleName,
hyperwarptypes.ModuleName,
kastypes.ModuleName,
}

var InitGenesis = []string{
Expand Down Expand Up @@ -334,4 +340,5 @@ var InitGenesis = []string{
hypertypes.ModuleName,
hyperwarptypes.ModuleName,
circuittypes.ModuleName,
kastypes.ModuleName,
}
2 changes: 2 additions & 0 deletions app/upgrades/v5/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
hypercoretypes "github.com/bcp-innovations/hyperlane-cosmos/x/core/types"
hyperwarptypes "github.com/bcp-innovations/hyperlane-cosmos/x/warp/types"
"github.com/dymensionxyz/dymension/v3/app/upgrades"
kastypes "github.com/dymensionxyz/dymension/v3/x/kas/types"
)

const (
Expand All @@ -20,6 +21,7 @@ var Upgrade = upgrades.Upgrade{
Added: []string{
hypercoretypes.ModuleName,
hyperwarptypes.ModuleName,
kastypes.ModuleName,
circuittypes.ModuleName,
},
},
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ require (
)

replace (
github.com/bcp-innovations/hyperlane-cosmos => github.com/dymensionxyz/hyperlane-cosmos v0.0.0-20250520112012-e15f3cfebc7b
github.com/bcp-innovations/hyperlane-cosmos => github.com/dymensionxyz/hyperlane-cosmos v0.0.0-20250604142341-c9b00acb9947
github.com/evmos/ethermint => github.com/dymensionxyz/ethermint v0.22.0-dymension-v1.1.0-rc01.0.20250515141645-7f16f1928018
// use dymension forks
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ github.com/dymensionxyz/ethermint v0.22.0-dymension-v1.1.0-rc01.0.20250515141645
github.com/dymensionxyz/ethermint v0.22.0-dymension-v1.1.0-rc01.0.20250515141645-7f16f1928018/go.mod h1:eA60HVW0vtGMLV3Xp3FHLw7/d2w8MTtBv1YyGmlyulg=
github.com/dymensionxyz/gerr-cosmos v1.1.0 h1:IW/P7HCB/iP9kgk3VXaWUoMoyx3vD76YO6p1fnubHVc=
github.com/dymensionxyz/gerr-cosmos v1.1.0/go.mod h1:n+0olxPogzWqFKba45mCpvrHLGmeS8W9UZjggHnWk6c=
github.com/dymensionxyz/hyperlane-cosmos v0.0.0-20250520112012-e15f3cfebc7b h1:swhhKl97Kw/xP3XK5s9yE7wJcHK20onXwohZn9UcwLE=
github.com/dymensionxyz/hyperlane-cosmos v0.0.0-20250520112012-e15f3cfebc7b/go.mod h1:Fu7YLwOAUGpSsTxBH/KgGwoNlbGHwAUc3gg1jZ5Fnao=
github.com/dymensionxyz/hyperlane-cosmos v0.0.0-20250604142341-c9b00acb9947 h1:ijADSaQvSIzMIv8msBb6lFps8cv/Ji1spDTY4wqB1s8=
github.com/dymensionxyz/hyperlane-cosmos v0.0.0-20250604142341-c9b00acb9947/go.mod h1:A/rrrIGIEq8qfybJIvpcH31GdXBLdTLp5Ww5koc7PCw=
github.com/dymensionxyz/osmosis/osmomath v0.0.6-dymension-v0.1.0.20250212133615-20c3718ed2f2 h1:/hXBQnPaH7gNvT37/br73OyaF55iq5TK8fcsvYcGcNg=
github.com/dymensionxyz/osmosis/osmomath v0.0.6-dymension-v0.1.0.20250212133615-20c3718ed2f2/go.mod h1:uCJk9ysBsOONgfPmQVDCp5altrjTnFtPtPwpRP9AQeI=
github.com/dymensionxyz/osmosis/v15 v15.2.1-0.20250518125211-85359101c419 h1:wMtODf2AcTxJiv4DRUMUGvU52ApPLX7c4eIJBqGVCUI=
Expand Down
43 changes: 43 additions & 0 deletions proto/dymensionxyz/dymension/kas/d.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
syntax = "proto3";

package dymensionxyz.dymension.kas;

import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/dymensionxyz/dymension/v3/x/kas/types";

// Kaspa transaction outpoint
// https://github.com/kaspanet/rusty-kaspa/blob/1adeae8e5e2bdf7b65265420d294a356edc6d9e6/consensus/client/src/outpoint.rs#L91
message TransactionOutpoint {
// 32 byte hash
bytes transaction_id = 1;
// pointer to the output in the transaction
uint32 index = 2;
}

// an index into a set of a dispatched Hyperlane withdrawal messages
// see
// https://github.com/dymensionxyz/hyperlane-cosmos/blob/5b73e596185ce009f7d9d412e26294c52e3108a8/x/core/keeper/query_server.go#L39
// and
// https://github.com/dymensionxyz/hyperlane-cosmos/blob/5b73e596185ce009f7d9d412e26294c52e3108a8/proto/hyperlane/core/v1/query.proto#L88-L92
message WithdrawalID {
// in stringified hex address format
string message_id = 2;
}

enum WithdrawalStatus {
WITHDRAWAL_STATUS_UNSPECIFIED = 0;
WITHDRAWAL_STATUS_UNPROCESSED = 1;
WITHDRAWAL_STATUS_PROCESSED = 2;
}

// signed by validators to attest to successfully relayed withdrawals
message ProgressIndication {
// current/'old' outpoint the validator sees on the hub
TransactionOutpoint old_outpoint = 1;
// new outpoint after processing withdrawals
TransactionOutpoint new_outpoint = 2;
// the processed withdrawals
repeated WithdrawalID processed_withdrawals = 3;
}
13 changes: 13 additions & 0 deletions proto/dymensionxyz/dymension/kas/events.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

package dymensionxyz.dymension.kas;

import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "dymensionxyz/dymension/kas/d.proto";

option go_package = "github.com/dymensionxyz/dymension/v3/x/kas/types";

message EventBootstrap {}

message EventUpdate { ProgressIndication update = 1; }
14 changes: 14 additions & 0 deletions proto/dymensionxyz/dymension/kas/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
syntax = "proto3";
package dymensionxyz.dymension.kas;

import "gogoproto/gogo.proto";
import "dymensionxyz/dymension/kas/d.proto";
option go_package = "github.com/dymensionxyz/dymension/v3/x/kas/types";

message GenesisState {
bool bootstrapped = 1;
string mailbox = 2;
string ism = 3;
TransactionOutpoint outpoint = 4;
repeated WithdrawalID processed_withdrawals = 5;
}
35 changes: 35 additions & 0 deletions proto/dymensionxyz/dymension/kas/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
syntax = "proto3";
package dymensionxyz.dymension.kas;

import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/base/query/v1beta1/pagination.proto";
import "dymensionxyz/dymension/kas/d.proto";

option go_package = "github.com/dymensionxyz/dymension/v3/x/kas/types";

service Query {

rpc WithdrawalStatus(QueryWithdrawalStatusRequest)
returns (QueryWithdrawalStatusResponse) {
option (google.api.http).get =
"/dymensionxyz/dymension/kas/withdrawal_status";
}

rpc Outpoint(QueryOutpointRequest) returns (QueryOutpointResponse) {
option (google.api.http).get = "/dymensionxyz/dymension/kas/outpoint";
}
}

message QueryWithdrawalStatusRequest {
repeated WithdrawalID withdrawal_id = 1;
}

message QueryWithdrawalStatusResponse {
repeated WithdrawalStatus status = 1;
TransactionOutpoint outpoint = 2;
}

message QueryOutpointRequest {}

message QueryOutpointResponse { TransactionOutpoint outpoint = 1; }
53 changes: 53 additions & 0 deletions proto/dymensionxyz/dymension/kas/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
syntax = "proto3";
package dymensionxyz.dymension.kas;

option go_package = "github.com/dymensionxyz/dymension/v3/x/kas/types";

import "google/protobuf/any.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "cosmos/msg/v1/msg.proto";
import "dymensionxyz/dymension/kas/d.proto";

service Msg {
option (cosmos.msg.v1.service) = true;

rpc Bootstrap(MsgBootstrap) returns (MsgBootstrapResponse);

rpc IndicateProgress(MsgIndicateProgress)
returns (MsgIndicateProgressResponse);
}

message MsgBootstrap {
option (cosmos.msg.v1.signer) = "authority";

// Authority is the address that controls the module (defaults to x/gov unless
// overwritten).
string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];

// the kaspa escrow mailbox
string mailbox = 2;

// the kaspa escrow ism
string ism = 3;

// the seed kaspa escrow outpoint
TransactionOutpoint outpoint = 4;
}

message MsgBootstrapResponse {}

message MsgIndicateProgress {
option (cosmos.msg.v1.signer) = "signer";
string signer = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];

// sig verification info
// https://github.com/dymensionxyz/hyperlane-cosmos/blob/89bed40d16e362c92c12166aa0f86f3db42b3db7/x/core/01_interchain_security/types/message_id_multisig_raw.go#L48
bytes metadata = 2;

// what is signed by validators
ProgressIndication payload = 3;
}

message MsgIndicateProgressResponse {}
22 changes: 22 additions & 0 deletions x/kas/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cli

import (
"fmt"

"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/cobra"

"github.com/dymensionxyz/dymension/v3/x/kas/types"
)

func GetQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

return cmd
}
22 changes: 22 additions & 0 deletions x/kas/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package cli

import (
"fmt"

"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/cobra"

"github.com/dymensionxyz/dymension/v3/x/kas/types"
)

func GetTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

return cmd
}
3 changes: 3 additions & 0 deletions x/kas/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Package kas does bookkeeping for the Kaspa<->Dymension Hyperlane-esque bridge.
// https://www.notion.so/dymension/ADR-Kaspa-Bridge-Implementation-206a4a51f86a803980aec7099c826fb4
package kas
8 changes: 8 additions & 0 deletions x/kas/genesis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package kas_test

import (
"testing"
)

func TestInitGenesis(t *testing.T) {
}
Loading
Loading