# Proposal: x/wauth module

**URL:** <https://forum.cosmos.network/t/proposal-x-wauth-module/17064>\
**Category:** Proposal Ideas\
**Created:** [June 16, 2026, 7:28am UTC](https://forum.cosmos.network/t/proposal-x-wauth-module/17064 "2026-06-16T07:28:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tulkinbekov](https://avatars.discourse-cdn.com/v4/letter/t/278dde/32.png) [@tulkinbekov](https://forum.cosmos.network/u/tulkinbekov)\
**Post date:** [June 16, 2026, 7:28am UTC](https://forum.cosmos.network/t/proposal-x-wauth-module/17064/1 "2026-06-16T07:28:52Z")

</div>

## **Native Authorization-Based Transfer Module for the Cosmos SDK**

## Summary

This topic proposes `x/wauth` (WAuth =\> “with authorization”), a new Cosmos SDK module that introduces off-chain-signed, on-chain-settled token transfers. The design is semantically equivalent to Ethereum’s EIP-3009 (`transferWithAuthorization`) but implemented as a first-class Cosmos SDK module with no EVM dependency. A working reference implementation targeting `cosmos/evm` is available and production-ready.

* * *

## Motivation

The Cosmos SDK’s transfer model requires the token sender to submit and pay for every transaction. This is the right default, but it makes an entire class of application patterns difficult or impossible to implement cleanly:

- **Meta-transactions / gas abstraction** : end users should not need to hold the native fee token to interact with an application.

- **Delegated and pull payments** : a recipient or relayer should be able to settle a pre-authorized payment without requiring another round-trip to the sender.

- **Machine-to-machine and API-triggered payments** : services built on the x402 pay-per-request standard need to settle blockchain payments in response to HTTP events, not interactive wallet sessions.

- **Subscription and batch billing** : a billing relayer needs to settle multiple pre-signed authorizations in a single transaction.

EVM chains address this with EIP-2612 (permit) and EIP-3009 (`transferWithAuthorization`). These are now ubiquitous building blocks in that ecosystem. Cosmos has `x/authz` and `x/feegrant`, which solve adjacent problems (persistent delegated execution grants and fee sponsorship, respectively), but neither provides a stateless, single-use signed payment primitive. `x/wauth` fills that gap.

* * *

## Design

### Authorization Structure

An `Authorization` is a signed, off-chain payment intent with the following fields:

| Field | Type | Description |
| --- | --- | --- |
| `from` | `sdk.AccAddress` | Spender (signs the authorization off-chain) |
| `to` | `sdk.AccAddress` | Recipient |
| `coins` | `sdk.Coins` | Multi-denom transfer amount |
| `nonce` | `[32]byte` | Cryptographically random, single-use value |
| `valid_after` | `time.Time` | Optional activation time |
| `valid_before` | `time.Time` | Required expiry deadline |
| `chain_id` | `string` | Prevents cross-chain replay attacks |
| `memo` | `string` | Relayer annotation (excluded from signing digest) |

The `memo` field is deliberately excluded from the signing digest, `sha256(gogoproto.Marshal(authorization_with_memo_cleared))` so relayers can annotate transactions without invalidating the user’s signature.

### Message Types

The module exposes four messages, mirroring the EIP-3009 interface:

| Message | Submitter | EIP-3009 Analogue |
| --- | --- | --- |
| `MsgTransferWithAuthorization` | Relayer (facilitator) | `transferWithAuthorization` |
| `MsgReceiveWithAuthorization` | Recipient | `receiveWithAuthorization` |
| `MsgMultiTransferWithAuthorization` | Relayer | _(batch extension - no EVM equivalent)_ |
| `MsgCancelAuthorization` | Original signer | `cancelAuthorization` |

#### MsgTransferWithAuthorization

A third-party facilitator submits a user-signed authorization. The chain verifies the sender’s signature, checks the nonce, validates the time window, and calls `bankKeeper.SendCoins`. The facilitator pays gas; the sender’s funds move without any on-chain action from the sender.

#### MsgReceiveWithAuthorization

The designated recipient submits the authorization. The receiver field must match `authorization.to`, preventing front-running by other parties.

#### MsgMultiTransferWithAuthorization

A batch message supporting up to 100 `(authorization, signature)` pairs. Each item is validated and settled independently; per-item failures are reported in the response without rolling back the entire batch. This is essential for billing relayers settling many subscriptions in a single block.

#### MsgCancelAuthorization

Marks a nonce as consumed without executing a transfer, allowing users to revoke an outstanding authorization before it is settled.

### Replay Protection

Each nonce is a 32-byte cryptographically random value (not a counter). After settlement or cancellation, the nonce is recorded in the module’s KV store keyed by `(sender_address, nonce)`. Nonce records carry a `prune_after` timestamp (`valid_before + nonce_prune_grace_period`) to allow safe cleanup without a pruning race condition.

### Signature Verification

The signing digest is `sha256(proto_marshal(authorization_without_memo))`. Verification supports:

- **secp256k1** (Cosmos-native): standard `VerifySignature` over the 32-byte SHA-256 digest.

- **eth\_secp256k1** (EVM-compatible): native compact signature verification using standard ECDSA semantics.

Signatures are 64-byte compact (R+S) or 65-byte with recovery bit; the recovery bit is stripped before verification.

### Module Parameters (governance-controlled)

| Parameter | Default | Constraint |
| --- | --- | --- |
| `max_valid_window_seconds` | `3600` (1 hour) | ≤ 2,592,000 (30 days) |
| `nonce_prune_grace_period_seconds` | `600` (10 min) | ≥ 0 |
| `enabled_denoms` | `[]` (all allowed) | Optional governance allowlist |

**### Relationship to Existing Modules**

| Module | Purpose | Difference from `x/wauth` |
| --- | --- | --- |
| `x/authz` | Persistent, re-usable execution grants | Grants persist until revoked; `x/wauth` authorizations are single-use and stateless until settled. |
| `x/feegrant` | Fee sponsorship for the grantee’s transactions | Pays gas for on-chain txs; does not settle token transfers. |
| `x/bank` | Core transfer primitive | `x/wauth` calls `bankKeeper.SendCoins` — it is a composable layer above, not a replacement. |

* * *

## x402 Compatibility

`x/wauth` is designed as the settlement layer for Coinbase/x402, a protocol for HTTP-native blockchain payments. In this model:

1. A client signs an `Authorization` offline and includes it in an HTTP request header.

2. The API server or a payment processor verifies the signature, serves the request, and submits `MsgTransferWithAuthorization` to settle.

3. The chain settles the payment atomically on the next block.

This enables pay-per-request APIs, metered subscriptions, and IoT micropayments without requiring the client to interact with the chain directly during the payment flow. The `MsgMultiTransferWithAuthorization` batch message supports settlement aggregation across many requests per block.

* * *

## Security Considerations

- **Replay protection** : enforced by 32-byte random nonces (not counters) to prevent ordering attacks. Cross-chain replay is blocked by the mandatory `chain_id` field in the signing payload.

- **Front-running on `ReceiveWithAuthorization`** : the receiver address is locked in the signed payload. A front-runner submitting `MsgTransferWithAuthorization` would succeed as a facilitator (funds still go to the correct recipient) but cannot redirect funds.

- **Griefing via cancellation** : `MsgCancelAuthorization` is signed by the originating account, so only the sender can cancel their own nonces.

- **Time window bounds** : `max_valid_window_seconds` (default 1h) is enforced on-chain to prevent authorizations with indefinitely long validity windows.

- **Denom allowlist** : chain operators can restrict `x/wauth` to specific token denominations via governance.

- **Blocked addresses** : `bankKeeper.BlockedAddr` is respected; module accounts and other restricted addresses cannot receive funds through `x/wauth`.

* * *

## Reference Implementation

A complete, tested implementation is available targeting `cosmos/evm`. It includes:

- Protobuf definitions for all message and query types

- Keeper with nonce store and governance-controlled params

- Full `ValidateBasic` and keeper-level validation

- CLI commands for all message types and queries

- Unit and integration tests

I am prepared to port this to `cosmos/cosmos-sdk` as a standalone module or as an extension under `x/bank`.

* * *

## Questions for the Team

1. **Scope** : Should this be proposed as a core SDK module, or a standalone maintained module? If core, which repository is the right target (`cosmos-sdk` or `cosmos/evm`)?

2. **Signing standard** : The current digest is `sha256(proto_marshal(auth))`. Is there interest in aligning with a Cosmos-native typed signing standard (e.g. SignDoc-compatible) to support hardware wallets and Ledger out of the box?

* * *

I would be pleased to provide any additional information upon request. I would also greatly appreciate any feedback or suggestions regarding potential future directions.

* * *

_Tillo Tulkinbekov_

_Blockchain Engineer, Gurufin - South Korea_

_[tulkinbekov@gurufin.com](mailto:tulkinbekov@gurufin.com) / [t.tulkinbekov@gmail.com](mailto:t.tulkinbekov@gmail.com)_

---

<div class="post-metadata">

**Author:** ![rattadan](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.cosmos.network/rattadan/32/9148_2.png) [@rattadan](https://forum.cosmos.network/u/rattadan)\
**Post date:** [June 19, 2026, 6:30am UTC](https://forum.cosmos.network/t/proposal-x-wauth-module/17064/2 "2026-06-19T06:30:36Z")

</div>

Looks like a profound work, but still some question:  
I guess the initiator/receiver that will trigger the release needs at least an already initialized wallet (with sequence number). This might turn out a major problem in real environment: The service won’t work out of the box, or at least will be limited to the small batch of current cosmos users.

I created a similiar concept using cosmwasm too, that allows usual webapps to hand out Tokens to users.  
The webapp doesn’t need to run a local signing or broadcasting client in the backend, its just creating the message that will trigger the escrow contract to release the funds mentioned in the tx

Here is the schematics:

 ![image](https://canada1.discourse-cdn.com/flex031/uploads/cosmos1/original/2X/4/46d9ee854333491f4afc501ce3650a77b52c0271.jpeg)

> **[Mintscan](https://www.mintscan.io/cosmos/tx/40833E2A89550C51593D971467DF0EF57009FD65D44060663AF2F6779D8CDC71?height=31635250)**
>
> Interchain block explorer and data analytics for sovereign blockchain networks.

WebApp

Composes the voucher message and decides the Token amount that shall  
be sent to the user

The ECDSA signature is derived from this execution message body and is being attached below

The WebApp holds the ECDSA private key in his .ENV Variable only, no backend client necessary

The contract holds the ECDSA public key only  
-it checks if the attached signature matches the message body  
-it checks if the nounce has been used already  
-it checks if the expiry date has been exceeded

if all conditions are met, the message gets executed and funds are being transferred  
from the contract treasury to the user

otherwise the message is being dropped

---

<div class="post-metadata">

**Author:** ![RoboMcGobo](https://yyz1.discourse-cdn.com/flex031/user_avatar/forum.cosmos.network/robomcgobo/32/5444_2.png) [@RoboMcGobo](https://forum.cosmos.network/u/RoboMcGobo)\
**Post date:** [June 25, 2026, 7:03pm UTC](https://forum.cosmos.network/t/proposal-x-wauth-module/17064/3 "2026-06-25T19:03:00Z")

</div>

Hi! Thanks for sharing this.

Can I ask what you’re using it for today, or plan to use it for?

---

<div class="post-metadata">

**Author:** ![tulkinbekov](https://avatars.discourse-cdn.com/v4/letter/t/278dde/32.png) [@tulkinbekov](https://forum.cosmos.network/u/tulkinbekov)\
**Post date:** [July 3, 2026, 4:56am UTC](https://forum.cosmos.network/t/proposal-x-wauth-module/17064/4 "2026-07-03T04:56:09Z")

</div>

Thank you for the interest!

We plan to use it as agentic payment option for Gurufin chain. It is built on top of cosmos/evm repository

---

<div class="post-metadata">

**Author:** ![tulkinbekov](https://avatars.discourse-cdn.com/v4/letter/t/278dde/32.png) [@tulkinbekov](https://forum.cosmos.network/u/tulkinbekov)\
**Post date:** [July 3, 2026, 4:58am UTC](https://forum.cosmos.network/t/proposal-x-wauth-module/17064/5 "2026-07-03T04:58:01Z")

</div>

@rattadan That is an interesting alternative! Meanwhile, we are working on fixing the PubKey issue on chain for new accounts
