Typescript SDK
CCL IBC SDK for typescript developers
Typescript Demo
Dependencies
For encryption, we recommend using @solar-republic/neutrino which has useful chacha20poly1305related functionalities and additional primitives for generating ephemereal lightweight wallets. Installation:
npm install --save @solar-republic/neutrinoFor 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:
npm install --save @cosmjs/crypto @cosmjs/amino @cosmjs/encodingIf you are developing in the browser environment or connecting to a public network you might also need
npm install --save @cosmjs/stargate
# or
npm install --save @cosmjs/cosmwasm-stargateGenerating Wallets
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
import { Slip10Curve, Random, Bip39, Slip10, stringToPath, Secp256k1 } from "@cosmjs/crypto"
const seed = await Bip39.mnemonicToSeed(Bip39.encode(Random.getBytes(16)));
const { privateKey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, stringToPath("m/44'/1'/0'/0"));
const pair = await Secp256k1.makeKeypair(privateKey);
// must be compressed to 33 bytes from 65
const publicKey = Secp256k1.compressPubkey(pair.pubkey);@solar-republic/neutrino
@secretjs
Query Client
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:
Signatures
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.
Browser Wallets
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
Getting Signer and Signer Address
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.
Generating the message and StdSignDoc
StdSignDocTo 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:
Encryption
After getting a public key of a gateway contract you can use it to derive a shared key like this:
Encrypting + Signing
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 { ... }
Broadcasting the message
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:
Last updated
Was this helpful?