| Crates.io | cw84 |
| lib.rs | cw84 |
| version | 2.1.0 |
| created_at | 2025-05-29 04:06:51.179823+00 |
| updated_at | 2025-07-16 02:44:02.739917+00 |
| description | Definition and types for the CosmWasm-84 interface |
| homepage | |
| repository | https://github.com/MegaRockLabs/cw-extra |
| max_upload_size | |
| id | 1693460 |
| size | 54,466 |
The CW84 standard defines an interface for CosmWasm-based smart contracts that enables account abstraction through custom authentication and authorization flows using signed payloads. It extends the capabilities of smart accounts by introducing signed message execution and validation, building on existing standards to provide a flexible and secure framework for smart contract interactions.
This standard is particularly suited for smart accounts that require custom signature verification schemes, allowing for advanced use cases such as delegated execution, multi-signature workflows, and application-specific authentication logic. Contracts implementing CW84 are fully compatible with a suite of related standards, ensuring interoperability within the CosmWasm ecosystem.
CW84-compliant contracts inherently support the following standards:
| Standard | Description |
|---|---|
cw-1 |
Proxy Contracts |
cw-2 |
Contract Info |
cw-81 |
Signature Verification |
cw-82 |
Minimal Smart Account |
cw-22 |
Supported Interface |
The CW84 standard defines a set of query and execute messages to support signed actions. The package provides procedural macros (#[signed_query] and #[signed_execute]) to inject the required variants into user-defined query and execute enums respectively. The package also expose minimal messages that implement the interface
The execute message that follows cw84 must include the standard Execute variant imposed by both cw82 and cw81 and a new variant ExecuteSigned that is a unique to this standard. To optimise the usage of resources and make your life easier it it's advisable to define a separate message e.g. ActionMsg that contains all the variant that can be execute this way
pub enum ActionMsg {
// Define your actions here
Foo { },
Bar { },
Execute { msgs: Vec<CosmosMsg> },
}
pub enum ExecuteMsg {
// cw82 | cw1
Execute {
msgs: Vec<CosmosMsg>,
signed: Option<Binary>, // Optional signature data for enhanced security
},
// cw84
ExecuteSigned {
msg : ActionMsg,
signed : Binary,
nonce: Option<Uint64>, // Optional nonce for replay protection
},
}
If you don't want to have a separate message it's also possible to inlcude the ExecuteMsg itself but you might need to have it inside a box and possibly deal deal with nested structure later
pub enum ExecuteMsg {
// ...
ExecuteSigned {
msg: Box<ExecuteMsg>,
signed: Binary,
nonce: Option<Uint64>, // Optional nonce for replay protection
}
}
With multi feature enabled, the msg field becomes a plural msgs and the previos message type turnig into a collection (Vec)
pub enum ExecuteMsg {
// ...
ExecuteSigned {
msgs: Vec<ActionMsg>, // or Vec<ExecuteMsg>, Box isn't necessary in this case
signed: Binary,
nonce: Option<Uint64>, // Optional nonce for replay protection
}
}
In case you went for separating signable actions into a separate message type like ActionMsg the standards suggests on adding an additional variant for doing multiple actions through the native flow
pub enum ExecuteMsg {
// ...
ExecuteNative {
msgs: Vec<ActionMsg>,
},
}
Without a separation or when including Self it defeats the purpose and as an optional variant it's for the better to omit it
The signed field is a binary payload that can be used to pass additional information required for signature verification or other custom logic. However the contracts aren't required to use cosmwasm_std::Binary which is used by default and can replace it with any signed data object that fits their needs. Take a look at SignedDataMsg from smart-account-auth if you look for potential options.
signed_execute: Primary effect is injects both variants (Execute and ExecuteSigned) described above into your enum. Takes up to two positional arguments to customise the behaviour. The first argument is used to set the message type allowed to be signed like ActionMsg from above. The second argument is used to customise the type of signed to use something other than cosmwasm_std::Binary
With both multi feature tag active and first positional argument passed the macro also injects the plural variant ExecuteNative as described above.
The Execute variant now includes an optional signed field for enhanced security, and both ExecuteSigned variants include an optional nonce field for replay protection.
use cw84::signed_execute;
use cosmwasm_schema::cw_serde;
#[signed_execute]
#[cw_serde]
enum ExecuteMsg {}
which is equivalent to:
enum ExecuteMsg {
Execute {
msgs: Vec<CosmosMsg>,
signed: Option<Binary>,
},
ExecuteSigned {
msg: ActionMsg,
signed: Binary,
nonce: Option<Uint64>,
},
}
use cw84::signed_execute;
use cosmwasm_schema::cw_serde;
#[signed_execute(ActionMsg, SignedDataMsg)]
#[cw_serde]
enum ExecuteMsg {}
Which is equivalent to:
enum ExecuteMsg {
Execute {
msgs: Vec<CosmosMsg>,
signed: Option<SignedDataMsg>,
},
ExecuteSigned {
msgs: Vec<ActionMsg>,
signed: SignedDataMsg, // or Binary if you didn't pass the second argument
nonce: Option<Uint64>,
},
// If `multi` feature is enabled and first argument is passed
ExecuteNative {
msgs: Vec<ActionMsg>
},
}
The query interface includes variants for checking execution permissions and validating signatures, with support for single and multi-signature verification via the multi feature. The Cw84QueryMsg enum defines the minimum required queries.
cw84 requires all the compatible contracts have all the query variants imposed by cw82, namely:
In addition to them all the compliant contracts must add the following new query variant:
enum QueryMsg {
#[returns(::cw1::CanExecuteResponse)]
CanExecuteSigned {
msg: ExecuteMsg,
signed: Binary,
nonce: Option<Uint64>, // Optional nonce for replay protection
}
}
The feature multi, the type of signed field behaves identical to what was described in the ExecuteMsg section. The response object when multi is enabled is CanExecuteSignedResponse that contains vector of booleans indicating whether each message can be executed or not.
The nonce field provides replay protection and is included in both single and multi variants of CanExecuteSigned.
#[cw_serde]
struct CanExecuteSignedResponse {
pub can_execute: Vec<bool>,
}
signed_query macro injects all the necessary methods into your enum. It takes a mandatory positional argument that indicates an ExecuteMsg or even better ActionMsg defined by your contract. It also takes up to two additional type arguments. First one is used to set the type of signed field, which defaults to cosmwasm_std::Binary. The second one is customise payload for cw81 queries (ValidSignature)
use cw84::signed_query;
use cosmwasm_schema::{cw_serde, QueryResponse};
#[signed_query(ActionMsg)]
#[cw_serde]
#[derive(QueryResponses)]
enum QueryMsg {}
which is equivalent to:
enum QueryMsg {
// cw84
CanExecuteSigned {
msg: ActionMsg,
signed: Binary,
nonce: Option<Uint64>,
},
// cw82 | cw1
CanExecute {
sender: String,
msg: CosmosMsg,
},
// cw82 | cw1 (injected when arguments provided)
CanExecuteNative {
sender: String,
msg: CosmosMsg,
},
// cw81
ValidSignature {
data: Binary,
signature: Binary,
payload: Option<Binary>,
},
}
use cw84::signed_query;
use cosmwasm_schema::{cw_serde, QueryResponse};
#[signed_query(ActionMsg, SignedDataMsg, AuthPayload)]
#[cw_serde]
#[derive(QueryResponses)]
enum QueryMsg {}
which is equivalent to:
enum QueryMsg {
// cw84
CanExecuteSigned {
msg: ActionMsg,
signed: SignedDataMsg,
nonce: Option<Uint64>,
},
// cw82 | cw1
CanExecute {
sender: String,
msg: CosmosMsg,
},
// cw82 | cw1 (injected when arguments provided)
CanExecuteNative {
sender: String,
msg: CosmosMsg,
},
// cw81
ValidSignature {
data: Binary,
signature: Binary,
payload: Option<AuthPayload>,
},
// cw81-multi
ValidSignatures {
data: Vec<Binary>,
signatures: Vec<Binary>,
payload: Option<AuthPayload>,
},
}
Examples to be used as a reference or used directly to avoid reinventing the wheel and give the best compatibility with existing ecosystem
ExecuteMsg from the Account contract by AbstrackSdk
AuthenticatorSudoMsg by Osmosis for account contracts using x/smart-account module
There are multiple possible options that are all defined in smart-account-auth authentication library:
CredentialsWrapper both of which represent more general version of the first two options respectively.extension fieldThere are also the following options from different sources:
cw-authenticatorof Osmosiscosmwasm_stdAdditionaly we can define a new type combine any of the abobe