Skip to content

Commit 69b8971

Browse files
AdityaSripalcrodriguezvegacolin-axnerexpertdicerdependabot[bot]
authored
ADR 8 Interface and Packet Data Implementations (#3287)
* adr 8 with 20/27 implementation * change interface name and register codecs * documentation * add comma before new line * fix return arg and dest for ica * add ica tests * adr 8 callback packet data impl followups (#3325) * remove query client (#3227) * remove query client * merge main * go mod tidy * Rename ``IsBound`` to ``HasCapability`` (#3253) ## Description closes: #828 ### Commit Message / Changelog Entry ```bash imp(api!): rename `IsBound` to `HasCapability` for IBC application modules ``` see the [guidelines](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) for commit messages. (view raw markdown for examples) --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#pull-request-targeting)). - [x] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [x] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/10-structure.md) and [Go style guide](../docs/dev/go-style-guide.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/main/testing/README.md#ibc-testing-package). - [ ] Updated relevant documentation (`docs/`) or specification (`x/<module>/spec/`). - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Provide a [commit message](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) to be used for the changelog entry in the PR description for review. - [ ] Re-reviewed `Files changed` in the Github PR explorer. - [ ] Review `Codecov Report` in the comment section below once CI passes. * chore: add support for tendermint debug log level (#3279) * build(deps): bump cosmossdk.io/math from 1.0.0-beta.6.0.20230216172121-959ce49135e4 to 1.0.0-rc.0 (#3285) Bumps [cosmossdk.io/math](https://github.com/cosmos/cosmos-sdk) from 1.0.0-beta.6.0.20230216172121-959ce49135e4 to 1.0.0-rc.0. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/cosmos/cosmos-sdk/commits/math/v1.0.0-rc.0">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=cosmossdk.io/math&package-manager=go_modules&previous-version=1.0.0-beta.6.0.20230216172121-959ce49135e4&new-version=1.0.0-rc.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> * Write docker inspect output to diagnostics (#3291) * chore: fix dead links (#3293) ## Description closes: #XXXX ### Commit Message / Changelog Entry ```bash type: commit message ``` see the [guidelines](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) for commit messages. (view raw markdown for examples) --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [x] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#pull-request-targeting)). - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/10-structure.md) and [Go style guide](../docs/dev/go-style-guide.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/main/testing/README.md#ibc-testing-package). - [ ] Updated relevant documentation (`docs/`) or specification (`x/<module>/spec/`). - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Provide a [commit message](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) to be used for the changelog entry in the PR description for review. - [x] Re-reviewed `Files changed` in the Github PR explorer. - [ ] Review `Codecov Report` in the comment section below once CI passes. * build(deps): bump google.golang.org/protobuf from 1.29.0 to 1.29.1 (#3292) * deps: bump SDK v0.47 (#3295) Co-authored-by: Damian Nolan <damiannolan@gmail.com> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * remove unnecessary import from doc * chore: remove support for v3 (#3294) * build(deps): bump actions/setup-go from 3 to 4 (#3307) * imp: remove unnecessary defer func statements (#3304) * Remove gogoproto yaml tags from proto files (#3290) ## Description Refer from original issue, I removed all `yaml` tags in proto files. closes: #3145 ### Commit Message / Changelog Entry ```bash type: commit message ``` see the [guidelines](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) for commit messages. (view raw markdown for examples) --- Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why. - [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#pull-request-targeting)). - [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work. - [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules/10-structure.md) and [Go style guide](../docs/dev/go-style-guide.md). - [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/main/testing/README.md#ibc-testing-package). - [ ] Updated relevant documentation (`docs/`) or specification (`x/<module>/spec/`). - [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code). - [ ] Provide a [commit message](https://github.com/cosmos/ibc-go/blob/main/docs/dev/pull-requests.md#commit-messages) to be used for the changelog entry in the PR description for review. - [ ] Re-reviewed `Files changed` in the Github PR explorer. - [ ] Review `Codecov Report` in the comment section below once CI passes. * add reasoning for migration to enable localhost * Support configuration file for e2e tests (#3260) * E2E fzf Test Selection Autocompletion (#3313) * post v7 release chores (#3310) * chore: fix linter warnings (#3311) * ADR 008: IBC Actor Callbacks (#1976) * context and decision * complete adr * Apply suggestions from code review Co-authored-by: Carlos Rodriguez <carlos@interchain.io> * change from caller to generalized actor * Apply suggestions from code review Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * create folder and scaffolded middleware * add error handling and generify packetdata interface * complete renaming * add user defined gas limit and clarify pseudocode * Clarify CallbackPacketData interface imp: Add ADR 008: IBC Actor Callbacks --------- Co-authored-by: Carlos Rodriguez <carlos@interchain.io> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * lint: fix spelling * chore: apply self review concerns * chore: rename CallbackPacketDataI to CallbackPacketData * chore: finish applying remaining review suggestions * test: add remaining unit tests for transfer and ica * test: add unmarshaling test * imp: address ADR 8 review suggestions (#3319) --------- Co-authored-by: Damian Nolan <damiannolan@gmail.com> * Bump interchain test (#3314) * fix: remove codec registration * fix: build + linting * Only run e2e on R4R (#3330) * fix fork workflows (#3328) * Revert "Merge branch 'main' of github.com:cosmos/ibc-go into colin/callback-packet-data-impl" This reverts commit 1c6164b, reversing changes made to 6f25b8e. * chore: add optional interface godoc * Apply suggestions from code review Co-authored-by: Carlos Rodriguez <carlos@interchain.io> * chore: use backticks instead of escape characters in testing --------- Co-authored-by: Lặc <67097720+expertdicer@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cian Hatton <cian@interchain.io> Co-authored-by: Carlos Rodriguez <carlos@interchain.io> Co-authored-by: Damian Nolan <damiannolan@gmail.com> Co-authored-by: GNaD13 <89174180+GNaD13@users.noreply.github.com> Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com> Co-authored-by: Aditya <adityasripal@gmail.com> * fix: merge conflicts * chore: nits from self review * chore: add link to ADR 008 in godoc --------- Co-authored-by: Carlos Rodriguez <carlos@interchain.io> Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> Co-authored-by: Lặc <67097720+expertdicer@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cian Hatton <cian@interchain.io> Co-authored-by: Damian Nolan <damiannolan@gmail.com> Co-authored-by: GNaD13 <89174180+GNaD13@users.noreply.github.com> Co-authored-by: Hieu Vu <72878483+hieuvubk@users.noreply.github.com>
1 parent 9fbeb1c commit 69b8971

File tree

7 files changed

+569
-24
lines changed

7 files changed

+569
-24
lines changed

modules/apps/27-interchain-accounts/types/packet.go

+75
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package types
22

33
import (
4+
"encoding/json"
45
"time"
56

67
errorsmod "cosmossdk.io/errors"
78
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
89
sdk "github.com/cosmos/cosmos-sdk/types"
10+
"github.com/cosmos/ibc-go/v7/modules/core/exported"
911
)
1012

1113
// MaxMemoCharLength defines the maximum length for the InterchainAccountPacketData memo field
@@ -24,6 +26,8 @@ var (
2426
DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds())
2527
)
2628

29+
var _ exported.CallbackPacketData = (*InterchainAccountPacketData)(nil)
30+
2731
// ValidateBasic performs basic validation of the interchain account packet data.
2832
// The memo may be empty.
2933
func (iapd InterchainAccountPacketData) ValidateBasic() error {
@@ -47,6 +51,77 @@ func (iapd InterchainAccountPacketData) GetBytes() []byte {
4751
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&iapd))
4852
}
4953

