Skip to content

Commit

Permalink
create account if nft receipient account is not existing (#319)
Browse files Browse the repository at this point in the history
  • Loading branch information
beer-1 authored Dec 16, 2024
1 parent e2fbf0f commit c4b2bf7
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
39 changes: 37 additions & 2 deletions x/ibc/nft-transfer/keeper/integration_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package keeper_test

import (
"crypto/rand"

channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v8/modules/core/24-host"

sdktypes "github.com/cosmos/cosmos-sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/initia-labs/initia/x/ibc/nft-transfer/types"
ibctesting "github.com/initia-labs/initia/x/ibc/testing"
Expand Down Expand Up @@ -51,7 +53,7 @@ func (suite *KeeperTestSuite) CreateNftClass(

func (suite *KeeperTestSuite) MintNft(
endpoint *ibctesting.Endpoint,
receiver sdktypes.AccAddress,
receiver sdk.AccAddress,
classId, className, tokenId, tokenUri, tokenData string,
) {
classNameBz, err := vmtypes.SerializeString(className)
Expand Down Expand Up @@ -224,6 +226,39 @@ func (suite *KeeperTestSuite) TestSendAndReceive() {
suite.ConfirmClassId(pathA2B.EndpointA, classId, targetClassId)
}
})

// transfer from chainA to chainB (non-existing account)
suite.Run("transfer A->B (non-existing account)", func() {
{
sender := pathA2B.EndpointA.Chain.SenderAccount.GetAddress()

// random receiver account
receiver := make(sdk.AccAddress, 20)
_, err := rand.Read(receiver)
suite.NoError(err)

packet = suite.transferNft(
pathA2B.EndpointA,
pathA2B.EndpointB,
targetClassId,
nftId,
sender.String(),
receiver.String(),
)

targetClassId = suite.receiverNft(
pathA2B.EndpointA,
pathA2B.EndpointB,
packet,
)

suite.ConfirmClassId(pathA2B.EndpointB, classId, targetClassId)

// receiver account should be created
suite.True(suite.chainB.App.GetAccountKeeper().HasAccount(suite.chainB.GetContext(), receiver))
}
})

}

func (suite *KeeperTestSuite) transferNft(
Expand Down
5 changes: 5 additions & 0 deletions x/ibc/nft-transfer/keeper/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t
return err
}

// create account if receiver does not exist
if !k.authKeeper.HasAccount(ctx, receiver) {
k.authKeeper.SetAccount(ctx, k.authKeeper.NewAccountWithAddress(ctx, receiver))
}

labels := []metrics.Label{
telemetry.NewLabel(coretypes.LabelSourcePort, packet.GetSourcePort()),
telemetry.NewLabel(coretypes.LabelSourceChannel, packet.GetSourceChannel()),
Expand Down
4 changes: 4 additions & 0 deletions x/ibc/nft-transfer/types/expected_keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ type AccountKeeper interface {
AddressCodec() address.Codec
GetModuleAddress(name string) sdk.AccAddress
GetModuleAccount(ctx context.Context, name string) sdk.ModuleAccountI

SetAccount(ctx context.Context, acc sdk.AccountI)
HasAccount(ctx context.Context, addr sdk.AccAddress) bool
NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI
}

type NftKeeper interface {
Expand Down

0 comments on commit c4b2bf7

Please sign in to comment.