/ Create Transfer Stack
/ SendPacket, since it is originating from the application to core IBC:
/ transferKeeper.SendPacket -> callbacks.SendPacket -> feeKeeper.SendPacket -> channel.SendPacket
/ RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way
/ channel.RecvPacket -> fee.OnRecvPacket -> callbacks.OnRecvPacket -> transfer.OnRecvPacket
/ transfer stack contains (from top to bottom):
/ - IBC Packet Forward Middleware
/ - IBC Callbacks Middleware
/ - Transfer
/ initialise the gas limit for callbacks, recommended to be 10M for use with cosmwasm contracts
maxCallbackGas := uint64(10_000_000)
/ the keepers for the callbacks middleware
wasmStackIBCHandler := wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper)
/ create IBC module from bottom to top of stack
/ Create Transfer Stack
var transferStack porttypes.IBCModule
transferStack = transfer.NewIBCModule(app.TransferKeeper)
/ callbacks wraps the transfer stack as its base app, and uses PacketForwardKeeper as the ICS4Wrapper
/ i.e. packet-forward-middleware is higher on the stack and sits between callbacks and the ibc channel keeper
/ Since this is the lowest level middleware of the transfer stack, it should be the first entrypoint for transfer keeper's
/ WriteAcknowledgement.
cbStack := ibccallbacks.NewIBCMiddleware(transferStack, app.PacketForwardKeeper, wasmStackIBCHandler, maxCallbackGas)
transferStack = packetforward.NewIBCMiddleware(
cbStack,
app.PacketForwardKeeper,
0,
packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp,
)
app.TransferKeeper.WithICS4Wrapper(cbStack)
/ Create static IBC router, add app routes, then set and seal it
ibcRouter := porttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack)
ibcRouter.AddRoute(wasmtypes.ModuleName, wasmStackIBCHandler)
app.IBCKeeper.SetRouter(ibcRouter)