54+
/*
55+
56+
ADR-8 CallbackPacketData implementation
57+
58+
InterchainAccountPacketData implements CallbackPacketData interface. This will allow middlewares targeting specific VMs
59+
to retrieve the desired callback address for the ICA packet on the source chain. Destination callback addresses are not
60+
supported for ICS 27.
61+
62+
The Memo is used to set the desired callback addresses.
63+
64+
The Memo format is defined like so:
65+
66+
```json
67+
{
68+
// ... other memo fields we don't care about
69+
"callbacks": {
70+
"src_callback_address": {contractAddrOnSourceChain},
71+
72+
// optional fields
73+
"src_callback_msg": {jsonObjectForSourceChainCallback},
74+
}
75+
}
76+
```
77+
78+
*/
79+
80+
// GetSourceCallbackAddress returns the source callback address provided in the packet data memo.
81+
// If no callback address is specified, an empty string is returned.
82+
//
83+
// The memo is expected to specify the callback address in the following format:
84+
// { "callbacks": { "src_callback_address": {contractAddrOnSourceChain}}
85+
//
86+
// ADR-8 middleware should callback on the returned address if it is a PacketActor
87+
// (i.e. smart contract that accepts IBC callbacks).
88+
func (iapd InterchainAccountPacketData) GetSourceCallbackAddress() string {
89+
if len(iapd.Memo) == 0 {
90+
return ""
91+
}
92+
93+
jsonObject := make(map[string]interface{})
94+
err := json.Unmarshal([]byte(iapd.Memo), &jsonObject)
95+
if err != nil {
96+
return ""
97+
}
98+
99+
callbackData, ok := jsonObject["callbacks"].(map[string]interface{})
100+
if !ok {
101+
return ""
102+
}
103+
104+
callbackAddr, ok := callbackData["src_callback_address"].(string)
105+
if !ok {
106+
return ""
107+
}
108+
109+
return callbackAddr
110+
}
111+
112+
// GetDestCallbackAddress returns an empty string. Destination callback addresses
113+
// are not supported for ICS 27. This feature is natively supported by
114+
// interchain accounts host submodule transaction execution.
115+
func (iapd InterchainAccountPacketData) GetDestCallbackAddress() string {
116+
return ""
117+
}
118+
119+
// UserDefinedGasLimit returns 0 (no-op). The gas limit of the executing
120+
// transaction will be used.
121+
func (iapd InterchainAccountPacketData) UserDefinedGasLimit() uint64 {
122+
return 0
123+
}
124+
50125
// GetBytes returns the JSON marshalled interchain account CosmosTx.
51126
func (ct CosmosTx) GetBytes() []byte {
52127
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&ct))

