Stakes can be taggued using the Solana memo feature to enable Kiln to distinguish your stakes on-chain.
Solana memo instruction
A Solana transaction is composed of multiple instructions, executed one after the other. Here is an example of instructions you can define with the standard Solana @solana/web3.js package.
This transaction will be taggued with the hello, world! memo and will create, initialize and delegate a stake account.
What value should we use for the memo?
Kiln gives to each partner a fix value to include as memo in all the transactions they craft with the following format: kiln_{uuidv4}.
constmemoProgram='MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr';constmemo='hello, world!';constinstructions= [// 1 - add memo to transactionnewTransactionInstruction({ keys: [ { pubkey: staker, isSigner:true, isWritable:true, }, ], programId:newPublicKey(memoProgram), data:Buffer.from(memo), }),// 2 - create stake accountSystemProgram.createAccount({/** The account that will transfer lamports to the created account */ fromPubkey: publicKey,/** Public key of the created account. Must be pre-calculated with PublicKey.createWithSeed() */ newAccountPubkey:stakeKey.publicKey,/** Amount of lamports to transfer to the created account */ lamports:solToLamports(parsedStakeAmount),/** Amount of space in bytes to allocate to the created account */ space:200,/** Public key of the program to assign as the owner of the created account */ programId, }),// 3 - init stake accountStakeProgram.initialize({ stakePubkey:stakeKey.publicKey, authorized: {/** stake authority */ staker: publicKey,/** withdraw authority */ withdrawer: publicKey, }, lockup: {/** Unix timestamp of lockup expiration */ unixTimestamp:0,/** Epoch of lockup expiration */ epoch:0,/** Lockup custodian authority */ custodian:newPublicKey('11111111111111111111111111111111'), }, }),// 4 - delegate stake accountStakeProgram.delegate({ stakePubkey:stakeKey.publicKey, authorizedPubkey: publicKey, votePubkey:newPublicKey(SOL_VOTE_ACCOUNT_ADDRESS), }),];tx.add(...instructions);
DYDX - How to bridge your rewards
How to bridge your rewards using Kiln Connect, regardless of your custody solution.
Rewards earned on DYDX are DYDX-USDC. In this tutorial we will present how to bridge these rewards to Ethereum or to Osmosis using the Kiln SDK. These flows can be done directly from Kiln Dashboard if you are using Fireblocks.
Bridge to Ethereum
The goal of this bridge is to bring your dYdX rewards in USDC on your ETH address so that you can use them for other purposes like depositing them on a centralized exchange to get some dYdX back.
To convert your DYDX-USDC to USDC on Ethereum, we will use the Noble bridge developed by Circle, which is the recommended on-chain approach.
There is 3 steps to this flow:
1) Transfer the USDC from DYDX to the Noble chain
2) Burn the USDC on Noble
3) Mint the USDC on Ethereum
Here is a TypeScript code snippet that you can use:
import { Kiln } from"@kilnfi/sdk";import axios from'axios';constf=async () => {constk=newKiln({ baseUrl:'https://api.kiln.fi', apiToken:'YOUR_KILN_API_TOKEN', });/** * Send dydx-usdc rewards to noble */// Craft IBC transfer transactionconsttransferTx=awaitk.client.POST('/v1/dydx/transaction/noble-ibc-transfer', { body: { pubkey:'02d92b48d3e9ef34f2016eac7857a02768c88e30aea7a2366bc5ba032a22eceb8b', amount_uusdc:'1000000', } } );// Sign the transaction with Fireblocks or your custody solutionconstsignResponse=awaitk.fireblocks.signDydxTx(vault,tx.data.data);// Broadcast the transaction on DYDXconstbroadcastedTx=awaitk.client.POST("/v1/dydx/transaction/broadcast", { body: { tx_serialized:signResponse.signed_tx.data.tx_serialized, } });/** * Burn the usdc on noble for eth address recipient */// Craft burn transactionconsttxburn=awaitk.client.POST('/v1/noble/transaction/burn-usdc', { body: { pubkey:'02d92b48d3e9ef34f2016eac7857a02768c88e30aea7a2366bc5ba032a22eceb8b', amount_usdc:'1000000', recipient:'0xBC86717BaD3F8CcF86d2882a6bC351C94580A994', } } );// Sign the transaction with Fireblocks or your custody solutionconstsignResponseBurn=awaitk.fireblocks.signDydxTx(vault,txburn.data.data);// Broadcast the transaction on NobleconstbroadcastedTxBurn=awaitk.client.POST("/v1/noble/transaction/broadcast", { body: { tx_serialized:signResponseBurn.signed_tx.data.tx_serialized, } });/** * Mint the USDC on Ethereum to the recipient */// Fetch the attestation from circle's API (https://developers.circle.com/stablecoins/reference/getattestation)const { data: attestation } =awaitaxios.get(`https://iris-api-sandbox.circle.com/v1/messages/4/${burnTxHash}`);// Craft the Ethereum mint transaction// todo: Kiln to add this part to the sdkconstmintTx;// Sign and broadcast the transaction with Fireblocks on EthereumconsttxHash=awaitk.fireblocks.signAndBroadcastEthTx(vault, mintTx);};f();
Bridge to Osmosis
The goal of this bridge is to bring your dYdX rewards in USDC on another cosmos address here on Osmosis so that you can use them for other purposes like depositing them on a centralized exchange or a Swap on Osmosis to get some dYdX back.
This flow follows two steps:
1) Transfer the DYDX-USDC to the Noble chain
2) Transfer the USDC on Noble to Osmosis
Here is a TypeScript code snippet that you can use:
import { Kiln } from"@kilnfi/sdk";import axios from'axios';constf=async () => {constk=newKiln({ apiToken:'YOUR_KILN_API_TOKEN', });/** * Send dydx-usdc rewards to noble */// Craft IBC transfer transactionconsttransferTx=awaitk.client.POST('/v1/dydx/transaction/noble-ibc-transfer', { body: { pubkey:'02d92b48d3e9ef34f2016eac7857a02768c88e30aea7a2366bc5ba032a22eceb8b', amount_uusdc:'1000000', } } );// Sign the transaction with Fireblocks or your custody solutionconstsignResponse=awaitk.fireblocks.signDydxTx(vault,tx.data.data);// Broadcast the transaction on DYDXconstbroadcastedTx=awaitk.client.POST("/v1/dydx/transaction/broadcast", { body: { tx_serialized:signResponse.signed_tx.data.tx_serialized, } });/** * Send usdc from noble to osmosis */// Craft IBC transfer transactionconsttx=awaitk.client.POST('/v1/noble/transaction/osmo-ibc-transfer', { body: { pubkey:'02d92b48d3e9ef34f2016eac7857a02768c88e30aea7a2366bc5ba032a22eceb8b', recipient:'osmo1qz0jvz6v3v7z2zg3z2zg3z2zg3z2zg3z2zg3z2', amount_uusdc:'1000000', } } );// Sign the transaction with Fireblocks or your custody solutionconstsignResponse=awaitk.fireblocks.signDydxTx(vault,tx.data.data);// Broadcast the transaction on NobleconstbroadcastedTx=awaitk.client.POST("/v1/noble/transaction/broadcast", { body: { tx_serialized:signResponse.signed_tx.data.tx_serialized, } });};f();