Learn the basics of working with the IBC Developer Toolkit
Loading...
Loading...
Loading...
Loading...
Loading...
CCL IBC SDK for typescript developers
For encryption, we recommend using @solar-republic/neutrino
which has useful chacha20poly1305
related functionalities and additional primitives for generating ephemereal lightweight wallets. Installation:
For signing, encoding and other cryptographic needs in the Cosmos ecosystem, it is common to use the suite of @cosmjs
packages. You can install the following:
If you are developing in the browser environment or connecting to a public network you might also need
Note: You can also use any Typescript / Javascript package managers and runtimes e,g, bun
, yarn
, pnpm
etc.
For chacha20poly1305
, we need to use a crypthographic keypair and it's advised to use one that isn't the same as the user's wallet. The SDK provides a method for generating a new wallet that can be used for encryption purposes. For our purposes, we just need a private / public keys of Secp256k1
type and there are various ways to generate them.
@cosmjs/crypto
@solar-republic/neutrino
@secretjs
Before proceeding to encryption, you might want to create a quering client that will be used for querying the state and contract of the Secret Network. At the very least, it is requited for fetching the public key of a gateway contract for deriving a shared key used later for encryption.
To perform a simple query on a secret contract we can use methods from @solar-republic/neutrino
:
For more persistent use-cases you can use secretjs:
To make sure that malicious applications aren't tricking the user into signing an actual blockchain transaction, it is discouraged to sign arbitrary blobs of data. To address the situation, there are various standards that inject additional data to the message before signing it. The most used in the Cosmos ecosystem is defined in ADR 036 which is also used in the SDK.
Most of the Cosmos wallets provide a method for signing arbitrary messages following the mentioned specification.
Here is a definition taken from documentation of Keplr wallet:
Although the API method requires a chainId,
it is set to empty string before signing the message
Cosmology
Cosmology defines signArbitrary
method as part of the interface for their wallet client and provides implementation / integration for every popular Cosmos wallet out there
CosmJS
The logic of the method has already been implemented and proposed as an addition to the library however it has been hanging in a unmerged PR for a while. You can find the full implementation with examples and tests [PR] Here
Manually
Firstly we need to get an amino signer that will be used for generating the signature. @cosmjs
has a defined interface OfflineAminoSigner
with signAmino
and getAccounts
methods and any other signer that implements it can be used for the purpose.
StdSignDoc
To use signAmino,
we need to generate a StdSignDoc
object that will be used for signing the message to pass as an argument.
CosmJS provides a function for this:
The 036 standard requires the message fields to AminoMsg to be:
As for the rest of the fields, they can be set to an empty string or 0. The final example will look like this:
After getting the document we can sign it with the signer:
After getting a public key of a gateway contract you can use it to derive a shared key like this:
Produced digest of hashing the ciphertext can be used as our message that we want to sign according to the 036 standard. The final message will look like this:
After this we are getting all the required fields for creating an EncryptedPayload
message or an ExecuteMsg::Encrypted { ... }
The encrypted message is safe to broadcast over public blockchain and other infrastructure. A common use-case in context of Cosmos account might be broadcasting it over IBC originating from a chain other than the Secret Network.
The potential use-case might involve broadcasting the message by initiating an IBC message directly and attaching the message as a payload (IBC-Hook) or passing the message to a smart contract on a remote chain to process and bridge it to the Secret Network.
Since Cosmwasm is quite flexible with defining messages due to supporting JSON serialization, it is possible the process is very similar in both cases so we only going to cover IBC-hooks for simplicity:
The Secret Network CCL SDK can be forked here.
The essential parameters required for chacha20poly1305
flow are defined in the following data structure:
EncryptedParams
A data structure that is visible to all network participants and can be transmitted over non-secure channels
Data meant to be encrypted and stored in the payload field of EncryptedParams
Your contract must define an endpoint where a user can pass all the required fields of the EncryptedParams
. E.g:
If you want to define a custom message, rename the fields, or add additional fields, there is a helpful trait WithEncryption
that you can implement. It simply tells the compiler how to extract the essential parameters from your custom message and turn it into EncryptedParams
Implementing the trait for your message will allow you to use other useful methods of the SDK (like handle_encrypted_wrapper
) that significantly simplify the development experience.
Example of the implementation for the ExecuteMsg
is as follows:
The SDK has multiple data structures that already implement WithEncryption
trait and also use the template engine of Rust to make them easily extendable. Take for example the following message:
You can define a new message that extends the GatewayExecuteMsg
by simply providing a new type for the Extension
instead of the default Option<Empty>
like this:
Your extended type in this case is available under MyGatewayExecuteMsg::Extension
variant and you can use it in your contract like this:
handle_encrypted_wrapper
The encryption logic, handle_encrypted_wrapper
, is where the encryption magic happens ⭐
You can review the function in the SDK here. It has the following functionality:
Check if Message is Encrypted:
If the message is encrypted (msg.is_encrypted()
), it proceeds with decryption.
Extract Encryption Parameters:
Retrieves the encryption parameters from the message (msg.encrypted()
).
Check Nonce:
Ensures the nonce has not been used before to prevent replay attacks.
Load Encryption Wallet:
Loads the encryption wallet from storage.
Decrypt Payload:
Decrypts the payload using the wallet and the provided parameters (payload
, user_key
, and nonce
).
decrypt_to_payload uses chacha20poly1305 algorithm
Verify Credentials:
Constructs a CosmosCredential
from the decrypted data.
Inserts the nonce into storage to mark it as used.
Verifies the sender using the verify_arbitrary
function with the credential.
Deserialize Inner Message:
Converts the decrypted payload into the original message type E
.
Ensures the decrypted message is not encrypted (nested encryption is not allowed).
Return Decrypted Message and Updated Info:
Returns the decrypted message and updated MessageInfo
with the verified sender.
chacha20poly1305_decrypt
The following function uses the following types for as the input parameters:
cosmwasm_std::Binary
,
std::vec::Vec
.
[u8]
and others that implement Deref<Target = [u8]>
trait
To verify a message that was was signed through a method cosmos arbitrary (036)
message format, you can use the following function:
The method takes in a CosmosCredential
struct as an argument which is a a helpful wrapper over essential required fields required for the verification:
Both CosmosCredential
and EncryptedParams
can be used with String
or base64 encoded Binary
types
To generate a preamble message for the cosmos arbitrary (036)
message format, you can use the following utility function:
The function uses a hardcoded JSON string with all the required keys present and sorted.
Secret Network's CCL (Confidential Computing Layer) IBC Toolkit is a cross-chain messaging and confidential computation SDK for Cosmos developers.
The toolkit allows Cosmos developers to build novel cross-chain applications such as:
private DAO voting mechanisms
secure random number generation (Secret VRF)
confidential data access control via Secret NFTs
encrypted DeFi order books
and more!
Continue to Cross-Chain messaging to learn how to use Secret Network's Confidential Computing Layer SDK , or dive into the Key value store tutorial here🔥
Initiate a contract call with an incoming IBC token transfer using IBC hooks
IBC-Hooks is an IBC middleware that uses incoming ICS-20 token transfers to initiate smart contract calls. This allows for arbitrary data to be passed in along with token transfers. This is useful for a variety of use cases such as cross-chain token swaps, auto-wrapping of SNIP-20 tokens, General Message Passing (GMP) between Secret Network and EVM chains, and much more! The mechanism enabling this is a memo
field on every ICS20 transfer packet as of IBC v3.4.0. Wasm hooks is an IBC middleware that parses an ICS20 transfer, and if the memo
field is of a particular form, it executes a Wasm contract call.
Note that the metadata in the memo
field is not used within ICS-20 itself, but instead, a middleware or custom CosmWasm contract can wrap around the transfer protocol to parse the metadata and execute custom logic based off of it. See more here.
ICS20 is JSON native, so JSON is used for the memo format:
An ICS20 packet is formatted correctly for Wasm hooks if the following all hold:
memo
is not blank
memo
is valid JSON
memo
has at least one key, with value "wasm"
memo["wasm"]
has exactly two entries, "contract"
and "msg"
memo["wasm"]["msg"]
is a valid JSON object
receiver == memo["wasm"]["contract"]
If an ICS20 packet is not directed towards wasmhooks, wasmhooks doesn't do anything. If an ICS20 packet is directed towards wasmhooks, and is formatted incorrectly, then wasmhooks returns an error.
Before Wasm hooks:
Ensure the incoming IBC packet is cryptographically valid
Ensure the incoming IBC packet has not timed out
In Wasm hooks, before packet execution:
Ensure the packet is correctly formatted (as defined above)
Edit the receiver to be the hardcoded IBC module account
In Wasm hooks, after packet execution:
Construct wasm message as defined above
Execute wasm message
If wasm message has error, return ErrAck
Otherwise continue through middleware
The following contract receives funds from IBC, wraps them as SNIP-20 tokens, and then transfers them to the recipient that is specified in the ibc-hooks message:
A contract that sends an IBC transfer may need to listen for the acknowledgment (ack
) of that packet. To allow contracts to listen to ack
of specific packets, we provide Ack callbacks. The sender of an IBC transfer packet may specify a callback in the memo
field of the transfer packet when the ack
of that packet is received.
Only the IBC packet sender can set the callback
For the callback to be processed, the transfer packet's memo
should contain the following in its JSON:
{"ibc_callback": "secret1contractAddr"}
The WASM hooks will keep the mapping from the packet's channel and sequence to the contract in storage. When an ack
is received, it will notify the specified contract via an execute
message.
Interface for receiving the Acks and Timeouts
The contract that awaits the callback should implement the following interface for a sudo message:
IBC-Hooks is an IBC middleware that uses incoming ICS-20 token transfers to initiate smart contract calls. Secret Network created a Cosmos Developer SDK that uses IBC hooks to execute Secret gateway contracts, which allows Cosmos developers on other chains to use Secret as a privacy layer for your chain.
The SDK abstracts the complexities involved in interacting with the Secret Network for applications that deal with Cosmos wallets. It introduces a secure method for generating confidential messages and reliably authenticating users at the same time using the chacha20poly1305
algorithm.
The SDK can be used be for developing major gateways that forward incoming messages to Secret Network, as well as built-in support for confidential messages directly in other contracts. To learn by doing, start with the key value store developer tutorial here.
IBC Transfer channel between the consumer chain and Secret Network
See Mintscan for a list of existing transfer channels between Cosmos chains and Secret Network