modules/apps/27-interchain-accounts/types/packet_test.go

+122
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package types_test
22

33
import (
4+
"fmt"
5+
46
"github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
57
)
68

@@ -82,3 +84,123 @@ func (suite *TypesTestSuite) TestValidateBasic() {
8284
})
8385
}
8486
}
87+
88+
func (suite *TypesTestSuite) TestGetSourceCallbackAddress() {
89+
const expSrcCbAddr = "srcCbAddr"
90+
91+
testCases := []struct {
92+
name string
93+
packetData types.InterchainAccountPacketData
94+
expPass bool
95+
}{
96+
{
97+
"memo is empty",
98+
types.InterchainAccountPacketData{
99+
Type: types.EXECUTE_TX,
100+
Data: []byte("data"),
101+
Memo: "",
102+
},
103+
false,
104+
},
105+
{
106+
"memo is not json string",
107+
types.InterchainAccountPacketData{
108+
Type: types.EXECUTE_TX,
109+
Data: []byte("data"),
110+
Memo: "memo",
111+
},
112+
false,
113+
},
114+
{
115+
"memo does not have callbacks in json struct",
116+
types.InterchainAccountPacketData{
117+
Type: types.EXECUTE_TX,
118+
Data: []byte("data"),
119+
Memo: `{"Key": 10}`,
120+
},
121+
false,
122+
},
123+
{
124+
"memo has callbacks in json struct but does not have src_callback_address key",
125+
types.InterchainAccountPacketData{
126+
Type: types.EXECUTE_TX,
127+
Data: []byte("data"),
128+
Memo: `{"callbacks": {"Key": 10}}`,
129+
},
130+
false,
131+
},
132+
{
133+
"memo has callbacks in json struct but does not have string value for src_callback_address key",
134+
types.InterchainAccountPacketData{
135+
Type: types.EXECUTE_TX,
136+
Data: []byte("data"),
137+
Memo: `{"callbacks": {"src_callback_address": 10}}`,
138+
},
139+
false,
140+
},
141+
{
142+
"memo has callbacks in json struct and properly formatted src_callback_address",
143+
types.InterchainAccountPacketData{
144+
Type: types.EXECUTE_TX,
145+
Data: []byte("data"),
146+
Memo: fmt.Sprintf(`{"callbacks": {"src_callback_address": "%s"}}`, expSrcCbAddr),
147+
},
148+
true,
149+
},
150+
}
151+
152+
for _, tc := range testCases {
153+
tc := tc
154+
suite.Run(tc.name, func() {
155+
srcCbAddr := tc.packetData.GetSourceCallbackAddress()
156+
157+
if tc.expPass {
158+
suite.Require().Equal(expSrcCbAddr, srcCbAddr)
159+
} else {
160+
suite.Require().Equal("", srcCbAddr)
161+
}
162+
})
163+
}
164+
}
165+
166+
func (suite *TypesTestSuite) TestGetDestCallbackAddress() {
167+
testCases := []struct {
168+
name string
169+
packetData types.InterchainAccountPacketData
170+
}{
171+
{
172+
"memo is empty",
173+
types.InterchainAccountPacketData{
174+
Type: types.EXECUTE_TX,
175+
Data: []byte("data"),
176+
Memo: "",
177+
},
178+
},
179+
{
180+
"memo has dest callback address specified in json struct",
181+
types.InterchainAccountPacketData{
182+
Type: types.EXECUTE_TX,
183+
Data: []byte("data"),
184+
Memo: `{"callbacks": {"dest_callback_address": "testAddress"}}`,
185+
},
186+
},
187+
}
188+
189+
for _, tc := range testCases {
190+
tc := tc
191+
suite.Run(tc.name, func() {
192+
destCbAddr := tc.packetData.GetDestCallbackAddress()
193+
suite.Require().Equal("", destCbAddr)
194+
})
195+
}
196+
}
197+
198+
func (suite *TypesTestSuite) TestUserDefinedGasLimit() {
199+
packetData := types.InterchainAccountPacketData{
200+
Type: types.EXECUTE_TX,
201+
Data: []byte("data"),
202+
Memo: `{"callbacks": {"user_defined_gas_limit": 100}}`,
203+
}
204+
205+
suite.Require().Equal(uint64(0), packetData.UserDefinedGasLimit(), "user defined gas limit does not return 0")
206+
}

