Secret Network Developer Tutorial: How to build a Keplr Staking App
Author: Austin Woetzel
Secure Secrets recently added a feature to our website to allow users to stake with our validator node via their Keplr wallet. This is a quick, easy way to stake which would normally require some navigation through the Keplr app.
Being a new Secret Network developer myself, there were many things I learned throughout the process of building this app including SecretJS, CosmWasm, Keplr, Figment, AWS, proxies, and more! I wanted to share this with the Secret Network community to help new developers get up and running faster. While this tutorial will focus on what it takes to build a staking app, the concepts could very easily apply to any front-end application that interacts with Secret Contracts and requires signing.
Step 1: Set up your REST API endpoint
Before you get started writing any code, you’re going to want to have the infrastructure in place for your app to communicate with the Secret Network blockchain for sending transactions. If you already have access to your own API, great! If not, I recommend using Figment’s Datahub which offers a generous free tier as well as a paid tier depending on the number of transactions you expect to have. Create an account and you will have access to endpoints for both the Secret Network mainnet (secret-2) and testnet (holodeck-2).
Dealing with CORS issues on Figment’s Datahub:
If you’ve worked with APIs before, you may have come across Cross Origin Resource Sharing (CORS) errors which is a security feature to prevent cross domain access to the API methods. Figment uses CORS protections which prevented direct access to the API from the Secure Secrets website, deployed via Netlify. The solution I came across was setting up a proxy server that acts as a passthrough for your API calls. For my app I did this using AWS with a lambda function, but the Secret Network/Figment Dev communities were extremely helpful with providing other solutions as well. I compiled a list below:
- AWS Lambda Function
- Azure Solution with extra explanation HERE. courtesy of floAr#4492 (discord handle)
- Cloudflare Workers Solution courtesy of ajc#1930 (discord handle)
- Host your own Nginx Server courtesy of ajc#1930
If you would like more information about configuring AWS to work with our AWS lambda function, feel free to reach out!
Step 2: Install Keplr
Chances are if you’ve spent any time in the Secret Network ecosystem, you’re probably very familiar Keplr, but if not, you’re going to want to install the Keplr App in your chrome browser.
Step 3: Get familiar with the Secret Network Testnet (Holodeck-2).
During development, you’ll want to use the Holodeck-2 testnet. You can read more about test net here.
Head over to the faucet to get some testnet tokens added to your Keplr wallet.
The testnet block explorer will be helpful to verify your transactions are going through successfully. You can also use it to identify a validator to stake to during testing. At the time of this writing, there are 4 active testnet validators.
Step 4: Install your dependencies
You’re going to need SecretJS for your project which is a Secret Network SDK for building CosmWasm clients. CosmWasm is a smart contracting platform built for the Cosmos ecosystem, which includes Secret Network.
https://www.npmjs.com/package/secretjs
Step 5: Building the Staking App
Now the fun begins and you can begin coding your app!
If you would like to jump right into our code and use it as a template, feel free! The gist is available here. I used VueJS, but other frameworks should be a similar implementation of SecretJS.
We will now walk though sections of the code with some explanation and resources for learning more…
Detect Keplr Wallet and initialize the SecretJS SigningCosmWasmClient
Keplr provides documentation for detecting their wallet in the browser and using the wallet with secretJS. The SigningCosmWasmClient is used to sign the transaction and then broadcasts the signed transaction to the chain.
if (!window.getOfflineSigner || !window.keplr) {
alert("Keplr Wallet not detected, please install extension" );
} else {
await window.keplr.enable(CHAIN_ID);
this.keplrOfflineSigner = await
window.getOfflineSigner(CHAIN_ID);
const accounts = await this.keplrOfflineSigner.getAccounts();
}
You will also need to get your Keplr wallet address which will be used later in the application.
const accounts = await this.keplrOfflineSigner.getAccounts(); this.walletAddress = accounts[0].address
Initialize the SigningCosmWasmClient, which takes in a few parameters including your API URL, wallet address, signer (Keplr), Enigma Utilities, and custom fees (fees will end up being overwritten later, so the numbers don’t matter here.)
this.cosmJS = new SigningCosmWasmClient(
SECRET_REST_URL,
this.walletAddress,
this.keplrOfflineSigner,
window.getEnigmaUtils(CHAIN_ID),
{
init: {
amount: [{ amount: "300000", denom: "uscrt" }],
gas: "300000",
},
exec: {
amount: [{ amount: "300000", denom: "uscrt" }],
gas: "300000",
},
});
Building the staking function
The following data needs to be passed into the .signAdaptor of the CosmWasmSigningClient where the transaction will be signed by your Keplr wallet,
- sendMsg
- fee
- Chain ID
- Memo
- accountNumber
- sequence
sendMsg
const sendMsg = {
type: "cosmos-sdk/MsgDelegate",
value: {
delegator_address: this.walletAddress,
validator_address: this.validatorAddress,
amount: {
denom: "uscrt",
amount: amount.toString(),
},
},
};
There are many different types of send Messages supported by the Cosmos SDK. The “MsgDelegate” type is described in the Cosmos Documentation here.
fee
const fee = {
amount: [
{
amount: "50000",
denom: "uscrt",
},
],
gas: "270000",
};
The qty for amount doesn’t matter because it will be overwritten by the fees set within the Keplr Popup later. Gas is set to 270000 which is based on what Keplr uses as the default value when staking from within the Keplr Staking Website.
chain ID
Chain ID = “secret-2” for mainnet and “holodeck-2” for testnet
memo
Custom Text String (optional)
accountNumber and sequence
const { accountNumber, sequence } = await this.cosmJS
.getNonce(this.walletAddress)
Account Number and Sequence returned by the .getNonce function of the SigningCosmWasmClient.
Finally, broadcast the signed transaction to the chain
const result = await this.cosmJS.postTx(signedTx)
Congratulations, you’ve successfully created a staking app!
You can look at the full code here which has a few more details I didn’t cover above.
Thanks for Reading!
Special thanks to Swiss Secret Node Dev#5818 (discord handle) for helping me with the SecretJS/Keplr code. It was difficult to find documentation specifically about staking transactions and he helped me clear that roadblock.
If you have any feedback, please don’t hesitate to reach out on Telegram (@AustinWoetzel) or discord (Austin W. | Secure Secrets#3275)
Website: https://www.securesecrets.org/
Twitter: https://twitter.com/securesecrets
Telegram: https://t.me/securesecrets
Secure Secrets Validator Node Address: secretvaloper1rfnmcuwzf3zn7r025j9zr3ncc7mt9ge56l7se7
If you would like to support Secure Secrets you can delegate to our node. If you want to support more content such as this, you can donate $SCRT to this address if you feel so inclined:
secret1ekhx9r35jpwmgngc48uhdead2ea25n4zgl9euu