Skip to main content
Version: Next

x/feegrant

Abstract

This document specifies the fee grant module. For the full ADR, please see Fee Grant ADR-029.

This module allows accounts to grant fee allowances and to use fees from their accounts. Grantees can execute any transaction without the need to maintain sufficient fees.

Contents

Concepts

Grant

Grant is stored in the KVStore to record a grant with full context. Every grant will contain granter, grantee and what kind of allowance is granted. granter is an account address who is giving permission to grantee (the beneficiary account address) to pay for some or all of grantee's transaction fees. allowance defines what kind of fee allowance (BasicAllowance or PeriodicAllowance, see below) is granted to grantee. allowance accepts an interface which implements FeeAllowanceI, encoded as Any type. There can be only one existing fee grant allowed for a grantee and granter, self grants are not allowed.

x/feegrant/proto/cosmos/feegrant/v1beta1/feegrant.proto
loading...

FeeAllowanceI looks like:

x/feegrant/fees.go
loading...

Fee Allowance types

There are two types of fee allowances present at the moment:

  • BasicAllowance
  • PeriodicAllowance
  • AllowedMsgAllowance

BasicAllowance

BasicAllowance is permission for grantee to use fee from a granter's account. If any of the spend_limit or expiration reaches its limit, the grant will be removed from the state.

x/feegrant/proto/cosmos/feegrant/v1beta1/feegrant.proto
loading...
  • spend_limit is the limit of coins that are allowed to be used from the granter account. If it is empty, it assumes there's no spend limit, grantee can use any number of available coins from granter account address before the expiration.

  • expiration specifies an optional time when this allowance expires. If the value is left empty, there is no expiry for the grant.

  • When a grant is created with empty values for spend_limit and expiration, it is still a valid grant. It won't restrict the grantee to use any number of coins from granter and it won't have any expiration. The only way to restrict the grantee is by revoking the grant.

PeriodicAllowance

PeriodicAllowance is a repeating fee allowance for the mentioned period, we can mention when the grant can expire as well as when a period can reset. We can also define the maximum number of coins that can be used in a mentioned period of time.

x/feegrant/proto/cosmos/feegrant/v1beta1/feegrant.proto
loading...
  • basic is the instance of BasicAllowance which is optional for periodic fee allowance. If empty, the grant will have no expiration and no spend_limit.

  • period is the specific period of time, after each period passes, period_can_spend will be reset.

  • period_spend_limit specifies the maximum number of coins that can be spent in the period.

  • period_can_spend is the number of coins left to be spent before the period_reset time.

  • period_reset keeps track of when a next period reset should happen.

AllowedMsgAllowance

AllowedMsgAllowance is a fee allowance, it can be any of BasicFeeAllowance, PeriodicAllowance but restricted only to the allowed messages mentioned by the granter.

x/feegrant/proto/cosmos/feegrant/v1beta1/feegrant.proto
loading...
  • allowance is either BasicAllowance or PeriodicAllowance.

  • allowed_messages is array of messages allowed to execute the given allowance.

FeeGranter flag

feegrant module introduces a FeeGranter flag for CLI for the sake of executing transactions with fee granter. When this flag is set, clientCtx will append the granter account address for transactions generated through CLI.

client/cmd.go
loading...
client/tx/tx.go
loading...
x/auth/tx/builder.go
loading...
proto/cosmos/tx/v1beta1/tx.proto
loading...

Example cmd:

simd tx gov submit-legacy-proposal --title="Test Proposal" --description="My awesome proposal" --type="Text" --from validator-key --fee-granter=cosmos1xh44hxt7spr67hqaa7nyx5gnutrz5fraw6grxn --chain-id=testnet --fees="10stake"

Granted Fee Deductions

Fees are deducted from grants in the x/auth ante handler. To learn more about how ante handlers work, read the Auth Module AnteHandlers Guide.

Gas

In order to prevent DoS attacks, using a filtered x/feegrant incurs gas. The SDK must assure that the grantee's transactions all conform to the filter set by the granter. The SDK does this by iterating over the allowed messages in the filter and charging 10 gas per filtered message. The SDK will then iterate over the messages being sent by the grantee to ensure the messages adhere to the filter, also charging 10 gas per message. The SDK will stop iterating and fail the transaction if it finds a message that does not conform to the filter.

WARNING: The gas is charged against the granted allowance. Ensure your messages conform to the filter, if any, before sending transactions using your allowance.

Pruning

A queue in the state maintained with the prefix of expiration of the grants and checks them on EndBlock with the current block time for every block to prune.

State

FeeAllowance

Fee Allowances are identified by combining Grantee (the account address of fee allowance grantee) with the Granter (the account address of fee allowance granter).

Fee allowance grants are stored in the state as follows:

  • Grant: 0x00 | grantee_addr_len (1 byte) | grantee_addr_bytes | granter_addr_len (1 byte) | granter_addr_bytes -> ProtocolBuffer(Grant)
x/feegrant/feegrant.pb.go
loading...

FeeAllowanceQueue

Fee Allowances queue items are identified by combining the FeeAllowancePrefixQueue (i.e., 0x01), expiration, grantee (the account address of fee allowance grantee), granter (the account address of fee allowance granter). Endblocker checks FeeAllowanceQueue state for the expired grants and prunes them from FeeAllowance if there are any found.

Fee allowance queue keys are stored in the state as follows:

  • Grant: 0x01 | expiration_bytes | grantee_addr_len (1 byte) | grantee_addr_bytes | granter_addr_len (1 byte) | granter_addr_bytes -> EmptyBytes