modules/apps/transfer/types/codec.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ package types
33
import (
44
"bytes"
55

6-
"github.com/cosmos/cosmos-sdk/x/authz"
7-
"github.com/cosmos/gogoproto/jsonpb"
8-
"github.com/cosmos/gogoproto/proto"
9-
106
"github.com/cosmos/cosmos-sdk/codec"
117
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
128
sdk "github.com/cosmos/cosmos-sdk/types"
139
"github.com/cosmos/cosmos-sdk/types/msgservice"
10+
"github.com/cosmos/cosmos-sdk/x/authz"
11+
"github.com/cosmos/gogoproto/jsonpb"
12+
"github.com/cosmos/gogoproto/proto"
1413
)
1514

1615
// RegisterLegacyAminoCodec registers the necessary x/ibc transfer interfaces and concrete types

modules/apps/transfer/types/packet.go

+110
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
package types
22

33
import (
4+
"encoding/json"
45
"strings"
56
"time"
67

78
errorsmod "cosmossdk.io/errors"
89
sdk "github.com/cosmos/cosmos-sdk/types"
910

1011
ibcerrors "github.com/cosmos/ibc-go/v7/internal/errors"
12+
"github.com/cosmos/ibc-go/v7/modules/core/exported"
1113
)
1214

1315
var (
@@ -23,6 +25,8 @@ var (
2325
DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds())
2426
)
2527

