Repository: desmos-labs/desmos
Pull request #838 (2022-04-22 12:00:00)

fix: simplify x/relationships store keys
## Description

This PR updates the `x/relationships` store keys to use single bytes instead of string prefixes, to slim the storage space.

<!-- Add a description of the changes that this PR introduces and the files that
are the most critical to review. -->

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://docs.cosmos.network/v0.44/building-modules/intro.html)
- [x] included the necessary unit and integration [tests](https://github.com/desmos-labs/desmos/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [x] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [x] reviewed "Files changed" and left comments if necessary
- [x] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [x] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [x] confirmed all author checklist items have been addressed
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [x] reviewed tests and test coverage
- [ ] manually tested (if applicable)

codecov[bot]: # [Codecov](https://codecov.io/gh/desmos-labs/desmos/pull/838?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs) Report
> Merging [#838](https://codecov.io/gh/desmos-labs/desmos/pull/838?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs) (8a062eb) into [master](https://codecov.io/gh/desmos-labs/desmos/commit/c6847685f83f4da2aa99d1d99923e7f995b998f4?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs) (c684768) will **decrease** coverage by `0.21%`.
> The diff coverage is `62.50%`.

```diff
@@            Coverage Diff             @@
##           master     #838      +/-   ##
==========================================
- Coverage   81.53%   81.31%   -0.22%     
==========================================
  Files          89       91       +2     
  Lines        7018     7098      +80     
==========================================
+ Hits         5722     5772      +50     
- Misses       1035     1059      +24     
- Partials      261      267       +6     
```


| [Impacted Files](https://codecov.io/gh/desmos-labs/desmos/pull/838?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs) | Coverage Δ | |
|---|---|---|
| [x/relationships/legacy/v1/keys.go](https://codecov.io/gh/desmos-labs/desmos/pull/838/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs#diff-eC9yZWxhdGlvbnNoaXBzL2xlZ2FjeS92MS9rZXlzLmdv) | `0.00% <0.00%> (ø)` | |
| [x/relationships/legacy/v2/store.go](https://codecov.io/gh/desmos-labs/desmos/pull/838/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs#diff-eC9yZWxhdGlvbnNoaXBzL2xlZ2FjeS92Mi9zdG9yZS5nbw==) | `73.52% <73.52%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/desmos-labs/desmos/pull/838?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/desmos-labs/desmos/pull/838?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs). Last update [7ef1a5b...8a062eb](https://codecov.io/gh/desmos-labs/desmos/pull/838?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=desmos-labs).


Patch:
diff --git a/.changeset/entries/6f0a061bd4ae3038eb8a5a71d9a3b1e6b88397a4e785bda00fec5fbd8bd0737b.yaml b/.changeset/entries/6f0a061bd4ae3038eb8a5a71d9a3b1e6b88397a4e785bda00fec5fbd8bd0737b.yaml
new file mode 100644
index 00000000..f0add99b
--- /dev/null
+++ b/.changeset/entries/6f0a061bd4ae3038eb8a5a71d9a3b1e6b88397a4e785bda00fec5fbd8bd0737b.yaml
@@ -0,0 +1,6 @@
+type: fix
+module: x/relationships
+pull_request: 838
+description: Replaced store keys to use less disk space
+backward_compatible: false
+date: 2022-04-22T12:01:24.865079216Z
diff --git a/.changeset/entries/8fea7719728d408975e08ec2ca629f6241c68afe263cc5897d7ebcb0856b4520.yaml b/.changeset/entries/8fea7719728d408975e08ec2ca629f6241c68afe263cc5897d7ebcb0856b4520.yaml
new file mode 100644
index 00000000..bad9b00f
--- /dev/null
+++ b/.changeset/entries/8fea7719728d408975e08ec2ca629f6241c68afe263cc5897d7ebcb0856b4520.yaml
@@ -0,0 +1,6 @@
+type: fix
+module: x/profiles
+pull_request: 832
+description: Fixed the CLI commands expected number of arguments
+backward_compatible: true
+date: 2022-04-22T05:53:09.198350555Z
diff --git a/.changeset/entries/bc776b2301982eaae47a6da9ac287a76dace06b0cb1cab882868d56c021dffdc.yaml b/.changeset/entries/bc776b2301982eaae47a6da9ac287a76dace06b0cb1cab882868d56c021dffdc.yaml
new file mode 100644
index 00000000..abf52d9f
--- /dev/null
+++ b/.changeset/entries/bc776b2301982eaae47a6da9ac287a76dace06b0cb1cab882868d56c021dffdc.yaml
@@ -0,0 +1,6 @@
+type: fix
+module: other
+pull_request: 829
+description: Added missing events and events attributes
+backward_compatible: true
+date: 2022-04-21T07:31:55.785338327Z
diff --git a/.changeset/entries/fc7708b5917c157edbbc96281bba1a63928dd2becf8fd057cd3d9592a88f1798.yaml b/.changeset/entries/fc7708b5917c157edbbc96281bba1a63928dd2becf8fd057cd3d9592a88f1798.yaml
new file mode 100644
index 00000000..59e2d2ee
--- /dev/null
+++ b/.changeset/entries/fc7708b5917c157edbbc96281bba1a63928dd2becf8fd057cd3d9592a88f1798.yaml
@@ -0,0 +1,6 @@
+type: fix
+module: x/profiles
+pull_request: 831
+description: Renamed the `dtag_transfer_requests` REST endpoint to `dtag-transfer-requests`
+backward_compatible: false
+date: 2022-04-22T05:44:24.874087179Z
diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml
index b4817463..e8ee1dcd 100644
--- a/.github/workflows/lint-pr.yml
+++ b/.github/workflows/lint-pr.yml
@@ -11,6 +11,6 @@ jobs:
   main:
     runs-on: ubuntu-latest
     steps:
-      - uses: amannn/action-semantic-pull-request@v4.3.0
+      - uses: amannn/action-semantic-pull-request@v4.4.0
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml
index 6d97753a..705ee85a 100644
--- a/client/docs/swagger-ui/swagger.yaml
+++ b/client/docs/swagger-ui/swagger.yaml
@@ -2329,7 +2329,7 @@ paths:
           format: boolean
       tags:
         - Query
-  /desmos/profiles/v2/dtag_transfer_requests:
+  /desmos/profiles/v2/dtag-transfer-requests:
     get:
       summary: >-
         IncomingDTagTransferRequests queries all the DTag transfers requests
diff --git a/proto/desmos/profiles/v2/query.proto b/proto/desmos/profiles/v2/query.proto
index 7a5d7d3b..023aa98c 100644
--- a/proto/desmos/profiles/v2/query.proto
+++ b/proto/desmos/profiles/v2/query.proto
@@ -27,7 +27,7 @@ service Query {
   // have been made towards the user with the given address
   rpc IncomingDTagTransferRequests(QueryIncomingDTagTransferRequestsRequest)
       returns (QueryIncomingDTagTransferRequestsResponse) {
-    option (google.api.http).get = "/desmos/profiles/v2/dtag_transfer_requests";
+    option (google.api.http).get = "/desmos/profiles/v2/dtag-transfer-requests";
   }
 
   // ChainLinks queries the chain links associated to the given user, if
diff --git a/proto/desmos/supply/v1/query.proto b/proto/desmos/supply/v1/query.proto
index 86bede92..2985e932 100644
--- a/proto/desmos/supply/v1/query.proto
+++ b/proto/desmos/supply/v1/query.proto
@@ -10,20 +10,20 @@ import "cosmos/base/v1beta1/coin.proto";
 
 option go_package = "github.com/desmos-labs/desmos/v3/x/supply/types";
 
-
 // Query defines the gRPC querier service.
 service Query {
 
   // TotalSupply queries the total supply of the given denom
-  rpc TotalSupply(QueryTotalSupplyRequest)
-      returns (QueryTotalSupplyResponse) {
+  rpc TotalSupply(QueryTotalSupplyRequest) returns (QueryTotalSupplyResponse) {
     option (google.api.http).get = "/desmos/supply/v1/total-supply/{denom}";
   }
 
-  // CirculatingSupply queries the amount of tokens circulating in the market of the given denom
+  // CirculatingSupply queries the amount of tokens circulating in the market of
+  // the given denom
   rpc CirculatingSupply(QueryCirculatingSupplyRequest)
       returns (QueryCirculatingSupplyResponse) {
-    option (google.api.http).get = "/desmos/supply/v1/circulating-supply/{denom}";
+    option (google.api.http).get =
+        "/desmos/supply/v1/circulating-supply/{denom}";
   }
 }
 
@@ -35,11 +35,13 @@ message QueryTotalSupplyRequest {
   // coin denom to query the circulating supply for
   string denom = 1;
 
-  // divider_exponent is a factor used to power the divider used to convert the supply to the desired representation
+  // divider_exponent is a factor used to power the divider used to convert the
+  // supply to the desired representation
   uint64 divider_exponent = 2;
 }
 
-// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC method
+// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC
+// method
 message QueryTotalSupplyResponse {
   option (gogoproto.equal) = false;
   option (gogoproto.goproto_getters) = false;
@@ -50,7 +52,8 @@ message QueryTotalSupplyResponse {
   ];
 }
 
-// QueryCirculatingSupplyRequest is the request type for the Query/CirculatingSupply RPC method
+// QueryCirculatingSupplyRequest is the request type for the
+// Query/CirculatingSupply RPC method
 message QueryCirculatingSupplyRequest {
   option (gogoproto.equal) = false;
   option (gogoproto.goproto_getters) = false;
@@ -58,11 +61,13 @@ message QueryCirculatingSupplyRequest {
   // coin denom to query the circulating supply for
   string denom = 1;
 
-  // divider_exponent is a factor used to power the divider used to convert the supply to the desired representation
+  // divider_exponent is a factor used to power the divider used to convert the
+  // supply to the desired representation
   uint64 divider_exponent = 2;
 }
 
-// QueryCirculatingSupplyRequest is the response type for the Query/CirculatingSupply RPC method
+// QueryCirculatingSupplyRequest is the response type for the
+// Query/CirculatingSupply RPC method
 message QueryCirculatingSupplyResponse {
   option (gogoproto.equal) = false;
   option (gogoproto.goproto_getters) = false;
diff --git a/x/fees/types/params.go b/x/fees/types/params.go
index 82d41f1b..77a321dc 100644
--- a/x/fees/types/params.go
+++ b/x/fees/types/params.go
@@ -60,7 +60,21 @@ func ValidateMinFeesParam(i interface{}) error {
 		if err := fee.Validate(); err != nil {
 			return err
 		}
+
+		if isMinFeeDuplicated(fee, fees) {
+			return fmt.Errorf("duplicated min fee for message type %s", fee.MessageType)
+		}
 	}
 
 	return nil
 }
+
+func isMinFeeDuplicated(value MinFee, minFees []MinFee) bool {
+	var count = 0
+	for _, fee := range minFees {
+		if fee.MessageType == value.MessageType {
+			count++
+		}
+	}
+	return count > 1
+}
diff --git a/x/profiles/client/cli/cli_chain_links.go b/x/profiles/client/cli/cli_chain_links.go
index 4546db45..0421abe0 100644
--- a/x/profiles/client/cli/cli_chain_links.go
+++ b/x/profiles/client/cli/cli_chain_links.go
@@ -26,7 +26,7 @@ func GetCmdLinkChainAccount() *cobra.Command {
 The link data must be supplied via a JSON file.
 
 Example:
-$ %s tx profiles link <path/to/data.json> --from=<key_or_address>
+$ %s tx profiles link-chain <path/to/data.json> --from=<key_or_address>
 
 Where data.json contains:
 
@@ -121,7 +121,7 @@ func GetCmdQueryChainLinks() *cobra.Command {
 %s query profiles chain-links desmos13p5pamrljhza3fp4es5m3llgmnde5fzcpq6nud "cosmos"
 %s query profiles chain-links desmos13p5pamrljhza3fp4es5m3llgmnde5fzcpq6nud "cosmos" cosmos19s242dxhxgzlsdmfjjg38jgfwhxca7569g84sw
 `, version.AppName, version.AppName, version.AppName, version.AppName, version.AppName),
-		Args: cobra.RangeArgs(0, 1),
+		Args: cobra.RangeArgs(0, 3),
 		RunE: func(cmd *cobra.Command, args []string) error {
 			clientCtx, err := client.GetClientQueryContext(cmd)
 			if err != nil {
diff --git a/x/profiles/client/cli/cli_dtag_requests.go b/x/profiles/client/cli/cli_dtag_requests.go
index 89301149..bee877db 100644
--- a/x/profiles/client/cli/cli_dtag_requests.go
+++ b/x/profiles/client/cli/cli_dtag_requests.go
@@ -81,8 +81,10 @@ func GetCmdCancelDTagTransfer() *cobra.Command {
 // GetCmdAcceptDTagTransfer returns the command to accept a DTag transfer request
 func GetCmdAcceptDTagTransfer() *cobra.Command {
 	cmd := &cobra.Command{
-		Use: "accept-dtag-transfer-request [DTag] [address]",
-		Short: `Accept a DTag transfer request made by the user with the given address.
+		Use:   "accept-dtag-transfer-request [DTag] [address]",
+		Short: `Accept a DTag transfer request made by another user towards you`,
+		Long: `Accept a DTag transfer request made by the user with the given address.
+
 When accepting the request, you can specify the request recipient DTag as your new DTag. 
 If this happens, your DTag and the other user's one will be effectively swapped.`,
 		Example: fmt.Sprintf(`%s tx profiles accept-dtag-transfer-request "leoDiCaprio" desmos13p5pamrljhza3fp4es5m3llgmnde5fzcpq6nud`, version.AppName),
diff --git a/x/profiles/keeper/msg_server_app_link.go b/x/profiles/keeper/msg_server_app_link.go
index d842b421..36b093ab 100644
--- a/x/profiles/keeper/msg_server_app_link.go
+++ b/x/profiles/keeper/msg_server_app_link.go
@@ -50,6 +50,7 @@ func (k Keeper) LinkApplication(
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
 		),
 		sdk.NewEvent(
@@ -91,6 +92,7 @@ func (k msgServer) UnlinkApplication(
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
diff --git a/x/profiles/keeper/msg_server_chain_link.go b/x/profiles/keeper/msg_server_chain_link.go
index 1b976a2f..bdb7d288 100644
--- a/x/profiles/keeper/msg_server_chain_link.go
+++ b/x/profiles/keeper/msg_server_chain_link.go
@@ -25,13 +25,21 @@ func (k msgServer) LinkChainAccount(goCtx context.Context, msg *types.MsgLinkCha
 		return nil, err
 	}
 
-	ctx.EventManager().EmitEvent(sdk.NewEvent(
-		types.EventTypeLinkChainAccount,
-		sdk.NewAttribute(types.AttributeKeyChainLinkSourceAddress, srcAddrData.GetValue()),
-		sdk.NewAttribute(types.AttributeKeyChainLinkSourceChainName, msg.ChainConfig.Name),
-		sdk.NewAttribute(types.AttributeKeyChainLinkDestinationAddress, msg.Signer),
-		sdk.NewAttribute(types.AttributeKeyChainLinkCreationTime, link.CreationTime.Format(time.RFC3339Nano)),
-	))
+	ctx.EventManager().EmitEvents(sdk.Events{
+		sdk.NewEvent(
+			sdk.EventTypeMessage,
+			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
+			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
+		),
+		sdk.NewEvent(
+			types.EventTypeLinkChainAccount,
+			sdk.NewAttribute(types.AttributeKeyChainLinkSourceAddress, srcAddrData.GetValue()),
+			sdk.NewAttribute(types.AttributeKeyChainLinkSourceChainName, msg.ChainConfig.Name),
+			sdk.NewAttribute(types.AttributeKeyChainLinkDestinationAddress, msg.Signer),
+			sdk.NewAttribute(types.AttributeKeyChainLinkCreationTime, link.CreationTime.Format(time.RFC3339Nano)),
+		),
+	})
 
 	return &types.MsgLinkChainAccountResponse{}, nil
 }
@@ -48,12 +56,20 @@ func (k msgServer) UnlinkChainAccount(goCtx context.Context, msg *types.MsgUnlin
 	// Delete the link
 	k.DeleteChainLink(ctx, link)
 
-	ctx.EventManager().EmitEvent(sdk.NewEvent(
-		types.EventTypeUnlinkChainAccount,
-		sdk.NewAttribute(types.AttributeKeyChainLinkSourceAddress, msg.Target),
-		sdk.NewAttribute(types.AttributeKeyChainLinkSourceChainName, msg.ChainName),
-		sdk.NewAttribute(types.AttributeKeyChainLinkDestinationAddress, msg.Owner),
-	))
+	ctx.EventManager().EmitEvents(sdk.Events{
+		sdk.NewEvent(
+			sdk.EventTypeMessage,
+			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
+			sdk.NewAttribute(sdk.AttributeKeySender, msg.Owner),
+		),
+		sdk.NewEvent(
+			types.EventTypeUnlinkChainAccount,
+			sdk.NewAttribute(types.AttributeKeyChainLinkSourceAddress, msg.Target),
+			sdk.NewAttribute(types.AttributeKeyChainLinkSourceChainName, msg.ChainName),
+			sdk.NewAttribute(types.AttributeKeyChainLinkDestinationAddress, msg.Owner),
+		),
+	})
 
 	return &types.MsgUnlinkChainAccountResponse{}, nil
 }
diff --git a/x/profiles/keeper/msg_server_dtag_transfers.go b/x/profiles/keeper/msg_server_dtag_transfers.go
index 63b5b8f9..f6b9843e 100644
--- a/x/profiles/keeper/msg_server_dtag_transfers.go
+++ b/x/profiles/keeper/msg_server_dtag_transfers.go
@@ -46,6 +46,7 @@ func (k msgServer) RequestDTagTransfer(goCtx context.Context, msg *types.MsgRequ
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
 		),
 		sdk.NewEvent(
@@ -74,6 +75,7 @@ func (k msgServer) CancelDTagTransferRequest(goCtx context.Context, msg *types.M
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Sender),
 		),
 		sdk.NewEvent(
@@ -178,6 +180,7 @@ func (k msgServer) AcceptDTagTransferRequest(goCtx context.Context, msg *types.M
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Receiver),
 		),
 		sdk.NewEvent(
@@ -207,6 +210,7 @@ func (k msgServer) RefuseDTagTransferRequest(goCtx context.Context, msg *types.M
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Receiver),
 		),
 		sdk.NewEvent(
diff --git a/x/profiles/keeper/msgs_server_profile.go b/x/profiles/keeper/msgs_server_profile.go
index cd02d541..5b75dd89 100644
--- a/x/profiles/keeper/msgs_server_profile.go
+++ b/x/profiles/keeper/msgs_server_profile.go
@@ -70,6 +70,7 @@ func (k msgServer) SaveProfile(goCtx context.Context, msg *types.MsgSaveProfile)
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator),
 		),
 		sdk.NewEvent(
@@ -95,6 +96,7 @@ func (k msgServer) DeleteProfile(goCtx context.Context, msg *types.MsgDeleteProf
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator),
 		),
 		sdk.NewEvent(
diff --git a/x/profiles/types/events.go b/x/profiles/types/events.go
index 598bccf8..3c77c25d 100644
--- a/x/profiles/types/events.go
+++ b/x/profiles/types/events.go
@@ -3,20 +3,20 @@ package types
 // DONTCOVER
 
 const (
-	EventTypeProfileSaved            = "profile_saved"
-	EventTypeProfileDeleted          = "profile_deleted"
-	EventTypeDTagTransferRequest     = "dtag_transfer_request"
-	EventTypeDTagTransferAccept      = "dtag_transfer_accept"
-	EventTypeDTagTransferRefuse      = "dtag_transfer_refuse"
-	EventTypeDTagTransferCancel      = "dtag_transfer_cancel"
+	EventTypeProfileSaved            = "save_profile"
+	EventTypeProfileDeleted          = "delete_profile"
+	EventTypeDTagTransferRequest     = "create_dtag_transfer_request"
+	EventTypeDTagTransferAccept      = "accept_dtag_transfer_request"
+	EventTypeDTagTransferRefuse      = "refuse_dtag_transfer_request"
+	EventTypeDTagTransferCancel      = "cancel_dtag_transfer_request"
 	EventTypeLinkChainAccount        = "link_chain_account"
 	EventTypeUnlinkChainAccount      = "unlink_chain_account"
 	EventTypeLinkChainAccountPacket  = "link_chain_account_packet"
-	EventTypePacket                  = "profiles_verification_packet"
+	EventTypePacket                  = "receive_profiles_verification_packet"
 	EventTypeTimeout                 = "timeout"
-	EventTypesApplicationLinkCreated = "application_link_created"
+	EventTypesApplicationLinkCreated = "link_application"
+	EventTypeApplicationLinkDeleted  = "unlink_application"
 	EventTypesApplicationLinkSaved   = "application_link_saved"
-	EventTypeApplicationLinkDeleted  = "application_link_deleted"
 
 	AttributeKeyProfileDTag                 = "profile_dtag"
 	AttributeKeyProfileCreator              = "profile_creator"
diff --git a/x/profiles/types/query.pb.go b/x/profiles/types/query.pb.go
index c5cb0c9c..dbc86efc 100644
--- a/x/profiles/types/query.pb.go
+++ b/x/profiles/types/query.pb.go
@@ -33,46 +33,46 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 func init() { proto.RegisterFile("desmos/profiles/v2/query.proto", fileDescriptor_fba4df0d7bde4d7c) }
 
 var fileDescriptor_fba4df0d7bde4d7c = []byte{
-	// 611 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x4d, 0x6b, 0x13, 0x41,
-	0x18, 0xc7, 0xb3, 0x82, 0x15, 0xe6, 0xa2, 0x0c, 0x7a, 0x48, 0x88, 0x5b, 0xac, 0xe6, 0x85, 0x34,
-	0xdd, 0x31, 0x09, 0x0a, 0x15, 0x3d, 0xd8, 0xf6, 0x52, 0x14, 0xac, 0xd2, 0x93, 0x97, 0x30, 0xbb,
-	0x99, 0x6c, 0x07, 0x37, 0x33, 0xd3, 0x9d, 0x4d, 0x34, 0x94, 0x5c, 0xbc, 0x79, 0x11, 0xc1, 0xbb,
-	0x27, 0x3f, 0x82, 0x1f, 0xc1, 0x83, 0x17, 0xb1, 0xe0, 0xc5, 0xa3, 0x24, 0x7e, 0x10, 0xc9, 0xbc,
-	0x24, 0x34, 0xcd, 0x26, 0x69, 0x6f, 0xbb, 0x3b, 0xbf, 0xff, 0x3c, 0xbf, 0x67, 0xf6, 0x61, 0x80,
-	0xdb, 0x22, 0xb2, 0xc3, 0x25, 0x12, 0x31, 0x6f, 0xd3, 0x88, 0x48, 0xd4, 0xab, 0xa3, 0xe3, 0x2e,
-	0x89, 0xfb, 0x9e, 0x88, 0x79, 0xc2, 0x21, 0xd4, 0xeb, 0x9e, 0x5d, 0xf7, 0x7a, 0xf5, 0xdc, 0xcd,
-	0x90, 0x87, 0x5c, 0x2d, 0xa3, 0xf1, 0x93, 0x26, 0x73, 0xf9, 0x90, 0xf3, 0x30, 0x22, 0x08, 0x0b,
-	0x8a, 0x30, 0x63, 0x3c, 0xc1, 0x09, 0xe5, 0x4c, 0x9a, 0xd5, 0xac, 0x59, 0x55, 0x6f, 0x7e, 0xb7,
-	0x8d, 0x30, 0x33, 0x25, 0x72, 0xc5, 0x34, 0x85, 0xa6, 0xf9, 0x62, 0xb8, 0x6a, 0x2a, 0xd7, 0x4a,
-	0x70, 0xd8, 0x8c, 0xc9, 0x71, 0x97, 0xc8, 0xc4, 0x16, 0x2c, 0xa4, 0xef, 0x8a, 0x63, 0xdc, 0xb1,
-	0x58, 0x25, 0x15, 0x0b, 0x8e, 0x30, 0x65, 0xcd, 0x88, 0xb2, 0x37, 0x96, 0x2d, 0xa7, 0xb2, 0x58,
-	0x88, 0x33, 0x64, 0x36, 0xe0, 0x63, 0xb2, 0xa9, 0x0f, 0x49, 0xbf, 0xd8, 0x82, 0xfa, 0x0d, 0xf9,
-	0x58, 0x12, 0x9d, 0x46, 0xbd, 0x9a, 0x4f, 0x12, 0x5c, 0x43, 0x02, 0x87, 0x94, 0xa9, 0x53, 0xd3,
-	0x6c, 0xfd, 0x3b, 0x00, 0x57, 0x5f, 0x8e, 0x11, 0xf8, 0xc1, 0x01, 0xd7, 0x0e, 0x74, 0x59, 0x58,
-	0xf2, 0xce, 0xff, 0x13, 0x4f, 0x61, 0x86, 0x78, 0xa5, 0x4f, 0x22, 0x57, 0x5e, 0x0e, 0x4a, 0xc1,
-	0x99, 0x24, 0x1b, 0x9b, 0xef, 0x7f, 0xff, 0xfb, 0x7c, 0xa5, 0x00, 0xef, 0xa2, 0x39, 0x2d, 0x4e,
-	0x9e, 0x4f, 0xba, 0x92, 0xc4, 0x03, 0xf8, 0xcb, 0x01, 0xf9, 0x7d, 0x16, 0xf0, 0x0e, 0x65, 0xe1,
-	0xde, 0x21, 0x0e, 0x0f, 0x63, 0xcc, 0x64, 0x9b, 0xc4, 0xa6, 0xac, 0x84, 0x8f, 0x53, 0xeb, 0x2e,
-	0x8a, 0x59, 0xeb, 0x27, 0x97, 0x4c, 0x9b, 0x56, 0xea, 0xaa, 0x95, 0x2a, 0xac, 0xcc, 0x6b, 0x45,
-	0x0d, 0x4a, 0x62, 0xa2, 0x93, 0x89, 0x81, 0x1f, 0x1d, 0x00, 0x76, 0xc7, 0xbf, 0xfb, 0xf9, 0xf8,
-	0x1f, 0xc2, 0x4a, 0xaa, 0xc1, 0x14, 0xb2, 0xb6, 0x9b, 0x2b, 0xb1, 0xc6, 0xad, 0xa4, 0xdc, 0xee,
-	0xc0, 0xf5, 0x79, 0x6e, 0x6a, 0xde, 0xb6, 0xd4, 0x14, 0xc1, 0xaf, 0x0e, 0xb8, 0x3e, 0xc9, 0xbf,
-	0x78, 0xcb, 0x48, 0x2c, 0x21, 0x5a, 0x5e, 0x49, 0x93, 0x56, 0xed, 0xfe, 0xea, 0x01, 0xe3, 0xe7,
-	0x29, 0xbf, 0x32, 0x2c, 0x2e, 0xf1, 0x43, 0x5c, 0x2b, 0x7d, 0x71, 0xc0, 0x8d, 0xa7, 0x42, 0x44,
-	0x34, 0x50, 0x53, 0xab, 0x4f, 0x2f, 0xbd, 0xec, 0x2c, 0x6a, 0x45, 0x6b, 0x17, 0x48, 0x18, 0xd3,
-	0x82, 0x32, 0x5d, 0x87, 0xb7, 0xe7, 0x99, 0x62, 0x21, 0xcc, 0x39, 0xfe, 0x74, 0x40, 0x76, 0x66,
-	0x8f, 0x9d, 0xfe, 0x6e, 0x44, 0x09, 0x4b, 0xf6, 0xf7, 0xe0, 0xf6, 0xaa, 0x75, 0xa7, 0x19, 0xab,
-	0xfc, 0xe8, 0x32, 0x51, 0xe3, 0xbe, 0xad, 0xdc, 0x1b, 0xb0, 0xb6, 0xd0, 0x1d, 0x05, 0x2a, 0x27,
-	0xd1, 0x89, 0x7e, 0x68, 0xd2, 0xd6, 0x00, 0x7e, 0x73, 0xc0, 0xad, 0x99, 0x02, 0x66, 0x3a, 0x1e,
-	0xac, 0x2a, 0x74, 0x76, 0x46, 0x1e, 0x5e, 0x34, 0x66, 0x7a, 0xa8, 0xaa, 0x1e, 0x8a, 0xf0, 0xde,
-	0xe2, 0x1e, 0xcc, 0x9c, 0x0c, 0xc0, 0xda, 0x81, 0xba, 0x74, 0x61, 0x31, 0xfd, 0x4a, 0x52, 0x80,
-	0xf5, 0x2a, 0x2d, 0xe5, 0x8c, 0xc8, 0x86, 0x12, 0xc9, 0xc3, 0xdc, 0xdc, 0x9b, 0x4b, 0xb1, 0x3b,
-	0xcf, 0x7e, 0x0c, 0x5d, 0xe7, 0x74, 0xe8, 0x3a, 0x7f, 0x87, 0xae, 0xf3, 0x69, 0xe4, 0x66, 0x4e,
-	0x47, 0x6e, 0xe6, 0xcf, 0xc8, 0xcd, 0xbc, 0xae, 0x85, 0x34, 0x39, 0xea, 0xfa, 0x5e, 0xc0, 0x3b,
-	0x26, 0xbf, 0x15, 0x61, 0x5f, 0xda, 0xbd, 0x7a, 0x0d, 0xf4, 0x6e, 0xba, 0x61, 0xd2, 0x17, 0x44,
-	0xfa, 0x6b, 0xea, 0x6a, 0x6e, 0xfc, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x2e, 0xcf, 0xbd, 0x67, 0x39,
-	0x07, 0x00, 0x00,
+	// 614 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x4f, 0x6b, 0x13, 0x4f,
+	0x18, 0xc7, 0xbb, 0x3f, 0xf8, 0x55, 0x98, 0x8b, 0x32, 0xe8, 0x21, 0x21, 0x6e, 0xb1, 0x9a, 0x3f,
+	0xa4, 0xc9, 0x8e, 0x49, 0x50, 0xa8, 0xe8, 0xc1, 0xb6, 0x97, 0xa2, 0x60, 0x95, 0x9e, 0xbc, 0x84,
+	0xd9, 0xcd, 0x64, 0x3b, 0xb8, 0x99, 0x99, 0xee, 0x6c, 0xa2, 0xa1, 0xe4, 0xe2, 0xcd, 0x8b, 0x08,
+	0xde, 0x3d, 0xf9, 0x12, 0x7c, 0x09, 0x1e, 0xbc, 0x88, 0x05, 0x2f, 0x1e, 0x25, 0xf1, 0x85, 0xc8,
+	0xce, 0x9f, 0x86, 0xc6, 0x6c, 0x92, 0xf6, 0xb6, 0xbb, 0xf3, 0xf9, 0xce, 0xf3, 0x79, 0x66, 0x1f,
+	0x06, 0xb8, 0x1d, 0x22, 0x7b, 0x5c, 0x22, 0x11, 0xf3, 0x2e, 0x8d, 0x88, 0x44, 0x83, 0x26, 0x3a,
+	0xee, 0x93, 0x78, 0xe8, 0x89, 0x98, 0x27, 0x1c, 0x42, 0xbd, 0xee, 0xd9, 0x75, 0x6f, 0xd0, 0xcc,
+	0x5f, 0x0f, 0x79, 0xc8, 0xd5, 0x32, 0x4a, 0x9f, 0x34, 0x99, 0x2f, 0x84, 0x9c, 0x87, 0x11, 0x41,
+	0x58, 0x50, 0x84, 0x19, 0xe3, 0x09, 0x4e, 0x28, 0x67, 0xd2, 0xac, 0xe6, 0xcc, 0xaa, 0x7a, 0xf3,
+	0xfb, 0x5d, 0x84, 0x99, 0x29, 0x91, 0x2f, 0x65, 0x29, 0xb4, 0xcd, 0x17, 0xc3, 0xd5, 0x32, 0xb9,
+	0x4e, 0x82, 0xc3, 0x76, 0x4c, 0x8e, 0xfb, 0x44, 0x26, 0xb6, 0x60, 0x31, 0x7b, 0x57, 0x1c, 0xe3,
+	0x9e, 0xc5, 0xaa, 0x99, 0x58, 0x70, 0x84, 0x29, 0x6b, 0x47, 0x94, 0xbd, 0xb2, 0x6c, 0x25, 0x93,
+	0xc5, 0x42, 0x9c, 0x23, 0x73, 0x01, 0x4f, 0xc9, 0xb6, 0x3e, 0x24, 0xfd, 0x62, 0x0b, 0xea, 0x37,
+	0xe4, 0x63, 0x49, 0x74, 0x1a, 0x0d, 0x1a, 0x3e, 0x49, 0x70, 0x03, 0x09, 0x1c, 0x52, 0xa6, 0x4e,
+	0x4d, 0xb3, 0xcd, 0xaf, 0x00, 0xfc, 0xff, 0x3c, 0x45, 0xe0, 0x3b, 0x07, 0x5c, 0x39, 0xd0, 0x65,
+	0x61, 0xd9, 0xfb, 0xf7, 0x9f, 0x78, 0x0a, 0x33, 0xc4, 0x0b, 0x7d, 0x12, 0xf9, 0xca, 0x72, 0x50,
+	0x0a, 0xce, 0x24, 0xd9, 0xdc, 0x7a, 0xfb, 0xf3, 0xcf, 0xc7, 0xff, 0x8a, 0xf0, 0x36, 0x9a, 0xd3,
+	0xe2, 0xd9, 0xf3, 0x49, 0x5f, 0x92, 0x78, 0x04, 0x7f, 0x38, 0xa0, 0xb0, 0xcf, 0x02, 0xde, 0xa3,
+	0x2c, 0xdc, 0x3b, 0xc4, 0xe1, 0x61, 0x8c, 0x99, 0xec, 0x92, 0xd8, 0x94, 0x95, 0xf0, 0x61, 0x66,
+	0xdd, 0x45, 0x31, 0x6b, 0xfd, 0xe8, 0x92, 0x69, 0xd3, 0x4a, 0x53, 0xb5, 0x52, 0x83, 0xd5, 0x79,
+	0xad, 0xa4, 0x83, 0x52, 0x4f, 0x4c, 0xb4, 0x6e, 0x27, 0x06, 0xbe, 0x77, 0x00, 0xd8, 0x4d, 0x7f,
+	0xf7, 0xd3, 0xf4, 0x1f, 0xc2, 0x6a, 0xa6, 0xc1, 0x14, 0xb2, 0xb6, 0x5b, 0x2b, 0xb1, 0xc6, 0xad,
+	0xac, 0xdc, 0x6e, 0xc1, 0x8d, 0x79, 0x6e, 0x6a, 0xde, 0xea, 0x6a, 0x8a, 0xe0, 0x67, 0x07, 0x5c,
+	0x3d, 0xcb, 0x3f, 0x7b, 0xcd, 0x48, 0x2c, 0x21, 0x5a, 0x5e, 0x49, 0x93, 0x56, 0xed, 0xee, 0xea,
+	0x01, 0xe3, 0xe7, 0x29, 0xbf, 0x0a, 0x2c, 0x2d, 0xf1, 0x43, 0x5c, 0x2b, 0x7d, 0x72, 0xc0, 0xb5,
+	0xc7, 0x42, 0x44, 0x34, 0x50, 0x53, 0xab, 0x4f, 0x2f, 0xbb, 0xec, 0x2c, 0x6a, 0x45, 0x1b, 0x17,
+	0x48, 0x18, 0xd3, 0xa2, 0x32, 0xdd, 0x80, 0x37, 0xe7, 0x99, 0x62, 0x21, 0xcc, 0x39, 0x7e, 0x77,
+	0x40, 0x6e, 0x66, 0x8f, 0x9d, 0xe1, 0x6e, 0x44, 0x09, 0x4b, 0xf6, 0xf7, 0xe0, 0xf6, 0xaa, 0x75,
+	0xa7, 0x19, 0xab, 0xfc, 0xe0, 0x32, 0x51, 0xe3, 0xbe, 0xad, 0xdc, 0x5b, 0xb0, 0xb1, 0xd0, 0x1d,
+	0x05, 0x2a, 0x27, 0xd1, 0x89, 0x7e, 0x68, 0xd3, 0xce, 0x08, 0x7e, 0x71, 0xc0, 0x8d, 0x99, 0x02,
+	0x66, 0x3a, 0xee, 0xad, 0x2a, 0x74, 0x7e, 0x46, 0xee, 0x5f, 0x34, 0x66, 0x7a, 0xa8, 0xa9, 0x1e,
+	0x4a, 0xf0, 0xce, 0xe2, 0x1e, 0xcc, 0x9c, 0x8c, 0xc0, 0xfa, 0x81, 0xba, 0x74, 0x61, 0x29, 0xfb,
+	0x4a, 0x52, 0x80, 0xf5, 0x2a, 0x2f, 0xe5, 0x8c, 0xc8, 0xa6, 0x12, 0x29, 0xc0, 0xfc, 0xdc, 0x9b,
+	0x4b, 0xb1, 0x3b, 0x4f, 0xbe, 0x8d, 0x5d, 0xe7, 0x74, 0xec, 0x3a, 0xbf, 0xc7, 0xae, 0xf3, 0x61,
+	0xe2, 0xae, 0x9d, 0x4e, 0xdc, 0xb5, 0x5f, 0x13, 0x77, 0xed, 0x65, 0x23, 0xa4, 0xc9, 0x51, 0xdf,
+	0xf7, 0x02, 0xde, 0x33, 0xf9, 0x7a, 0x84, 0x7d, 0x69, 0xf7, 0x1a, 0xb4, 0xd0, 0x9b, 0xe9, 0x86,
+	0xc9, 0x50, 0x10, 0xe9, 0xaf, 0xab, 0xab, 0xb9, 0xf5, 0x37, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x22,
+	0xf5, 0xbf, 0x39, 0x07, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
diff --git a/x/profiles/types/query.pb.gw.go b/x/profiles/types/query.pb.gw.go
index 6acc9045..5ec0613d 100644
--- a/x/profiles/types/query.pb.gw.go
+++ b/x/profiles/types/query.pb.gw.go
@@ -710,7 +710,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
 var (
 	pattern_Query_Profile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3}, []string{"desmos", "profiles", "v2", "user"}, "", runtime.AssumeColonVerbOpt(true)))
 
-	pattern_Query_IncomingDTagTransferRequests_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"desmos", "profiles", "v2", "dtag_transfer_requests"}, "", runtime.AssumeColonVerbOpt(true)))
+	pattern_Query_IncomingDTagTransferRequests_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"desmos", "profiles", "v2", "dtag-transfer-requests"}, "", runtime.AssumeColonVerbOpt(true)))
 
 	pattern_Query_ChainLinks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"desmos", "profiles", "v2", "chain-links"}, "", runtime.AssumeColonVerbOpt(true)))
 
diff --git a/x/relationships/keeper/migrations.go b/x/relationships/keeper/migrations.go
index 1b406fd3..642422cd 100644
--- a/x/relationships/keeper/migrations.go
+++ b/x/relationships/keeper/migrations.go
@@ -3,6 +3,8 @@ package keeper
 import (
 	sdk "github.com/cosmos/cosmos-sdk/types"
 
+	v2 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v2"
+
 	profilesv4 "github.com/desmos-labs/desmos/v3/x/profiles/legacy/v4"
 
 	v1 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v1"
@@ -28,3 +30,8 @@ func NewMigrator(keeper Keeper, pk profilesv4.Keeper) Migrator {
 func (m Migrator) Migrate1To2(ctx sdk.Context) error {
 	return v1.MigrateStore(ctx, m.pk, m.keeper.storeKey, m.keeper.cdc)
 }
+
+// Migrate1To2 migrates from version 2 to 3.
+func (m Migrator) Migrate2To3(ctx sdk.Context) error {
+	return v2.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc)
+}
diff --git a/x/relationships/keeper/msg_server.go b/x/relationships/keeper/msg_server.go
index 3be3921c..faa4c055 100644
--- a/x/relationships/keeper/msg_server.go
+++ b/x/relationships/keeper/msg_server.go
@@ -49,6 +49,7 @@ func (k msgServer) CreateRelationship(goCtx context.Context, msg *types.MsgCreat
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -83,10 +84,11 @@ func (k msgServer) DeleteRelationship(goCtx context.Context, msg *types.MsgDelet
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
-			types.EventTypeRelationshipsDeleted,
+			types.EventTypeRelationshipDeleted,
 			sdk.NewAttribute(types.AttributeRelationshipCreator, msg.Signer),
 			sdk.NewAttribute(types.AttributeRelationshipCounterparty, msg.Counterparty),
 			sdk.NewAttribute(types.AttributeKeySubspace, fmt.Sprintf("%d", msg.SubspaceID)),
@@ -117,6 +119,7 @@ func (k msgServer) BlockUser(goCtx context.Context, msg *types.MsgBlockUser) (*t
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Blocker),
 		),
 		sdk.NewEvent(
@@ -151,6 +154,7 @@ func (k msgServer) UnblockUser(goCtx context.Context, msg *types.MsgUnblockUser)
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Blocker),
 		),
 		sdk.NewEvent(
diff --git a/x/relationships/legacy/v1/keys.go b/x/relationships/legacy/v1/keys.go
new file mode 100644
index 00000000..7c3f2e17
--- /dev/null
+++ b/x/relationships/legacy/v1/keys.go
@@ -0,0 +1,45 @@
+package v1
+
+// DONTCOVER
+
+import (
+	subspacestypes "github.com/desmos-labs/desmos/v3/x/subspaces/types"
+)
+
+var (
+	RelationshipsStorePrefix = []byte("relationships")
+	UsersBlocksStorePrefix   = []byte("users_blocks")
+)
+
+// SubspaceRelationshipsPrefix returns the prefix used to store all relationships for the given subspace
+func SubspaceRelationshipsPrefix(subspaceID uint64) []byte {
+	return append(RelationshipsStorePrefix, subspacestypes.GetSubspaceIDBytes(subspaceID)...)
+}
+
+// UserRelationshipsSubspacePrefix returns the prefix used to store all the relationships created by the user
+// with the given address for the subspace having the given id
+func UserRelationshipsSubspacePrefix(subspace uint64, user string) []byte {
+	return append(SubspaceRelationshipsPrefix(subspace), []byte(user)...)
+}
+
+// RelationshipsStoreKey returns the store key used to store the relationships containing the given data
+func RelationshipsStoreKey(user, counterparty string, subspace uint64) []byte {
+	return append(UserRelationshipsSubspacePrefix(subspace, user), []byte(counterparty)...)
+}
+
+// SubspaceBlocksPrefix returns the store prefix used to store the blocks for the given subspace
+func SubspaceBlocksPrefix(subspaceID uint64) []byte {
+	return append(UsersBlocksStorePrefix, subspacestypes.GetSubspaceIDBytes(subspaceID)...)
+}
+
+// BlockerSubspacePrefix returns the store prefix used to store the blocks that the given blocker
+// has created inside the specified subspace
+func BlockerSubspacePrefix(subspaceID uint64, blocker string) []byte {
+	return append(SubspaceBlocksPrefix(subspaceID), []byte(blocker)...)
+}
+
+// UserBlockStoreKey returns the store key used to save the block made by the given blocker,
+// inside the specified subspace and towards the given blocked user
+func UserBlockStoreKey(blocker, blockedUser string, subspace uint64) []byte {
+	return append(BlockerSubspacePrefix(subspace, blocker), []byte(blockedUser)...)
+}
diff --git a/x/relationships/legacy/v2/store.go b/x/relationships/legacy/v2/store.go
new file mode 100644
index 00000000..16117ea2
--- /dev/null
+++ b/x/relationships/legacy/v2/store.go
@@ -0,0 +1,103 @@
+package v2
+
+import (
+	"github.com/cosmos/cosmos-sdk/codec"
+	"github.com/cosmos/cosmos-sdk/store/prefix"
+	sdk "github.com/cosmos/cosmos-sdk/types"
+
+	v1 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v1"
+	"github.com/desmos-labs/desmos/v3/x/relationships/types"
+)
+
+// MigrateStore performs in-place store migrations from v1 to v2.
+// The migration includes:
+//
+// - migrate all relationships keys to the new ones
+// - migrate all user blocks keys to the new ones
+func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error {
+	store := ctx.KVStore(storeKey)
+
+	err := migrateRelationships(store, cdc)
+	if err != nil {
+		return err
+	}
+
+	err = migrateUserBlocks(store, cdc)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// migrateRelationships migrates all the relationships from using the old key to using the new key
+func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error {
+	prefixStore := prefix.NewStore(store, v1.RelationshipsStorePrefix)
+	iterator := prefixStore.Iterator(nil, nil)
+
+	// Read all the existing relationships and the associated keys
+	var keys [][]byte
+	var relationships []types.Relationship
+	for ; iterator.Valid(); iterator.Next() {
+		keys = append(keys, append(v1.RelationshipsStorePrefix, iterator.Key()...))
+
+		var relationship types.Relationship
+		err := cdc.Unmarshal(iterator.Value(), &relationship)
+		if err != nil {
+			return err
+		}
+		relationships = append(relationships, relationship)
+	}
+	iterator.Close()
+
+	for i, relationship := range relationships {
+		// Delete the old key
+		store.Delete(keys[i])
+
+		bz, err := cdc.Marshal(&relationships[i])
+		if err != nil {
+			return err
+		}
+
+		// Store the relationship with the new key
+		store.Set(types.RelationshipsStoreKey(relationship.Creator, relationship.Counterparty, relationship.SubspaceID), bz)
+	}
+
+	return nil
+}
+
+// migrateUserBlocks migrates all the user blocks from using the old key to using the new key
+func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error {
+	prefixStore := prefix.NewStore(store, v1.UsersBlocksStorePrefix)
+	iterator := prefixStore.Iterator(nil, nil)
+
+	// Read all the existing blocks and the associated keys
+	var keys [][]byte
+	var blocks []types.UserBlock
+	for ; iterator.Valid(); iterator.Next() {
+		keys = append(keys, append(v1.UsersBlocksStorePrefix, iterator.Key()...))
+
+		var block types.UserBlock
+		err := cdc.Unmarshal(iterator.Value(), &block)
+		if err != nil {
+			return err
+		}
+		blocks = append(blocks, block)
+	}
+	iterator.Close()
+
+	for i, block := range blocks {
+		// Delete the old key
+		store.Delete(keys[i])
+
+		bz, err := cdc.Marshal(&blocks[i])
+		if err != nil {
+			return err
+		}
+
+		// Store the block with the new key
+		store.Set(types.UserBlockStoreKey(block.Blocker, block.Blocked, block.SubspaceID), bz)
+	}
+
+	return nil
+}
diff --git a/x/relationships/module.go b/x/relationships/module.go
index 7641ca8a..37db0891 100644
--- a/x/relationships/module.go
+++ b/x/relationships/module.go
@@ -33,7 +33,7 @@ import (
 )
 
 const (
-	consensusVersion = 2
+	consensusVersion = 3
 )
 
 // type check to ensure the interface is properly implemented
@@ -118,6 +118,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
 	if err != nil {
 		panic(err)
 	}
+	err = cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2To3)
+	if err != nil {
+		panic(err)
+	}
 }
 
 // NewAppModule creates a new AppModule Object
diff --git a/x/relationships/types/events.go b/x/relationships/types/events.go
index d697196e..96dc0889 100644
--- a/x/relationships/types/events.go
+++ b/x/relationships/types/events.go
@@ -3,10 +3,10 @@ package types
 // DONTCOVER
 
 const (
-	EventTypeRelationshipCreated  = "relationship_created"
-	EventTypeRelationshipsDeleted = "relationships_deleted"
-	EventTypeBlockUser            = "block_user"
-	EventTypeUnblockUser          = "unblock_user"
+	EventTypeRelationshipCreated = "create_relationship"
+	EventTypeRelationshipDeleted = "delete_relationship"
+	EventTypeBlockUser           = "block_user"
+	EventTypeUnblockUser         = "unblock_user"
 
 	AttributeValueCategory            = ModuleName
 	AttributeRelationshipCreator      = "creator"
diff --git a/x/relationships/types/keys.go b/x/relationships/types/keys.go
index 61db1bc0..b7ce62c9 100644
--- a/x/relationships/types/keys.go
+++ b/x/relationships/types/keys.go
@@ -18,8 +18,8 @@ const (
 )
 
 var (
-	RelationshipsStorePrefix = []byte("relationships")
-	UsersBlocksStorePrefix   = []byte("users_blocks")
+	RelationshipsStorePrefix = []byte{0x01}
+	UsersBlocksStorePrefix   = []byte{0x02}
 )
 
 // SubspaceRelationshipsPrefix returns the prefix used to store all relationships for the given subspace
diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go
index f22224dc..6b88584a 100644
--- a/x/subspaces/keeper/msg_server.go
+++ b/x/subspaces/keeper/msg_server.go
@@ -49,6 +49,7 @@ func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSub
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, subspace.Creator),
 		),
 		sdk.NewEvent(
@@ -99,6 +100,7 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -136,6 +138,7 @@ func (k msgServer) DeleteSubspace(goCtx context.Context, msg *types.MsgDeleteSub
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -196,6 +199,7 @@ func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUs
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator),
 		),
 		sdk.NewEvent(
@@ -247,6 +251,7 @@ func (k msgServer) EditUserGroup(goCtx context.Context, msg *types.MsgEditUserGr
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -303,6 +308,7 @@ func (k msgServer) SetUserGroupPermissions(goCtx context.Context, msg *types.Msg
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, signer.String()),
 		),
 		sdk.NewEvent(
@@ -346,6 +352,7 @@ func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUs
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -402,6 +409,7 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -456,6 +464,7 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer),
 		),
 		sdk.NewEvent(
@@ -510,6 +519,7 @@ func (k msgServer) SetUserPermissions(goCtx context.Context, msg *types.MsgSetUs
 		sdk.NewEvent(
 			sdk.EventTypeMessage,
 			sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+			sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(msg)),
 			sdk.NewAttribute(sdk.AttributeKeySender, signer.String()),
 		),
 		sdk.NewEvent(
diff --git a/x/supply/types/query.pb.go b/x/supply/types/query.pb.go
index 179d7cd5..533ec8f7 100644
--- a/x/supply/types/query.pb.go
+++ b/x/supply/types/query.pb.go
@@ -38,7 +38,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 type QueryTotalSupplyRequest struct {
 	// coin denom to query the circulating supply for
 	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
-	// divider_exponent is a factor used to power the divider used to convert the supply to the desired representation
+	// divider_exponent is a factor used to power the divider used to convert the
+	// supply to the desired representation
 	DividerExponent uint64 `protobuf:"varint,2,opt,name=divider_exponent,json=dividerExponent,proto3" json:"divider_exponent,omitempty"`
 }
 
@@ -75,7 +76,8 @@ func (m *QueryTotalSupplyRequest) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryTotalSupplyRequest proto.InternalMessageInfo
 
-// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC method
+// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC
+// method
 type QueryTotalSupplyResponse struct {
 	TotalSupply github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=total_supply,json=totalSupply,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"total_supply"`
 }
@@ -113,11 +115,13 @@ func (m *QueryTotalSupplyResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryTotalSupplyResponse proto.InternalMessageInfo
 
-// QueryCirculatingSupplyRequest is the request type for the Query/CirculatingSupply RPC method
+// QueryCirculatingSupplyRequest is the request type for the
+// Query/CirculatingSupply RPC method
 type QueryCirculatingSupplyRequest struct {
 	// coin denom to query the circulating supply for
 	Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"`
-	// divider_exponent is a factor used to power the divider used to convert the supply to the desired representation
+	// divider_exponent is a factor used to power the divider used to convert the
+	// supply to the desired representation
 	DividerExponent uint64 `protobuf:"varint,2,opt,name=divider_exponent,json=dividerExponent,proto3" json:"divider_exponent,omitempty"`
 }
 
@@ -154,7 +158,8 @@ func (m *QueryCirculatingSupplyRequest) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_QueryCirculatingSupplyRequest proto.InternalMessageInfo
 
-// QueryCirculatingSupplyRequest is the response type for the Query/CirculatingSupply RPC method
+// QueryCirculatingSupplyRequest is the response type for the
+// Query/CirculatingSupply RPC method
 type QueryCirculatingSupplyResponse struct {
 	CirculatingSupply github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,1,opt,name=circulating_supply,json=circulatingSupply,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"circulating_supply"`
 }
@@ -250,7 +255,8 @@ const _ = grpc.SupportPackageIsVersion4
 type QueryClient interface {
 	// TotalSupply queries the total supply of the given denom
 	TotalSupply(ctx context.Context, in *QueryTotalSupplyRequest, opts ...grpc.CallOption) (*QueryTotalSupplyResponse, error)
-	// CirculatingSupply queries the amount of tokens circulating in the market of the given denom
+	// CirculatingSupply queries the amount of tokens circulating in the market of
+	// the given denom
 	CirculatingSupply(ctx context.Context, in *QueryCirculatingSupplyRequest, opts ...grpc.CallOption) (*QueryCirculatingSupplyResponse, error)
 }
 
@@ -284,7 +290,8 @@ func (c *queryClient) CirculatingSupply(ctx context.Context, in *QueryCirculatin
 type QueryServer interface {
 	// TotalSupply queries the total supply of the given denom
 	TotalSupply(context.Context, *QueryTotalSupplyRequest) (*QueryTotalSupplyResponse, error)
-	// CirculatingSupply queries the amount of tokens circulating in the market of the given denom
+	// CirculatingSupply queries the amount of tokens circulating in the market of
+	// the given denom
 	CirculatingSupply(context.Context, *QueryCirculatingSupplyRequest) (*QueryCirculatingSupplyResponse, error)
 }
 


Test patch:
diff --git a/x/fees/types/params_test.go b/x/fees/types/params_test.go
index d0d7e63a..ed7be503 100644
--- a/x/fees/types/params_test.go
+++ b/x/fees/types/params_test.go
@@ -18,17 +18,40 @@ func TestValidateParams(t *testing.T) {
 		shouldErr bool
 	}{
 		{
-			name: "invalid params returns error",
+			name: "invalid type returns error",
 			params: types.NewParams([]types.MinFee{
 				types.NewMinFee("", sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1)))),
 			}),
 			shouldErr: true,
 		},
+		{
+			name: "invalid amount returns error",
+			params: types.NewParams([]types.MinFee{
+				types.NewMinFee("/desmos.profiles.v2.SaveProfile", sdk.Coins{sdk.Coin{Denom: "", Amount: sdk.NewInt(1)}}),
+			}),
+			shouldErr: true,
+		},
+		{
+			name: "duplicated min fee returns error",
+			params: types.NewParams([]types.MinFee{
+				types.NewMinFee("/desmos.profiles.v2.SaveProfile", sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1)))),
+				types.NewMinFee("/desmos.profiles.v2.SaveProfile", sdk.NewCoins(sdk.NewCoin("photino", sdk.NewInt(1)))),
+			}),
+			shouldErr: true,
+		},
 		{
 			name:      "default params returns no error",
 			params:    types.DefaultParams(),
 			shouldErr: false,
 		},
+		{
+			name: "custom params returns no error",
+			params: types.NewParams([]types.MinFee{
+				types.NewMinFee("/desmos.profiles.v2.SaveProfile", sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1)))),
+				types.NewMinFee("/desmos.profiles.v2.CreateChainLink", sdk.NewCoins(sdk.NewCoin("photino", sdk.NewInt(1)))),
+			}),
+			shouldErr: false,
+		},
 	}
 
 	for _, tc := range testCases {
diff --git a/x/profiles/keeper/msg_server_chain_link_test.go b/x/profiles/keeper/msg_server_chain_link_test.go
index 5b8205a4..833a1f34 100644
--- a/x/profiles/keeper/msg_server_chain_link_test.go
+++ b/x/profiles/keeper/msg_server_chain_link_test.go
@@ -107,6 +107,12 @@ func (suite *KeeperTestSuite) TestMsgServer_LinkChainAccount() {
 			),
 			shouldErr: false,
 			expEvents: sdk.Events{
+				sdk.NewEvent(
+					sdk.EventTypeMessage,
+					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgLinkChainAccount{})),
+					sdk.NewAttribute(sdk.AttributeKeySender, destAddr),
+				),
 				sdk.NewEvent(
 					types.EventTypeLinkChainAccount,
 					sdk.NewAttribute(types.AttributeKeyChainLinkSourceAddress, srcAddr),
@@ -198,6 +204,12 @@ func (suite *KeeperTestSuite) TestMsgServer_UnlinkChainAccount() {
 			),
 			shouldErr: false,
 			expEvents: sdk.Events{
+				sdk.NewEvent(
+					sdk.EventTypeMessage,
+					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgUnlinkChainAccount{})),
+					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
+				),
 				sdk.NewEvent(
 					types.EventTypeUnlinkChainAccount,
 					sdk.NewAttribute(types.AttributeKeyChainLinkSourceAddress, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
diff --git a/x/profiles/keeper/msg_server_dtag_transfers_test.go b/x/profiles/keeper/msg_server_dtag_transfers_test.go
index cde8890d..3c7d3e40 100644
--- a/x/profiles/keeper/msg_server_dtag_transfers_test.go
+++ b/x/profiles/keeper/msg_server_dtag_transfers_test.go
@@ -80,6 +80,7 @@ func (suite *KeeperTestSuite) TestMsgServer_RequestDTagTransfer() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgRequestDTagTransfer{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 				),
 				sdk.NewEvent(
@@ -148,6 +149,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CancelDTagTransfer() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgCancelDTagTransferRequest{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 				),
 				sdk.NewEvent(
@@ -290,6 +292,7 @@ func (suite *KeeperTestSuite) TestMsgServer_AcceptDTagTransfer() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgAcceptDTagTransferRequest{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
 				),
 				sdk.NewEvent(
@@ -324,6 +327,7 @@ func (suite *KeeperTestSuite) TestMsgServer_AcceptDTagTransfer() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgAcceptDTagTransferRequest{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
 				),
 				sdk.NewEvent(
@@ -360,6 +364,7 @@ func (suite *KeeperTestSuite) TestMsgServer_AcceptDTagTransfer() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgAcceptDTagTransferRequest{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
 				),
 				sdk.NewEvent(
@@ -441,6 +446,7 @@ func (suite *KeeperTestSuite) TestMsgServer_RefuseDTagTransfer() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgRefuseDTagTransferRequest{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
 				),
 				sdk.NewEvent(
diff --git a/x/profiles/keeper/msgs_server_profile_test.go b/x/profiles/keeper/msgs_server_profile_test.go
index 6fbdfc89..812ccc65 100644
--- a/x/profiles/keeper/msgs_server_profile_test.go
+++ b/x/profiles/keeper/msgs_server_profile_test.go
@@ -44,6 +44,7 @@ func (suite *KeeperTestSuite) TestMsgServer_SaveProfile() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSaveProfile{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"),
 				),
 				sdk.NewEvent(
@@ -83,6 +84,7 @@ func (suite *KeeperTestSuite) TestMsgServer_SaveProfile() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSaveProfile{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"),
 				),
 				sdk.NewEvent(
@@ -128,6 +130,7 @@ func (suite *KeeperTestSuite) TestMsgServer_SaveProfile() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSaveProfile{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"),
 				),
 				sdk.NewEvent(
@@ -211,6 +214,7 @@ func (suite *KeeperTestSuite) TestMsgServer_SaveProfile() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSaveProfile{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
 				),
 				sdk.NewEvent(
@@ -307,6 +311,7 @@ func (suite *KeeperTestSuite) TestMsgServer_DeleteProfile() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgDeleteProfile{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773"),
 				),
 				sdk.NewEvent(
diff --git a/x/relationships/keeper/msg_server_test.go b/x/relationships/keeper/msg_server_test.go
index 66aa88d2..300b969d 100644
--- a/x/relationships/keeper/msg_server_test.go
+++ b/x/relationships/keeper/msg_server_test.go
@@ -94,6 +94,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgCreateRelationship{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 				),
 				sdk.NewEvent(
@@ -205,10 +206,11 @@ func (suite *KeeperTestSuite) TestMsgServer_DeleteRelationship() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgDeleteRelationship{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 				),
 				sdk.NewEvent(
-					types.EventTypeRelationshipsDeleted,
+					types.EventTypeRelationshipDeleted,
 					sdk.NewAttribute(types.AttributeRelationshipCreator, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 					sdk.NewAttribute(types.AttributeRelationshipCounterparty, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"),
 					sdk.NewAttribute(types.AttributeKeySubspace, "1"),
@@ -319,6 +321,7 @@ func (suite *KeeperTestSuite) TestMsgServer_BlockUser() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgBlockUser{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 				),
 				sdk.NewEvent(
@@ -431,6 +434,7 @@ func (suite *KeeperTestSuite) TestMsgServer_UnblockUser() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgUnblockUser{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"),
 				),
 				sdk.NewEvent(
diff --git a/x/relationships/legacy/v2/store_test.go b/x/relationships/legacy/v2/store_test.go
new file mode 100644
index 00000000..1f620e97
--- /dev/null
+++ b/x/relationships/legacy/v2/store_test.go
@@ -0,0 +1,115 @@
+package v2_test
+
+import (
+	"testing"
+
+	v2 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v2"
+
+	"github.com/cosmos/cosmos-sdk/testutil"
+	sdk "github.com/cosmos/cosmos-sdk/types"
+	"github.com/stretchr/testify/require"
+
+	"github.com/desmos-labs/desmos/v3/app"
+	v1 "github.com/desmos-labs/desmos/v3/x/relationships/legacy/v1"
+	"github.com/desmos-labs/desmos/v3/x/relationships/types"
+)
+
+func TestMigrateStore(t *testing.T) {
+	cdc, _ := app.MakeCodecs()
+	storeKey := sdk.NewKVStoreKey(types.StoreKey)
+	testCases := []struct {
+		name      string
+		store     func(ctx sdk.Context)
+		shouldErr bool
+		check     func(ctx sdk.Context)
+	}{
+		{
+			name: "relationships are migrated properly",
+			store: func(ctx sdk.Context) {
+				store := ctx.KVStore(storeKey)
+
+				relBz := cdc.MustMarshal(&types.Relationship{
+					Creator:      "user",
+					Counterparty: "counterparty",
+					SubspaceID:   1,
+				})
+				store.Set(v1.RelationshipsStoreKey("user", "counterparty", 1), relBz)
+			},
+			shouldErr: false,
+			check: func(ctx sdk.Context) {
+				store := ctx.KVStore(storeKey)
+
+				// Make sure the old keys are deleted properly
+				v1Key := v1.RelationshipsStoreKey("user", "counterparty", 1)
+				require.False(t, store.Has(v1Key))
+
+				v2Key := types.RelationshipsStoreKey("user", "counterparty", 1)
+				require.True(t, store.Has(v2Key))
+
+				var stored types.Relationship
+				err := cdc.Unmarshal(store.Get(v2Key), &stored)
+				require.NoError(t, err)
+				require.Equal(t, types.Relationship{
+					Creator:      "user",
+					Counterparty: "counterparty",
+					SubspaceID:   1,
+				}, stored)
+			},
+		},
+		{
+			name: "user blocks are migrated properly",
+			store: func(ctx sdk.Context) {
+				store := ctx.KVStore(storeKey)
+
+				blockBz := cdc.MustMarshal(&types.UserBlock{
+					Blocker:    "blocker",
+					Blocked:    "blocked",
+					Reason:     "reason",
+					SubspaceID: 1,
+				})
+				store.Set(v1.UserBlockStoreKey("blocker", "blocked", 1), blockBz)
+			},
+			shouldErr: false,
+			check: func(ctx sdk.Context) {
+				store := ctx.KVStore(storeKey)
+
+				// Make sure the old keys are deleted properly
+				v1Key := v1.UserBlockStoreKey("blocker", "blocked", 1)
+				require.False(t, store.Has(v1Key))
+
+				v2Key := types.UserBlockStoreKey("blocker", "blocked", 1)
+				require.True(t, store.Has(v2Key))
+
+				var stored types.UserBlock
+				err := cdc.Unmarshal(store.Get(v2Key), &stored)
+				require.NoError(t, err)
+				require.Equal(t, types.UserBlock{
+					Blocker:    "blocker",
+					Blocked:    "blocked",
+					Reason:     "reason",
+					SubspaceID: 1,
+				}, stored)
+			},
+		},
+	}
+
+	for _, tc := range testCases {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			ctx := testutil.DefaultContext(storeKey, sdk.NewTransientStoreKey("test"))
+			if tc.store != nil {
+				tc.store(ctx)
+			}
+
+			err := v2.MigrateStore(ctx, storeKey, cdc)
+			if tc.shouldErr {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+				if tc.check != nil {
+					tc.check(ctx)
+				}
+			}
+		})
+	}
+}
diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go
index 68096b66..212b04a3 100644
--- a/x/subspaces/keeper/msg_server_test.go
+++ b/x/subspaces/keeper/msg_server_test.go
@@ -65,6 +65,7 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateSubspace() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgCreateSubspace{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69"),
 				),
 				sdk.NewEvent(
@@ -119,6 +120,7 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateSubspace() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgCreateSubspace{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos18atyyv6zycryhvnhpr2mjxgusdcah6kdpkffq0"),
 				),
 				sdk.NewEvent(
@@ -179,6 +181,7 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateSubspace() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgCreateSubspace{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll"),
 				),
 				sdk.NewEvent(
@@ -371,6 +374,7 @@ func (suite *KeeperTestsuite) TestMsgServer_EditSubspace() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgEditSubspace{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"),
 				),
 				sdk.NewEvent(
@@ -492,6 +496,7 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteSubspace() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgDeleteSubspace{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"),
 				),
 				sdk.NewEvent(
@@ -675,6 +680,7 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgCreateUserGroup{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"),
 				),
 				sdk.NewEvent(
@@ -857,6 +863,7 @@ func (suite *KeeperTestsuite) TestMsgServer_EditUserGroup() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgEditUserGroup{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"),
 				),
 				sdk.NewEvent(
@@ -1077,6 +1084,7 @@ func (suite *KeeperTestsuite) TestMsgServer_SetUserGroupPermissions() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSetUserGroupPermissions{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"),
 				),
 				sdk.NewEvent(
@@ -1127,6 +1135,7 @@ func (suite *KeeperTestsuite) TestMsgServer_SetUserGroupPermissions() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSetUserGroupPermissions{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"),
 				),
 				sdk.NewEvent(
@@ -1269,6 +1278,7 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgDeleteUserGroup{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"),
 				),
 				sdk.NewEvent(
@@ -1447,6 +1457,7 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgAddUserToUserGroup{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"),
 				),
 				sdk.NewEvent(
@@ -1629,6 +1640,7 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgRemoveUserFromUserGroup{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"),
 				),
 				sdk.NewEvent(
@@ -1767,6 +1779,7 @@ func (suite *KeeperTestsuite) TestMsgServer_SetUserPermissions() {
 				sdk.NewEvent(
 					sdk.EventTypeMessage,
 					sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
+					sdk.NewAttribute(sdk.AttributeKeyAction, sdk.MsgTypeURL(&types.MsgSetUserPermissions{})),
 					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos17ua98rre5j9ce7hfude0y5y3rh4gtqkygm8hru"),
 				),
 				sdk.NewEvent(