Loading...
Learn the basics of working with the IBC Developer Toolkit
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Learn how to use Secret Network's IBC Developer Toolkit to design dApps with confidential computing.
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
Secret Network's IBC CCL SDK is available on IBC hooks-enabled chains with an IBC transfer channel enabled for Secret Network.
Secret Network's IBC Developer Toolkit is available on any Cosmos chain that has established an IBC transfer channel with Secret Network!
Learn how to create your own testnet relayer channel here to start using the IBC Developer Toolkit!
Learn how to use Secret Network as the confidential computation layer of the Cosmos with IBC hooks
Secret Network's Confidential Computation SDK uses IBC hooks to seamlessly handle cross-chain encrypted payloads, which means Cosmos developers can now encrypt and decrypt messages with a simple token transfer.
See fullstack demo for Osmosis Mainnet here.
This tutorial explains how to upload your own Key-value store contract on Secret Network, which you can use to encrypt values on Secret Network and transmit them cross-chain from a Cosmos chain of your choice! After this tutorial, you will have the tools you need to encrypt messages on any IBC hooks-enabled Cosmos chain.
In this example, you will send a token from Osmosis mainnet to Secret Network mainnet to encrypt a string
🔥
To get started, clone the repository:
Install the dependencies:
Create an env
file. Simply update env.testnet to omit ".testnet" from the file name and then add your wallet's mnemonics:
Now that you have your environment configured, it's time to upload the encryption contract to Secret Network.
First, compile the contract:
This compiles the contract and creates a wasm
file in the following directory:
The files that make up the IBC SDK, including the script to upload the contract to Secret Network, are in ./src.
Compile the typescript files so you can execute them with node:
Once you run the above command, the typescript files in ./src
will be compiled as javascript files in ./dist
.
Upload and instantiate the encryption contract on Secret Network Mainnet:
In your terminal, a codeID
, codeHash
, and contractAddress
will be returned:
Update contracts.json
with your contractAddress
and codeHash
accordingly:
Now that you have your encryption smart contract uploaded on Secret Network, let's use it to store encrypted messages from Osmosis Mainnet Most of the ECDH cryptography has been abstracted away so there are only a few values you need to change.
The functions in ./src are helper functions that help us configure cross-chain network clients, IBC token transfers, etc. However, there is also an additional function which executes the gateway contract called execute-gateway.js! Execute-gateway.js demonstrates sending a token transfer to store an unencrypted as well as an encrypted message.
Feel free to update the strings to be encrypted.
To encrypt the payload, run execute-gateway.js
:
This will initiate a Token transfer:
As well as an IBC Acknowledgement response:
Congrats! You have now used the Secret Network CCL SDK to encrypt a string
on Osmosis Mainnet!
Now that you have used Secret Network's CCL SDK to successfully encrypt a string
cross-chain, let's examine the gateway smart contract you deployed on Secret Network to understand how everything works underneath the hood.
At a high level, you can think of the SDK like so:
There is a gateway contract deployed to Secret Network, which has the ability to encrypt a string
, as well as query the encrypted string
.
The gateway contract imports helper functions from the SDK, which is where the gateway contract imports encryption and query types, etc.
You can add additional functionality to the gateway contract as you see fit. For example, you could write an execute message that stores encrypted votes or encrypted NFTs, etc!
To use the SDK's encryption helper functions, simply write your gateway contract messages inside of the InnerMethods
enum , which imports GatewayExecuteMsg from the SDK :)
Now let's examine each of the gateway contract's files to understand how it encrypts a user-inputted string
.
state.rs is where we define the keymap
that holds our encrypted strings.
The keymap SECRETS
is designed to store a mapping from account user addresses (as strings) to their secrets (also as strings), using the Bincode2 serialization format.
msg.rs is where we define the functionality of our gateway contract. It has 2 primary functionalities: storing encrypted strings and querying encrypted strings. Note that the types ExecuteMsg
and QueryMsg
are defined in the SDK here.
GatewayExecuteMsg: Defines execution messages that can be sent to the contract, including resetting an encryption key, sending encrypted data, and extending with additional message types.
GatewayQueryMsg: Defines query messages that can be sent to the contract, including querying for an encryption key, querying with authentication data, querying with a permit, and extending with additional query types.
contract.rs contains the smart contract logic which allows the following:
Execution: Processes messages to reset the encryption key or store a secret, ensuring only authorized access.
Querying: Handles queries to retrieve the encryption key and perform permissioned queries.
The encryption logic, handle_encrypted_wrapper
, is imported from the SDK at line 55. This 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.
In this tutorial, you learned how to utilize Secret Network's Confidential Computation SDK to encrypt and decrypt messages across Cosmos chains using IBC hooks. By following the steps outlined, you successfully:
Configured the development environment with the necessary dependencies and environment variables.
Uploaded and instantiated an encryption contract on the Secret Network mainnet.
Encrypted and transmitted a payload from the Osmosis Mainnet to the Secret mainnet using IBC token transfers.
With these tools and knowledge, you are now equipped to handle cross-chain encrypted payloads on any IBC hooks-enabled Cosmos chain, enhancing the security and confidentiality of your blockchain applications.
Secret Network's IBC CCL SDK is available on IBC hooks-enabled chains with an IBC transfer channel enabled for Secret Network.
See additional Mainnet transfer channels on Mintscan .
Learn how to use Secret Network as the confidential computation layer of the Cosmos
For any Cosmos chain, you can use encrypted payloads to execute and query confidential messages on Secret Network smart contracts.
Using our Confidential Computation Layer (CCL) SDK, you can seamlessly handle encrypted payloads, as the master gateway contract on Secret Network automatically decrypts the payload and hands the decrypted payload over to the target contract.
The encryption of the payload is done using the , an algorithm.
The key for this symmetric encryption is created by using the (ECDH) scheme, comprising of two components:
An extra encryption public key provided from the Secret Gateway Contract
A randomly created (ephemeral) encryption private key on the user side (independent of the user wallet's private key)
Combining both of these keys together via the ECDH Scheme yields our encryption key, which we use to encrypt the payload with ChaCha20-Poly1305.
As a first example for this, we have used the CCL SDK to encrypt a string
and subsequently store it in a Secret Network contract.
Learn how to run the Go relayer to create a transfer channel between any Cosmos chain and Secret Network.
The is a relayer implementation written in Golang. It can create clients, connections, and channels, as well as relay packets and update and upgrade clients.
In order to use Secret Network's IBC Developer Toolkit, you need an IBC transfer channel established between Secret Network and your Cosmos chain.
In this section, you will learn:
How to get started with the Go relayer.
Basic Go relayer commands.
How to create a transfer channel between Secret Network testnet and Neutron testnet.
Let's get started!
Clone the :
Build the Go relayer:
If you run into any errors during installation, you can install without make
like so:
To check that the installation was successful, run:
Which returns:
The configuration data is added to the config file, stored at $HOME/.relayer/config/config.yaml
by default.
If this is the first time you run the relayer, first initialize the config with the following command:
And check the config with:
Now you are all set to add the chains and paths you want to relay on, add your keys and start relaying. You will set up two testnet chains: Neutron's pion-1
and Secret Network's pulsar-3
.
rly chains add
will check the liveliness of the available RPC endpoints for that chain in the chain registry. The command may fail if none of these RPC endpoints are available. In this case, you will want to manually add the chain config.
Create new keys for the relayer to use when signing and relaying transactions:
Query your key balances:
Then, dit the relayer's key
values in the config file to match the key-name
s chosen above. The configuration data is added to the config file, stored at $HOME/.relayer/config/config.yaml:
You configured the chain metadata, now you need path metadata.
Update your config file like so to use a configuration path that has been tested in production:
Alternatively, you can also create your own path like so:
If you create your own path, be sure to add your transfer channels to the channel filters in the config.yaml
like so:
Before starting to relay and after making some changes to the config, you can check the status of the chains in the config:
Which returns this output when healthy:
And you can check the status of the paths in the config:
In case one of the checks receives a ✘
instead of ✔
, you will need to check if you completed all the previous steps correctly.
Finally, start the relayer on the desired path. The relayer will periodically update the clients and listen for IBC messages to relay:
The Secret Network CCL SDK can be forked .
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 ⭐
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
).
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.
CCL IBC SDK for typescript developers
See a fullstack Next.js typescript demo (using Osmosis Mainnet). Code available .
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:
Most of the Cosmos wallets provide a method for signing arbitrary messages following the mentioned specification.
Although the API method requires a chainId,
it is set to empty string before signing the message
Cosmology
CosmJS
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:
Note that for our consumer chain, we are using the endpoint
, chainID
, token
, and prefix
for Osmosis Mainnet. But you could update this for any Cosmos chain that has IBC hooks enabled and a transfer channel with Secret Network
The rly chains add
command fetches chain metadata from the and adds it to your config file:
You can fund your Secret Network testnet wallet and your Neutron testnet wallet
There is one easy command to get this path information - from the in the Go relayer repository:
Congrats! You are now relaying between Secret Network testnet and Neutron testnet!
You can review the function in the SDK . It has the following functionality:
uses chacha20poly1305 algorithm
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 which is also used in the SDK.
Here is a definition taken from documentation of :
Cosmology signArbitrary
method as part of the interface for their wallet client and provides implementation / integration for every popular Cosmos wallet out there
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
Osmosis
SECRET / channel-1
OSMOSIS / channel-88
Noble
SECRET / channel-88
NOBLE / channel-17
Axelar
SECRET / channel-20
AXELAR / channel-12
Juno
SECRET / channel-8
JUNO / channel-48
Evmos
SECRET / channel-18
EVMOS / channel-15
Verifiable on-chain random number generator for the entire Cosmos.
This VRF tutorial uses IBC Hooks, as introduced in IBC v3.4.0. If your chain is on a previous IBC version, see the SecretVRF tutorial using proxy contracts here.
Secret VRF is a provably fair and verifiable on-chain random number generator (RNG) that enables smart contracts to access random values without compromising security or usability. Coupled with cross-chain interoperable smart contracts using IBC hooks, Secret Network enables developers and projects across the Cosmos access to state-of-the-art on-chain RNG.
Use Secret VRF to build reliable smart contracts for any application that relies on unpredictable outcomes:
NFT Minting: Utilize randomness for features like unordered minting, trait randomization, and identity numbering, enhancing the authenticity and security of NFT collections.
Web3 Gaming: Apply randomness in gambling, damage calculation, loot boxes, and boss drops to build trust among players by ensuring fairness and preventing any player from having an unfair advantage.
DAO Operations: Employ randomness for wallet initialization, task assigning, unordered voting/liquidations, and order book ordering, facilitating equitable and secure decentralized governance and operations.
Learn more about how SecretVRF works in-depth here.
To use SecretVRF on any IBC-enabled chain with IBC hooks, all that is required is:
An IBC transfer channel between Secret Network and the consumer chain that receives randomness.
Uploading the RNG Consumer Contract to your chain and directing it to your chain's transfer channel
Git clone
the IBC hooks randomness repository:
Update the SECRET_TRANSFER_CHANNEL_ID
and the CHAIN_TRANSFER_CHANNEL_ID
to the channel-id for your IBC-enabled chain:
For this example, we request randomness on Juno Mainnet, but you can request randomness on any IBC-compatible chain that has a transfer channel established with Secret Network.
Once you have updated the transfer channels, compile the contract:
Upload the compiled contract:
Upon successful upload, a code_id
is returned:
Instantiate the contract with the returned code_id
:
Upon succesful instantiation, a contract_address
is returned:
Now that you've instantiated your randomness contract, all that's left is to request randomness! Simply execute request_random:
A transaction hash will be returned:
You can update the job_id
string to any string of your choosing
Navigate to the recently received transactions for your contract:
And then view the magic of cross-chain randomness with IBC hooks 😍:
Congrats! You've just sent a verifiable on-chain random byte
with SecretVRF 🙌.
Secret VRF revolutionizes blockchain applications by providing a secure and verifiable source of randomness, critical for fairness in NFT minting, gaming, and DAO operations. Its seamless integration with IBC hooks enables cross-chain interoperability, allowing developers across the Cosmos ecosystem to build more reliable and elegant smart contracts.
If you have any questions, join our discord and a Secret developer will assist you ASAP.
A fullstack tutorial for cross-chain confidential sealed bid auctions on IBC-connected chains.
Overview
This tutorial explains how to upload a confidential sealed bid auction contract on Secret Network, which you can execute and query for private auctions on any IBC-connected chain. 🚀
In this example, you will learn how to deploy a confidential auction contract on Secret Network which you will execute from Osmosis mainnet.
The SDK abstracts IBC interactions with the Secret Network for applications that use Cosmos wallets. It introduces a secure method for generating confidential messages and reliably authenticating users at the same time using the chacha20poly1305
algorithm.
View the typescript SDK here, which we will learn how to implement shortly
In this tutorial you will learn:
How to run the fullstack cross-chain Next.js application in your browser.
How to use the core smart contract logic for confidential cross-chain auctions using IBC hooks.
How to deploy your very own auction contract on Secret Network.
See a fullstack demo here!
Clone the repo:
cd
into next-frontend
and install the dependencies:
Add environment variables in cosmos-ccl-encrypted-payloads-demo/next-frontend
:
Start the application:
The fullstack Next.js application should now be running in your browser! You can use it to create confidential auctions and bids. Now that you have the application running in your browser, let's dive into the smart contract logic!
To encrypt auction bids using the SDK, we use the enum
called InnerMethods
, which wraps the possible actions in the auction smart contract, namely, CreateAuctionItem
and Bid, with the SDK encryption logic:
InnerMethods
leverage the SDK by using the GatewayExecuteMsg
to structure encrypted execution messages for cross-chain auction management and bidding:
Understanding the Encryption SDK
The magic of Secret Network's encryption SDK happens here, with handle_encrypted_wrapper:
The Extension
variant inExecuteMsg
leverages the functionality of handle_encrypted_wrapper
because the wrapper decrypts and verifies the entire message payload before the Extension
message is processed. Here’s how it works:
handle_encrypted_wrapper
Applies to the Entire Input:
When the execute
function is called, the msg
and info
parameters are initially encrypted.
handle_encrypted_wrapper
is invoked with these parameters:
This function decrypts and verifies the wrapper (encrypted payload) to produce:
A decrypted msg
(of type ExecuteMsg
).
A decrypted info
(with verified sender details).
Decrypted msg
Can Contain ExecuteMsg::Extension
:
After decryption, the msg
can match any variant of ExecuteMsg
, including ExecuteMsg::Extension
.
For example:
Here, Extension
contains an additional layer of messages (InnerMethods
) which define specific functionality.
How handle_encrypted_wrapper
Affects Extension
:
The msg
inside ExecuteMsg::Extension
(i.e., InnerMethods
) is also encrypted in the original input.
handle_encrypted_wrapper
ensures:
The outer msg
is decrypted (revealing Extension
).
The inner data (e.g., InnerMethods
) is now in cleartext and ready for logical execution.
Without this decryption, the contract could not access or process InnerMethods
within the Extension
.
Validation and Security:
By verifying and decrypting the entire payload at the wrapper level, the contract ensures:
The Extension
message is authentic and unaltered.
The sender (info
) is authenticated and valid.
Any operations within InnerMethods
(like bidding) are authorized based on the decrypted info
and secure data.
Now that you understand how the encryption SDK functions, let's look how it's connected to the frontend. The Next.js encryption logic can be found in Gateway.ts:
Both of these functions access a confidential auction contract
already deployed on Secret Network (at the end of this tutorial, you will learn how to deploy your own).
Then, we call the execute_gateway_contract
function, which is where all of the cross-chain SDK logic is implemented using IBC hooks:
You can further examine sendIBCToken
and gatewayChachaHookMemo
in the CCL-SDK ibc.ts
file here.
There are two types of queries using the CCL SDK:
Unauthenticated queries ie Extension
, which are queries that don’t require sensitive or protected data. Example: Retrieving a list of auctions, which is public.
Authenticated queries ie Inner Queries
(WithPermit
, WithAuthData
), which are queries that require auth_data
from the caller for permission validation. Example: MyBid { auction_id: u64 }
retrieves a user-specific bid.
Extended Queries
Inner Queries
Data Access Level
Public or general data
Private or user-specific data
Authorization
No extra authentication required
Requires auth_data
or permit
Processing Function
query::query_extended
query::query_with_auth_data
Use Cases
Public info like auctions
Personal data like a user’s bids
To query encrypted bids using the CCL SDK, use the enum
InnerQueries
, which wraps the possible queries in the auction smart contract, namely, MyBid
, with the CCL SDK encryption logic:
InnerMethods
leverages the SDK by using the GatewayQueryMsg
types to query encrypted cross-chain bids. You have the choice of using two different types of encrypted queries: query_with_auth_data
and query_with_permit.
In this tutorial, you we will learn how to implement query_with_permit
.
The Next.js query decryption logic can be found in Gateway.ts:
Because bids are encrypted, we must decrypt them in order to query a wallet's bids. The frontend function query_contract_auth
securely queries the Secret smart contract using query permits, ensuring that only authorized users can access sensitive data. Query permits are cryptographic credentials that:
Prove the user’s ownership of a wallet.
Allow contracts to verify the user’s identity.
Avoid exposing the private key.
cd
into deploy-scripts
and install the dependencies:
Add your wallet mnemonic to .env
. Then compile the contract:
The compile script requires Docker to be open for successful compilation
Compile the typescript upload script so you can upload the compiled vauction contract:
Once you run the above command, the typescript upload file in ./src
will be compiled as javascript file in ./dist
.
Upload and instantiate the voting contract on Secret Network Mainnet:
In your terminal, a codeID
, codeHash
, and contractAddress
will be returned:
Finally, update config.ts with your contract's code_hash and address:
Congratulations on completing this on using Secret Network's IBC SDK to encrypt auction bids cross-chain using Secret Network smart contracts! 🎉 You've explored the intricacies of encrypted messaging, cross-chain IBC interactions, and secure smart contract execution using the Secret Network CCL SDK. By building and running the fullstack IBC application, you’ve gained hands-on experience in contract deployment, frontend integration, and secure querying with Secret Network query permits. 🚀
A fullstack tutorial for cross-chain confidential voting on IBC-connected chains.
This tutorial explains how to upload a confidential voting contract on Secret Network, which you can execute and query for private voting on any IBC-connected chain. 🚀
In this example, you will learn how to deploy a confidential voting contract on Secret Network which you will execute from Osmosis mainnet.
The SDK abstracts IBC interactions with the Secret Network for applications that use Cosmos wallets. It introduces a secure method for generating confidential messages and reliably authenticating users at the same time using the chacha20poly1305
algorithm.
View the typescript SDK here, which we will learn how to implement shortly
In this tutorial you will learn:
How to run the fullstack cross-chain Next.js application in your browser.
How to use the core smart contract logic for confidential cross-chain votes and proposals using IBC hooks.
How to deploy your very own voting contract on Secret Network.
See a fullstack demo here!
Clone the repo:
cd
into next-frontend
and install the dependencies:
Add environment variables in cosmos-ccl-encrypted-payloads-demo/next-frontend
:
Start the application:
The fullstack Next.js application should now be running in your browser! You can use it to create confidential votes and proposals. Now that you have the application running in your browser, let's dive into the smart contract logic!
To encrypt proposals and votes using the SDK, we use the enum
called InnerMethods
, which wraps the possible actions in the voting smart contract, namely, CreateProposal
and Vote
, with the SDK encryption logic:
InnerMethods
leverage the SDK by using the GatewayExecuteMsg
to structure encrypted execution messages for cross-chain proposal management and voting:
Understanding the Encryption SDK
The magic of Secret Network's encryption SDK happens here, with handle_encrypted_wrapper:
The Extension
variant inExecuteMsg
leverages the functionality of handle_encrypted_wrapper
because the wrapper decrypts and verifies the entire message payload before the Extension
message is processed. Here’s how it works:
handle_encrypted_wrapper
Applies to the Entire Input:
When the execute
function is called, the msg
and info
parameters are initially encrypted.
handle_encrypted_wrapper
is invoked with these parameters:
This function decrypts and verifies the wrapper (encrypted payload) to produce:
A decrypted msg
(of type ExecuteMsg
).
A decrypted info
(with verified sender details).
Decrypted msg
Can Contain ExecuteMsg::Extension
:
After decryption, the msg
can match any variant of ExecuteMsg
, including ExecuteMsg::Extension
.
For example:
Here, Extension
contains an additional layer of messages (InnerMethods
) which define specific functionality.
How handle_encrypted_wrapper
Affects Extension
:
The msg
inside ExecuteMsg::Extension
(i.e., InnerMethods
) is also encrypted in the original input.
handle_encrypted_wrapper
ensures:
The outer msg
is decrypted (revealing Extension
).
The inner data (e.g., InnerMethods
) is now in cleartext and ready for logical execution.
Without this decryption, the contract could not access or process InnerMethods
within the Extension
.
Validation and Security:
By verifying and decrypting the entire payload at the wrapper level, the contract ensures:
The Extension
message is authentic and unaltered.
The sender (info
) is authenticated and valid.
Any operations within InnerMethods
(like creating proposals or voting) are authorized based on the decrypted info
and secure data.
Now that you understand how the encryption SDK functions, let's look how it's connected to the frontend. The Next.js encryption logic can be found in Gateway.ts:
Both of these functions access a confidential voting contract
already deployed on Secret Network (at the end of this tutorial, you will learn how to deploy your own).
Then, we call the execute_gateway_contract
function, which is where all of the cross-chain SDK logic is implemented using IBC hooks:
You can further examine sendIBCToken
and gatewayChachaHookMemo
in the CCL-SDK ibc.ts
file here.
There are two types of queries using the CCL SDK:
Unauthenticated queries ie Extension
, which are queries that don’t require sensitive or protected data. Example: Retrieving a list of proposals or votes, which is public.
Authenticated queries ie Inner Queries
(WithPermit
, WithAuthData
), which are queries that require auth_data
from the caller for permission validation. Example: MyVote { proposal_id }
retrieves a user-specific vote.
Extended Queries
Inner Queries
Data Access Level
Public or general data
Private or user-specific data
Authorization
No extra authentication required
Requires auth_data
or permit
Processing Function
query::query_extended
query::query_with_auth_data
Use Cases
Public info like proposals, votes
Personal data like a user’s vote
To query encrypted votes using the CCL SDK, use the enum
InnerQueries
, which wraps the possible queries in the voting smart contract, namely, MyVote
, with the CCL SDK encryption logic:
InnerMethods
leverages the SDK by using the GatewayQueryMsg
types to query encrypted cross-chain votes. You have the choice of using two different types of encrypted queries: query_with_auth_data
and query_with_permit.
In this tutorial, you we will learn how to implement query_with_permit
.
The Next.js query decryption logic can be found in Gateway.ts:
Because votes are encrypted, we must decrypt them in order to query a wallet's votes. The frontend function query_contract_auth
securely queries the Secret smart contract using query permits, ensuring that only authorized users can access sensitive data. Query permits are cryptographic credentials that:
Prove the user’s ownership of a wallet.
Allow contracts to verify the user’s identity.
Avoid exposing the private key.
cd
into deploy-scripts
and install the dependencies:
Add your wallet mnemonic to .env
. Then compile the contract:
The compile script requires Docker to be open for successful compilation
Compile the typescript upload script so you can upload the compiled voting contract:
Once you run the above command, the typescript upload file in ./src
will be compiled as javascript file in ./dist
.
Upload and instantiate the voting contract on Secret Network Mainnet:
In your terminal, a codeID
, codeHash
, and contractAddress
will be returned:
Finally, update config.ts with your contract's code_hash and address:
Congratulations on completing this on using Secret Network's IBC SDK to encrypt votes cross-chain using Secret smart contracts! 🎉 You've explored the intricacies of encrypted messaging, cross-chain IBC interactions, and secure smart contract execution using the Secret Network CCL SDK. By building and running the fullstack application, you’ve gained hands-on experience in contract deployment, frontend integration, and secure querying with query permits. 🚀
Now let's take a look at the frontend code to see how query_with_permit is implemented.
You now should have all the tools you need to use the IBC CCL toolkit! Lastly, let's learn how to deploy your own auction contract on Secret Network
Now let's take a look at the frontend code to see how query_with_permit is implemented.
You now should have all the tools you need to use the IBC CCL toolkit! Lastly, let's learn how to deploy your own voting contract on Secret Network