28+
var _ exported.CallbackPacketData = (*FungibleTokenPacketData)(nil)
29+
2630
// NewFungibleTokenPacketData contructs a new FungibleTokenPacketData instance
2731
func NewFungibleTokenPacketData(
2832
denom string, amount string,
@@ -62,3 +66,109 @@ func (ftpd FungibleTokenPacketData) ValidateBasic() error {
6266
func (ftpd FungibleTokenPacketData) GetBytes() []byte {
6367
return sdk.MustSortJSON(mustProtoMarshalJSON(&ftpd))
6468
}
69+
70+
/*
71+
72+
ADR-8 CallbackPacketData implementation
73+
74+
FungibleTokenPacketData implements CallbackPacketData interface. This will allow middlewares targeting specific VMs
75+
to retrieve the desired callback addresses for the ICS20 packet on the source and destination chains.
76+
77+
The Memo is used to ensure that the callback is desired by the user. This allows a user to send an ICS20 packet
78+
to a contract with ADR-8 enabled without automatically triggering the callback logic which may lead to unexpected
79+
behaviour.
80+
81+
The Memo format is defined like so:
82+
83+
```json
84+
{
85+
// ... other memo fields we don't care about
86+
"callbacks": {
87+
"src_callback_address": {contractAddrOnSourceChain},
88+
"dest_callback_address": {contractAddrOnDestChain},
89+
90+
// optional fields
91+
"src_callback_msg": {jsonObjectForSourceChainCallback},
92+
"dest_callback_msg": {jsonObjectForDestChainCallback},
93+
}
94+
}
95+
```
96+
97+
For transfer, we will enforce that the src_callback_address is the same as sender and dest_callback_address is the same as receiver.
98+
However, we may remove this restriction at a later date if it proves useful.
99+
100+
*/
101+
102+
// GetSourceCallbackAddress returns the sender address if it is also specified in
103+
// the packet data memo. The desired callback address must be confirmed in the
104+
// memo under the "callbacks" key. This ensures that the callback is explicitly
105+
// desired by the user and not called automatically. If no callback address is
106+
// specified, an empty string is returned.
107+
//
108+
// The memo is expected to contain the source callback address in the following format:
109+
// { "callbacks": { "src_callback_address": {contractAddrOnSourceChain}}
110+
//
111+
// ADR-8 middleware should callback on the returned address if it is a PacketActor
112+
// (i.e. smart contract that accepts IBC callbacks).
113+
func (ftpd FungibleTokenPacketData) GetSourceCallbackAddress() string {
114+
if len(ftpd.Memo) == 0 {
115+
return ""
116+
}
117+
118+
jsonObject := make(map[string]interface{})
119+
err := json.Unmarshal([]byte(ftpd.Memo), &jsonObject)
120+
if err != nil {
121+
return ""
122+
}
123+
124+
callbackData, ok := jsonObject["callbacks"].(map[string]interface{})
125+
if !ok {
126+
return ""
127+
}
128+
129+
if callbackData["src_callback_address"] == ftpd.Sender {
130+
return ftpd.Sender
131+
}
132+
133+
return ""
134+
}
135+
136+
// GetDestCallbackAddress returns the receiving address if it is also specified in
137+
// the packet data memo. The desired callback address must be confirmed in the
138+
// memo under the "callbacks" key. This ensures that the callback is explicitly
139+
// desired by the user and not called automatically. If no callback address is
140+
// specified, an empty string is returned.
141+
//
142+
// The memo is expected to contain the destination callback address in the following format:
143+
// { "callbacks": { "dest_callback_address": {contractAddrOnDestChain}}
144+
//
145+
// ADR-8 middleware should callback on the returned address if it is a PacketActor
146+
// (i.e. smart contract that accepts IBC callbacks).
147+
func (ftpd FungibleTokenPacketData) GetDestCallbackAddress() string {
148+
if len(ftpd.Memo) == 0 {
149+
return ""
150+
}
151+
152+
jsonObject := make(map[string]interface{})
153+
err := json.Unmarshal([]byte(ftpd.Memo), &jsonObject)
154+
if err != nil {
155+
return ""
156+
}
157+
158+
callbackData, ok := jsonObject["callbacks"].(map[string]interface{})
159+
if !ok {
160+
return ""
161+
}
162+
163+
if callbackData["dest_callback_address"] == ftpd.Receiver {
164+
return ftpd.Receiver
165+
}
166+
167+
return ""
168+
}
169+
170+
// UserDefinedGasLimit returns 0 (no-op). The gas limit of the executing
171+
// transaction will be used.
172+
func (ftpd FungibleTokenPacketData) UserDefinedGasLimit() uint64 {
173+
return 0
174+
}

0 commit comments

Comments
 (0)