diff --git a/app/ibc-hooks/message.go b/app/ibc-hooks/message.go index 35c738df..b313eefb 100644 --- a/app/ibc-hooks/message.go +++ b/app/ibc-hooks/message.go @@ -1,6 +1,8 @@ package evm_hooks import ( + "encoding/json" + evmtypes "github.com/initia-labs/minievm/x/evm/types" ) @@ -43,3 +45,41 @@ type HookData struct { // AsyncCallback is a contract address AsyncCallback *AsyncCallback `json:"async_callback,omitempty"` } + +// asyncCallback is same as AsyncCallback. +type asyncCallback struct { + // callback id should be issued form the executor contract + Id uint64 `json:"id"` + ContractAddress string `json:"contract_address"` +} + +// asyncCallbackStringID is same as AsyncCallback but +// it has Id as string. +type asyncCallbackStringID struct { + // callback id should be issued form the executor contract + Id uint64 `json:"id,string"` + ContractAddress string `json:"contract_address"` +} + +// UnmarshalJSON implements the json unmarshaler interface. +// custom unmarshaler is required because we have to handle +// id as string and uint64. +func (a *AsyncCallback) UnmarshalJSON(bz []byte) error { + var ac asyncCallback + err := json.Unmarshal(bz, &ac) + if err != nil { + var acStr asyncCallbackStringID + err := json.Unmarshal(bz, &acStr) + if err != nil { + return err + } + + a.Id = acStr.Id + a.ContractAddress = acStr.ContractAddress + return nil + } + + a.Id = ac.Id + a.ContractAddress = ac.ContractAddress + return nil +} diff --git a/app/ibc-hooks/message_test.go b/app/ibc-hooks/message_test.go new file mode 100644 index 00000000..27833179 --- /dev/null +++ b/app/ibc-hooks/message_test.go @@ -0,0 +1,30 @@ +package evm_hooks_test + +import ( + "encoding/json" + "testing" + + evmhooks "github.com/initia-labs/minievm/app/ibc-hooks" + "github.com/stretchr/testify/require" +) + +func Test_Unmarshal_AsyncCallback(t *testing.T) { + var callback evmhooks.AsyncCallback + err := json.Unmarshal([]byte(`{ + "id": 99, + "contract_address": "0x1" + }`), &callback) + require.NoError(t, err) + require.Equal(t, evmhooks.AsyncCallback{ + Id: 99, + ContractAddress: "0x1", + }, callback) + + var callbackStringID evmhooks.AsyncCallback + err = json.Unmarshal([]byte(`{ + "id": "99", + "contract_address": "0x1" + }`), &callbackStringID) + require.NoError(t, err) + require.Equal(t, callback, callbackStringID) +}