Messages

Msg/GrantAllowance

A fee allowance grant will be created with the MsgGrantAllowance message.

x/feegrant/proto/cosmos/feegrant/v1beta1/tx.proto
loading...

Msg/RevokeAllowance

An allowed grant fee allowance can be removed with the MsgRevokeAllowance message.

x/feegrant/proto/cosmos/feegrant/v1beta1/tx.proto
loading...

Events

The feegrant module emits the following events:

Msg Server

MsgGrantAllowance

TypeAttribute KeyAttribute Value
messageactionset_feegrant
messagegranter{granterAddress}
messagegrantee{granteeAddress}

MsgRevokeAllowance

TypeAttribute KeyAttribute Value
messageactionrevoke_feegrant
messagegranter{granterAddress}
messagegrantee{granteeAddress}

Exec fee allowance

TypeAttribute KeyAttribute Value
messageactionuse_feegrant
messagegranter{granterAddress}
messagegrantee{granteeAddress}

Prune fee allowances

TypeAttribute KeyAttribute Value
messageactionprune_feegrant
messagepruner{prunerAddress}

Client

CLI

A user can query and interact with the feegrant module using the CLI.

Query

The query commands allow users to query feegrant state.

simd query feegrant --help
grant

The grant command allows users to query a grant for a given granter-grantee pair.

simd query feegrant grant [granter] [grantee] [flags]

Example:

simd query feegrant grant cosmos1.. cosmos1..

Example Output:

allowance:
'@type': /cosmos.feegrant.v1beta1.BasicAllowance
expiration: null
spend_limit:
- amount: "100"
denom: stake
grantee: cosmos1..
granter: cosmos1..
grants-by-grantee

The grants-by-grantee command allows users to query all grants for a given grantee.

simd query feegrant  grants-by-grantee [grantee] [flags]

Example:

simd query feegrant grants-by-grantee cosmos1..

Example Output:

allowances:
- allowance:
'@type': /cosmos.feegrant.v1beta1.BasicAllowance
expiration: null
spend_limit:
- amount: "100"
denom: stake
grantee: cosmos1..
granter: cosmos1..
pagination:
next_key: null
total: "0"
grants-by-granter

The grants-by-granter command allows users to query all grants created by a given granter.

simd query feegrant grants-by-granter [granter] [flags]

Example:

simd query feegrant grants-by-granter cosmos1..

Example Output:

allowances:
- allowance:
'@type': /cosmos.feegrant.v1beta1.BasicAllowance
expiration: null
spend_limit:
- amount: "100"
denom: stake
grantee: cosmos1..
granter: cosmos1..
pagination:
next_key: null
total: "0"

Transactions

The tx commands allow users to interact with the feegrant module.

simd tx feegrant --help
grant

The grant command allows users to grant fee allowances to another account. The fee allowance can have an expiration date, a total spend limit, a periodic spend limit, and/or allowed messages.

simd tx feegrant grant [granter] [grantee] [flags]

Examples:

One-time spend limit
simd tx feegrant grant cosmos1.. cosmos1.. --spend-limit 100stake
Periodic spend limit
simd tx feegrant grant cosmos1.. cosmos1.. --spend-limit 100stake --period 3600 --period-limit 10stake
With expiration
simd tx feegrant grant cosmos1.. cosmos1.. --spend-limit 100stake --expiration 2024-10-31T15:04:05Z
With allowed messages
simd tx feegrant grant cosmos1.. cosmos1.. --spend-limit 100stake --expiration 2024-10-31T15:04:05Z --allowed-messages "/cosmos.gov.v1beta1.MsgSubmitProposal,/cosmos.gov.v1beta1.MsgVote"

Available flags:

  • --spend-limit: The maximum amount of tokens the grantee can spend
  • --period: The time duration in seconds for periodic allowance
  • --period-limit: The maximum amount of tokens the grantee can spend within each period
  • --expiration: The date and time when the grant expires (RFC3339 format)
  • --allowed-messages: Comma-separated list of allowed message type URLs
revoke

The revoke command allows users to revoke a granted fee allowance.

simd tx feegrant revoke [granter] [grantee] [flags]

Example:

simd tx feegrant revoke cosmos1.. cosmos1..

gRPC

A user can query the feegrant module using gRPC endpoints.

Allowance

The Allowance endpoint allows users to query a granted fee allowance.

cosmos.feegrant.v1beta1.Query/Allowance

Example:

grpcurl -plaintext \
-d '{"grantee":"cosmos1..","granter":"cosmos1.."}' \
localhost:9090 \
cosmos.feegrant.v1beta1.Query/Allowance

Example Output:

{
"allowance": {
"granter": "cosmos1..",
"grantee": "cosmos1..",
"allowance": {"@type":"/cosmos.feegrant.v1beta1.BasicAllowance","spendLimit":[{"denom":"stake","amount":"100"}]}
}
}

Allowances

The Allowances endpoint allows users to query all granted fee allowances for a given grantee.

cosmos.feegrant.v1beta1.Query/Allowances

Example:

grpcurl -plaintext \
-d '{"address":"cosmos1.."}' \
localhost:9090 \
cosmos.feegrant.v1beta1.Query/Allowances

Example Output:

{
"allowances": [
{
"granter": "cosmos1..",
"grantee": "cosmos1..",
"allowance": {"@type":"/cosmos.feegrant.v1beta1.BasicAllowance","spendLimit":[{"denom":"stake","amount":"100"}]}
}
],
"pagination": {
"total": "1"
}
}