diff --git a/.gitbook/README.md b/.gitbook/README.md index 0335017be..97cf030de 100644 --- a/.gitbook/README.md +++ b/.gitbook/README.md @@ -1,8 +1,15 @@ # Getting Started +**Stable Package Version** + +![Stable Package (all) versions](https://img.shields.io/npm/v/%40injectivelabs/sdk-ts/latest?label=%40injectivelabs%2Fsdk-ts) +![Supported Node Version](http://img.shields.io/badge/node-16.x-brightgreen.svg) + **Latest Package Versions:** -![](https://img.shields.io/npm/v/%40injectivelabs/sdk-ts/next?label=%40injectivelabs%2Fsdk-ts)![](https://img.shields.io/npm/v/%40injectivelabs/wallet-ts/next?label=%40injectivelabs%2Fwallet-ts)![](https://img.shields.io/npm/v/%40injectivelabs/sdk-ui-ts/next?label=%40injectivelabs%2Fsdk-ui-ts)![](https://img.shields.io/npm/v/%40injectivelabs/utils/next?label=%40injectivelabs%2Futils)![](https://img.shields.io/npm/v/%40injectivelabs/token-metadata/next?label=%40injectivelabs%2Ftoken-metadata)![](https://img.shields.io/npm/v/%40injectivelabs/networks/next?label=%40injectivelabs%2Fnetworks) +![](https://img.shields.io/npm/v/%40injectivelabs/sdk-ts/next?label=%40injectivelabs%2Fsdk-ts)![](https://img.shields.io/npm/v/%40injectivelabs/wallet-ts/next?label=%40injectivelabs%2Fwallet-ts)![](https://img.shields.io/npm/v/%40injectivelabs/sdk-ui-ts/next?label=%40injectivelabs%2Fsdk-ui-ts) + +![](https://img.shields.io/npm/v/%40injectivelabs/utils/next?label=%40injectivelabs%2Futils)![](https://img.shields.io/npm/v/%40injectivelabs/token-metadata/next?label=%40injectivelabs%2Ftoken-metadata)![](https://img.shields.io/npm/v/%40injectivelabs/networks/next?label=%40injectivelabs%2Fnetworks) _**Note:** The latest versions are published using the `next` tag. For stable versions use the `latest` tag or check npm registry for the latest stable version._ @@ -10,15 +17,15 @@ The purpose of this Wiki is to help developers build decentralized applications _Note: Reading the Technical Concepts section after reading the overview below is highly recommended. There are some concepts that can have a bit steeper learning curve than others, so we recommend going through them to understand a bit more about Injective._ -* [Wallets](wallet/) - In this section, we are going to explain (in technical terms) how Accounts are derived on Injective, how you can connect your wallet straight from the dApp itself, and finally have a look at the **WalletStrategy** - a package built by the InjectiveLabs team which offers out of the box solution for providing multiple wallet solutions to the user to connect and interact with your dApp. -* [Querying](querying/) - In this section we are going to explore different ways to obtain data from different data sources needed to build your dApps. First, we are going to see how to query the chain directly and then we are going to explore the Indexer API - an indexer solution for easier data access/streaming including historical data. -* [Transaction](transactions/) - In this section, we are going to explore different ways to make transactions on Injective. First, we are going to explain (in technical terms) how Transactions work on Injective and some technical concepts around them and then we are going to have a look at how to prepare, sign, and broadcast transactions on Injective in several ways. There are a couple of ways to do this. +- [Wallets](wallet/) - In this section, we are going to explain (in technical terms) how Accounts are derived on Injective, how you can connect your wallet straight from the dApp itself, and finally have a look at the **WalletStrategy** - a package built by the InjectiveLabs team which offers out of the box solution for providing multiple wallet solutions to the user to connect and interact with your dApp. +- [Querying](querying/) - In this section we are going to explore different ways to obtain data from different data sources needed to build your dApps. First, we are going to see how to query the chain directly and then we are going to explore the Indexer API - an indexer solution for easier data access/streaming including historical data. +- [Transaction](transactions/) - In this section, we are going to explore different ways to make transactions on Injective. First, we are going to explain (in technical terms) how Transactions work on Injective and some technical concepts around them and then we are going to have a look at how to prepare, sign, and broadcast transactions on Injective in several ways. There are a couple of ways to do this. 1. Using the Cosmos native approach in creating a transaction, sign it using a **Cosmos native wallet** and broadcast it to Injective, 2. Using the Ethereum native approach in creating a transaction using EIP712 typed data, sign it using an **Ethereum native wallet** and broadcast it to Injective, 3. Using the Ethereum native approach in creating a transaction using EIP712 typed data, sign it using a **Ledger device** and broadcast it to Injective, 4. Using the Cosmos native approach in creating a transaction, sign it using a **raw PrivateKey** and broadcast it to Injective, 5. Using the Web3Gateway microservice - an API that provides fee delegation services. -* [Core Modules](core-modules/) - In this section we are going to have a quick summary of the core modules on Injective and show examples of how to create some Messages (+ pack them into a transaction, sign them using a private key, and broadcast them on Injective) within these core modules. -* [Bridge](bridge/) - In this section, we are going to have a look at Injective's interoperability and explain how developers can utilize the Peggy bridge and the IBC bridge to bridge assets over to Injective. -* [Networks](readme/networks.md) - In this section, we will look at different (pre-defined) available Networks for developers to utilize while building dApps on top of Injective, allowing them to start building without the need to make their own infrastructure. -* [Calculations](calculations/) - In this section, we will look at different calculations formula converting values between UI human-readable and chain format. +- [Core Modules](core-modules/) - In this section we are going to have a quick summary of the core modules on Injective and show examples of how to create some Messages (+ pack them into a transaction, sign them using a private key, and broadcast them on Injective) within these core modules. +- [Bridge](bridge/) - In this section, we are going to have a look at Injective's interoperability and explain how developers can utilize the Peggy bridge and the IBC bridge to bridge assets over to Injective. +- [Networks](readme/networks.md) - In this section, we will look at different (pre-defined) available Networks for developers to utilize while building dApps on top of Injective, allowing them to start building without the need to make their own infrastructure. +- [Calculations](calculations/) - In this section, we will look at different calculations formula converting values between UI human-readable and chain format. diff --git a/.gitbook/SUMMARY.md b/.gitbook/SUMMARY.md index f9fb2de00..039e1b903 100644 --- a/.gitbook/SUMMARY.md +++ b/.gitbook/SUMMARY.md @@ -8,6 +8,7 @@ * [Denom Client](readme/token-metadata/denom-client.md) * [Networks](readme/networks.md) * [CosmJs Support](readme/getting-started-cosmjs.md) + * [Running examples](readme/running-examples.md) * [Wallet](wallet/README.md) * [Accounts](wallet/wallet-accounts.md) * [Wallet Connections](wallet/wallet-connections.md) @@ -50,9 +51,11 @@ * [Tendermint](querying/querying-chain/querying-chain-tendermint.md) * [Wasm](querying/querying-chain/querying-chain-wasm.md) * [WasmX](querying/querying-chain/querying-chain-wasmx.md) + * [Token Factory](querying/querying-chain/token-factory.md) * [Ethereum (GraphQL)](querying/querying-ethereum.md) * [Transactions](transactions/README.md) - * [Cosmos](transactions/transactions-cosmos.md) + * [Cosmos](transactions/transactions-cosmos/README.md) + * [Ledger through Keplr Wallet](transactions/transactions-cosmos/ledger-through-keplr-wallet.md) * [Ethereum](transactions/ethereum.md) * [Ethereum Ledger](transactions/ethereum-ledger.md) * [MsgBroadcaster](transactions/msgbroadcaster.md) @@ -86,3 +89,5 @@ * [DEX](building-dapps/dex.md) * [Bridge](building-dapps/bridge.md) * [Calculations](calculations/README.md) + * [Min Price Tick Size](calculations/min-price-tick-size.md) + * [Min Quantity Tick Size](calculations/min-quantity-tick-size.md) diff --git a/.gitbook/bridge/ethereum.md b/.gitbook/bridge/ethereum.md index 19d803cc1..f8147fa27 100644 --- a/.gitbook/bridge/ethereum.md +++ b/.gitbook/bridge/ethereum.md @@ -51,7 +51,7 @@ const contract = new PeggyContract({ }) ``` -* The snippet below instantiates a PeggyContract instance which can easily `estimateGas` and `sendTransaction` using the `web3` we provide to the contract’s constructor. It’s implementation can be found [here](https://github.com/InjectiveLabs/injective-ts/blob/master/packages/contracts/src/contracts/Peggy.ts). Obviously, this is just an example and you can use the web3 package directly + the ABI of the contract to instantiate the contract, and then handle the logic of signing and broadcasting the transaction using some web3 provider. +* The snippet below instantiates a PeggyContract instance which can easily `estimateGas` and `sendTransaction` using the `web3` we provide to the contract’s constructor. Its implementation can be found [here](https://github.com/InjectiveLabs/injective-ts/blob/master/packages/contracts/src/contracts/Peggy.ts). Obviously, this is just an example and you can use the web3 package directly + the ABI of the contract to instantiate the contract, and then handle the logic of signing and broadcasting the transaction using some web3 provider. ### From Injective to Ethereum @@ -61,7 +61,7 @@ If you are not familiar with how Transactions (and Messages) work on Cosmos you When `MsgSendToEth` is called on the chain, some of the validators will pick up the transaction, batch multiple `MsgSendToEth` requests into one and: burn the assets being withdrawn on Injective, unlock these funds on the Peggy Smart Contract on Ethereum and send them to the respective address. -There is a bridgeFee included in these transactions to incentivise Validators to pick up and process your withdrawal requests faster. The bridgeFee is in the asset the user wants to withdraw to Ethereum (if you withdraw INJ you have to pay the bridgeFee in INJ as well). +There is a bridgeFee included in these transactions to incentivize Validators to pick up and process your withdrawal requests faster. The bridgeFee is in the asset the user wants to withdraw to Ethereum (if you withdraw INJ you have to pay the bridgeFee in INJ as well). Here is an example implementation that prepares the transaction, uses a privateKey to sign it and finally, broadcasts it to Injective: diff --git a/.gitbook/building-dapps/configuring-nuxt.md b/.gitbook/building-dapps/configuring-nuxt.md index 2cf63a81a..4bd927422 100644 --- a/.gitbook/building-dapps/configuring-nuxt.md +++ b/.gitbook/building-dapps/configuring-nuxt.md @@ -30,7 +30,8 @@ $ yarn add @bangjelkoski/node-stdlib-browser $ yarn add -D @bangjelkoski/vite-plugin-node-polyfills ``` -Make sure you are using the `vue-tsc@^1.2.0`, `nuxt@^3.3.3`, `typescript@^4.9.5` versions. +Make sure you are using the `vue-tsc@1.8.8 +`, `nuxt@^3.8.1`, `typescript@^5.0.4` versions. **Buffer** @@ -55,7 +56,7 @@ export default defineNuxtPlugin(() => { If you are going to use `pinia` as state management, add it to your packages: ```bash -$ yarn add pinia @pinia/nuxt +$ yarn add @pinia/nuxt@^0.4.9 ``` ### 5. Using `vueuse` @@ -88,11 +89,12 @@ Then, we need to configure the `tsconfig.json` if you are using TypeScript (reco ### 6. nuxt.config.ts / packages.json -Before we boot our application, we need to set everything up in the `nuxt.config.ts`, the main configuration point for every Nuxt 3 application. Let's see a reference `nuxt.config.ts` and explain every line using comments so its easier for developers to understand. +Before we boot our application, we need to set everything up in the `nuxt.config.ts`, the main configuration point for every Nuxt 3 application. Let's see a reference `nuxt.config.ts` and explain every line using comments so it's easier for developers to understand. ```ts // filename - nuxt.config.ts import { nodePolyfills } from "@bangjelkoski/vite-plugin-node-polyfills"; +import tsconfigPaths from 'vite-tsconfig-paths' export default defineNuxtConfig({ ssr: false, // whether to pre-render your application @@ -120,10 +122,10 @@ export default defineNuxtConfig({ // We generate only sitemaps for the client side as we don't need a server // Note: there is a problem with sitemaps for Vite + Nuxt3 - // as usually is that it takes to much time/memory to generate + // as usual is that it takes too much time/memory to generate // sitemaps and the build process can fail // on Github Actions/Netlify/Vercel/etc so we have to use another - // strategy like generating them locally and them pushing them to services like + // strategy like generating them locally and pushing them to services like // busgnag sourcemap: { server: false, @@ -137,7 +139,8 @@ export default defineNuxtConfig({ "process.env.DEBUG": JSON.stringify(process.env.DEBUG), }, - plugins: [ // setting up node + crypto polyfils + plugins: [ // setting up node + crypto polyfils + vite TS path resolution + tsconfigPaths(), nodePolyfills({ protocolImports: false }) ], diff --git a/.gitbook/building-dapps/configuring-react.md b/.gitbook/building-dapps/configuring-react.md index 405232ead..360cd2719 100644 --- a/.gitbook/building-dapps/configuring-react.md +++ b/.gitbook/building-dapps/configuring-react.md @@ -35,7 +35,7 @@ $ yarn add @bangjelkoski/vite-plugin-node-polyfills ### 4. Using a state management -React has a lot of different state managers, pick the one you are going to use and install it. You can use the build in `Context API` for state management without the need to install a third-party solution. The preffered third-party state managers are `Redux` and `Zustand`. +React has a lot of different state managers, pick the one you are going to use and install it. You can use the build in `Context API` for state management without the need to install a third-party solution. The preferred third-party state managers are `Redux` and `Zustand`. ```bash $ yarn add zustand diff --git a/.gitbook/building-dapps/smart-contract.md b/.gitbook/building-dapps/smart-contract.md index 80bc3a541..570ebf8ae 100644 --- a/.gitbook/building-dapps/smart-contract.md +++ b/.gitbook/building-dapps/smart-contract.md @@ -1,6 +1,6 @@ # Smart Contract -Within these short series we are going to showcase how easy it is to build a dApp on top of Injective. There is an open-sourced [dApp](https://github.com/InjectiveLabs/injective-simple-sc-counter-ui) which everyone can reference and use to build on top of Injective.There are examples for Next, Nuxt and Vanilla Js. For those who want to start from scratch, this is the right place to start. +Within these short series we are going to showcase how easy it is to build a dApp on top of Injective. There is an open-sourced [dApp](https://github.com/InjectiveLabs/injective-simple-sc-counter-ui) which everyone can reference and use to build on top of Injective. There are examples for Next, Nuxt and Vanilla Js. For those who want to start from scratch, this is the right place to start. In this example we will implement the connection and interact with an example Smart Contract deployed on the Injective Chain using the injective-ts module. @@ -10,7 +10,7 @@ The series will include: - Connecting to the Chain and the Indexer API, - Connect to a user wallet and get their address, - Querying the smart contract ( in this case fetching the current count of the smart contract ), -- Modifying the state of the contract ( in this case incrementing the count by 1, or setting it to a speciffic value), +- Modifying the state of the contract ( in this case incrementing the count by 1, or setting it to a specific value), ### Setup @@ -167,7 +167,7 @@ const msg = MsgExecuteContractCompat.fromJSON({ contractAddress: COUNTER_CONTRACT_ADDRESS, sender: injectiveAddress, msg: { - increment: {}, // we pass an empty object if the method doesnt have parameters + increment: {}, // we pass an empty object if the method doesn't have parameters }, }) @@ -181,7 +181,7 @@ const response = await msgBroadcastClient.broadcast({ console.log(response) ``` -Now, lets see an example of how to se the counter to a specific value. Note that in this Smart Contract the count can be set to specific value only by the creator of the Smart Contract. +Now, lets see an example of how to set the counter to a specific value. Note that in this Smart Contract the count can be set to specific value only by the creator of the Smart Contract. ```js // Preparing the message @@ -191,7 +191,7 @@ const msg = MsgExecuteContractCompat.fromJSON({ sender: injectiveAddress, msg: { reset: { - count: parseInt(number, 10), // we are parseing the number variable here because usualy it comes from an input which always gives a string, and we need to pass a number instead. + count: parseInt(number, 10), // we are parsing the number variable here because usually it comes from an input which always gives a string, and we need to pass a number instead. }, }, }) diff --git a/.gitbook/calculations/README.md b/.gitbook/calculations/README.md index bebe608d5..b9367329b 100644 --- a/.gitbook/calculations/README.md +++ b/.gitbook/calculations/README.md @@ -1,10 +1,10 @@ # Calculations -Here are some formula formatting values between the chain and UI human-readable. +In this page we are going to look through some calculations and formatting to understand better about how numbers are represented on the chain vs how we are showing them on the UI. -### Bridges Supported +### Tick Sizes -| Topic | Description | -| ------------------------------------------------------- | --------------------------------------- | -| [Market min price tick size](minPriceTickSize.md) | Minimum market order price tick size | -| [Market min quantity tick size](minQuantityTickSzie.md) | Minimum market order quantity tick size | +| Topic | Description | +| ---------------------------------------------------------- | --------------------------------------- | +| [Market min price tick size](min-price-tick-size.md) | Minimum market order price tick size | +| [Market min quantity tick size](min-quantity-tick-size.md) | Minimum market order quantity tick size | diff --git a/.gitbook/calculations/minPriceTickSize.md b/.gitbook/calculations/min-price-tick-size.md similarity index 100% rename from .gitbook/calculations/minPriceTickSize.md rename to .gitbook/calculations/min-price-tick-size.md diff --git a/.gitbook/calculations/minQuantityTickSize.md b/.gitbook/calculations/min-quantity-tick-size.md similarity index 100% rename from .gitbook/calculations/minQuantityTickSize.md rename to .gitbook/calculations/min-quantity-tick-size.md diff --git a/.gitbook/contracts/injective-name-service.md b/.gitbook/contracts/injective-name-service.md index 7d042afd4..83550b407 100644 --- a/.gitbook/contracts/injective-name-service.md +++ b/.gitbook/contracts/injective-name-service.md @@ -100,7 +100,7 @@ console.log(injectiveAddress) ### Reverse Resolution -* Get primary name for injective address. +* Get the primary name for injective address. ```ts import { getNetworkEndpoints, Network } from '@injectivelabs/networks' diff --git a/.gitbook/core-modules/auction.md b/.gitbook/core-modules/auction.md index 8a6b14445..965e3c02a 100644 --- a/.gitbook/core-modules/auction.md +++ b/.gitbook/core-modules/auction.md @@ -1,6 +1,6 @@ # Auction -The `auction` module is heart of the `buy-back-and-burn` on chain mechanism, where 60% of the weekly trading fees are colleted and auctioned off to the highest INJ bidder where the submitted INJ of the highest bidder are burned in the process. +The `auction` module is heart of the `buy-back-and-burn` on chain mechanism, where 60% of the weekly trading fees are collected and auctioned off to the highest INJ bidder where the submitted INJ of the highest bidder are burned in the process. ### MsgBid @@ -60,18 +60,21 @@ console.log(txHash); If you would like to grow the burn auction's pool size, you can directly send funds to the Auction subaccount. Notes: - - You will need to send funds to the pool's subaccount `0x1111111111111111111111111111111111111111111111111111111111111111`. - - Be aware that any funds you send will be reflected in the next auction, not the current one. - - You cannot transfer from your default subaccountId since that balance is now associated with your Injective address in the bank module. Therefore, in order for `MsgExternalTransfer` to work, you will need to transfer from a non-default subaccountId. - How to find the subaccountId that you will be transferring from: - - you can query your existing subaccountIds via the [account portfolio api](../querying/querying-api/querying-indexer-portfolio.md). +* You will need to send funds to the pool's subaccount `0x1111111111111111111111111111111111111111111111111111111111111111`. +* Be aware that any funds you send will be reflected in the next auction, not the current one. +* You cannot transfer from your default subaccountId since that balance is now associated with your Injective address in the bank module. Therefore, in order for `MsgExternalTransfer` to work, you will need to transfer from a non-default subaccountId. + +How to find the subaccountId that you will be transferring from: + +* you can query your existing subaccountIds via the [account portfolio api](../querying/querying-api/querying-indexer-portfolio.md). How to use funds that are currently associated with your Injective Address in bank module: - - If you have existing non-default subaccounts, you'll want to do a [MsgDeposit](./exchange.md#MsgDeposit) to one of your existing non-default subaccountIds and use that subaccountId as the `srcSubaccountId` below. - - If you don't have existing non-default subaccounts, you can do a [MsgDeposit](./exchange.md#MsgDeposit) to a new default subaccountId, which would be done via importing `getSubaccountId` from `sdk-ts` and setting the `subaccountId` field in [MsgDeposit](./exchange.md#MsgDeposit) to `getSubaccountId(injectiveAddress, 1)`. -For more info, check out the [burn auction pool docs](https://docs.injective.network/develop/tech-concepts/auction_pool/). +* If you have existing non-default subaccounts, you'll want to do a [MsgDeposit](broken-reference) to one of your existing non-default subaccountIds and use that subaccountId as the `srcSubaccountId` below. +* If you don't have existing non-default subaccounts, you can do a [MsgDeposit](broken-reference) to a new default subaccountId, which would be done via importing `getSubaccountId` from `sdk-ts` and setting the `subaccountId` field in [MsgDeposit](broken-reference) to `getSubaccountId(injectiveAddress, 1)`. + +For more info, check out the [burn auction pool docs](https://docs.injective.network/develop/tech-concepts/auction\_pool/). ```ts import { diff --git a/.gitbook/core-modules/distribution.md b/.gitbook/core-modules/distribution.md index b9f60c029..163cc7aff 100644 --- a/.gitbook/core-modules/distribution.md +++ b/.gitbook/core-modules/distribution.md @@ -39,7 +39,7 @@ console.log(txHash); ### MsgWithdrawValidatorCommission -This message is used to by the validator to withdraw the commission earned. +This message is used by the validator to withdraw the commission earned. ```ts import { diff --git a/.gitbook/core-modules/peggy.md b/.gitbook/core-modules/peggy.md index 6004d60a4..ade9c4a49 100644 --- a/.gitbook/core-modules/peggy.md +++ b/.gitbook/core-modules/peggy.md @@ -1,6 +1,6 @@ # Peggy -The `peggy` module is heart of the injective <> ethereum bridge, where deposited funds will be locked on the ethereum [peggy contract](https://etherscan.io/address/0xF955C57f9EA9Dc8781965FEaE0b6A2acE2BAD6f3#code) and minted on the Injective chain. Similarly withdrawal funds will be burned on the injective chain and unlocked on the ethereum peggy contract. +The `peggy` module is the heart of the injective <> ethereum bridge, where deposited funds will be locked on the ethereum [peggy contract](https://etherscan.io/address/0xF955C57f9EA9Dc8781965FEaE0b6A2acE2BAD6f3#code) and minted on the Injective chain. Similarly withdrawal funds will be burned on the injective chain and unlocked on the ethereum peggy contract. ### MsgSendToEth diff --git a/.gitbook/core-modules/staking.md b/.gitbook/core-modules/staking.md index b9137ec3d..0e8eae2dd 100644 --- a/.gitbook/core-modules/staking.md +++ b/.gitbook/core-modules/staking.md @@ -78,34 +78,36 @@ const txHash = await new MsgBroadcasterWithPk({ console.log(txHash); ``` -### MsgDelegate +### MsgCancelUnbondingDelegation -This Message is used to Delegate INJ to a validator. +This message is used to cancel unbonding from a validator, reset the bonding period, and delegate back to the previous validator. ```ts -import { MsgUndelegate, MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts"; +import { MsgCancelUnbondingDelegation, MsgBroadcasterWithPk } from "@injectivelabs/sdk-ts"; import { BigNumberInBase } from "@injectivelabs/utils"; import { Network } from "@injectivelabs/networks"; -const injectiveAddress = "inj1..."; +const delegatorAddress = "inj1..."; const privateKey = "0x..."; const amount = new BigNumberInBase(5); const validatorAddress = "inj1..."; +const creationHeight = "123456"; // the height at which the unbonding was initiated -const msg = MsgUndelegate.fromJSON({ - injectiveAddress, +const msg = MsgCancelUnbondingDelegation.fromJSON({ + delegatorAddress, validatorAddress, amount: { denom: INJ_DENOM, amount: amount.toWei().toFixed(), }, + creationHeight, }); const txHash = await new MsgBroadcasterWithPk({ - privateKey, - network: Network.Testnet +privateKey, +network: Network.Testnet }).broadcast({ - msgs: msg +msgs: msg }); console.log(txHash); diff --git a/.gitbook/core-modules/token-factory.md b/.gitbook/core-modules/token-factory.md index 67858b309..db25b4c88 100644 --- a/.gitbook/core-modules/token-factory.md +++ b/.gitbook/core-modules/token-factory.md @@ -6,6 +6,8 @@ This `tokenfactory` module allows any account to create a new token with the nam _Note: If you want your denom to be visible on products like Helix, Hub, Explorer, etc, it's important to add token metadata information using the `MsgSetDenomMetadata` message as explained below._ +_Note #2: It's recommended to change your admin to the zero address for safety and preventing supply manipulation._ + #### Messages Let's explore (and provide examples) the Messages that the TokenFactory module exports and we can use to interact with the Injective chain. @@ -14,6 +16,8 @@ Let's explore (and provide examples) the Messages that the TokenFactory module e Creates a denom of `factory/{creator address}/{subdenom}` given the denom creator address and the subdenom. Subdenoms can contain \[a-zA-Z0-9./]. Keep in mind that there is a `creation fee` which you need to cover when creating a new token. +Keep in mind that that the `admin` of the token can change the supply (mint or burn new tokens). Its recommended that the `admin` is unset using the `MsgChangeAdmin`, as explained below. + ```ts import { MsgCreateDenom, @@ -170,6 +174,36 @@ const txHash = await new MsgBroadcasterWithPk({ console.log(txHash); ``` +#### MsgChangeAdmin + +The admin of the denom can mint new supply or burn existing one. It's recommended to change the admin to the zero address as to not allow changing the token's supply. + +```ts +import { MsgChangeAdmin } from '@injectivelabs/sdk-ts' +import { BigNumberInBase } from '@injectivelabs/utils' +import { Network } from '@injectivelabs/networks' + +const injectiveAddress = 'inj1...' +const privateKey = '0x...' +const subdenom = 'inj-test' +const denom = `factory/${injectiveAddress}/${subdenom}` + +const msg = MsgChangeAdmin.fromJSON({ + denom, + sender: injectiveAddress, + newAdmin: 'inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49' /** SET TO ZERO ADDRESS */, +}) + +const txHash = await new MsgBroadcasterWithPk({ + privateKey, + network: Network.Testnet, +}).broadcast({ + msgs: msg, +}) + +console.log(txHash) +``` + #### Full Example Here is a full example on how to create a new token, mint new tokens and set token metadata on Injective. @@ -198,6 +232,11 @@ const msgMint = MsgMint.fromJSON({ amount: amount } }); +const msgChangeAdmin = MsgChangeAdmin.fromJSON({ + denom: `factory/${injectiveAddress}/${subdenom}`, + sender: injectiveAddress, + newAdmin: 'inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49' /** SET TO ZERO ADDRESS */ +}); const msgSetDenomMetadata = MsgSetDenomMetadata.fromJSON({ sender: injectiveAddress, metadata: { @@ -226,7 +265,7 @@ const txHash = await new MsgBroadcasterWithPk({ privateKey, network: Network.Testnet }).broadcast({ - msgs: [msgCreateDenom, msgMint, msgSetDenomMetadata] + msgs: [msgCreateDenom, msgMint, msgSetDenomMetadata, msgChangeAdmin] }); console.log(txHash); diff --git a/.gitbook/core-modules/tokenfactory.md b/.gitbook/core-modules/tokenfactory.md index 0b77e733f..0fe6124cd 100644 --- a/.gitbook/core-modules/tokenfactory.md +++ b/.gitbook/core-modules/tokenfactory.md @@ -12,30 +12,30 @@ Let's explore (and provide examples) the Messages that the TokenFactory module e Creates a denom of `factory/{creator address}/{subdenom}` given the denom creator address and the subdenom. Subdenoms can contain [a-zA-Z0-9./]. Keep in mind that there is a `creation fee` which you need to cover when creating a new token. +Keep in mind that that the `admin` of the token can change the supply (mint or burn new tokens). Its recommended that the `admin` is unset using the `MsgChangeAdmin`, as explained [below](#msgchangeadmin). + ```ts -import { - MsgCreateDenom, -} from "@injectivelabs/sdk-ts"; -import { BigNumberInBase } from "@injectivelabs/utils"; -import { Network } from "@injectivelabs/networks"; +import { MsgCreateDenom } from '@injectivelabs/sdk-ts' +import { BigNumberInBase } from '@injectivelabs/utils' +import { Network } from '@injectivelabs/networks' -const injectiveAddress = "inj1..."; -const privateKey = "0x..."; -const subdenom = "inj-test"; +const injectiveAddress = 'inj1...' +const privateKey = '0x...' +const subdenom = 'inj-test' const msg = MsgCreateDenom.fromJSON({ subdenom, sender: injectiveAddress, -}); +}) const txHash = await new MsgBroadcasterWithPk({ privateKey, - network: Network.Testnet + network: Network.Testnet, }).broadcast({ - msgs: msg -}); + msgs: msg, +}) -console.log(txHash); +console.log(txHash) ``` ### MsgMint @@ -43,33 +43,31 @@ console.log(txHash); Minting of a specific denom is only allowed for the current admin. Note, the current admin is defaulted to the creator of the denom. ```ts -import { - MsgMint, -} from "@injectivelabs/sdk-ts"; -import { BigNumberInBase } from "@injectivelabs/utils"; -import { Network } from "@injectivelabs/networks"; +import { MsgMint } from '@injectivelabs/sdk-ts' +import { BigNumberInBase } from '@injectivelabs/utils' +import { Network } from '@injectivelabs/networks' -const injectiveAddress = "inj1..."; -const privateKey = "0x..."; -const subdenom = "inj-test"; +const injectiveAddress = 'inj1...' +const privateKey = '0x...' +const subdenom = 'inj-test' const amountToMint = 1_000_000_000 const msg = MsgMint.fromJSON({ sender: injectiveAddress, amount: { denom: `factory/${injectiveAddress}/${subdenom}`, - amount: amountToMint - } -}); + amount: amountToMint, + }, +}) const txHash = await new MsgBroadcasterWithPk({ privateKey, - network: Network.Testnet + network: Network.Testnet, }).broadcast({ msgs: msg, -}); +}) -console.log(txHash); +console.log(txHash) ``` ### MsgBurn @@ -77,40 +75,37 @@ console.log(txHash); Burning of a specific denom is only allowed for the current admin. Note, the current admin is defaulted to the creator of the denom. ```ts -import { - MsgBurn, -} from "@injectivelabs/sdk-ts"; -import { BigNumberInBase } from "@injectivelabs/utils"; -import { Network } from "@injectivelabs/networks"; +import { MsgBurn } from '@injectivelabs/sdk-ts' +import { BigNumberInBase } from '@injectivelabs/utils' +import { Network } from '@injectivelabs/networks' -const injectiveAddress = "inj1..."; -const privateKey = "0x..."; -const subdenom = "inj-test"; +const injectiveAddress = 'inj1...' +const privateKey = '0x...' +const subdenom = 'inj-test' const amountToBurn = 1_000_000_000 const msg = MsgBurn.fromJSON({ sender: injectiveAddress, amount: { denom: `factory/${injectiveAddress}/${subdenom}`, - amount: amountToBurn - } -}); + amount: amountToBurn, + }, +}) const txHash = await new MsgBroadcasterWithPk({ privateKey, - network: Network.Testnet + network: Network.Testnet, }).broadcast({ - msgs: msg -}); + msgs: msg, +}) -console.log(txHash); +console.log(txHash) ``` ### MsgSetDenomMetadata Setting of metadata for a specific denom is only allowed for the admin of the denom. It allows the overwriting of the denom metadata in the bank module. - ```ts import { MsgSetDenomMetadata, @@ -122,7 +117,6 @@ const injectiveAddress = "inj1..."; const privateKey = "0x..."; const subdenom = 'inj-test' const denom = `factory/${injectiveAddress}/${subdenom}`; -const amountToBurn = 1_000_000_000 const denomUnitsIfTokenHas0Decimals = [ { @@ -166,3 +160,33 @@ const txHash = await new MsgBroadcasterWithPk({ console.log(txHash); ``` + +### MsgChangeAdmin + +The admin of the denom has the ability to mint new supply or burn existing one. It's recommended to change the admin to an empty string as to not allow manipulating with the token's supply. + +```ts +import { MsgChangeAdmin } from '@injectivelabs/sdk-ts' +import { BigNumberInBase } from '@injectivelabs/utils' +import { Network } from '@injectivelabs/networks' + +const injectiveAddress = 'inj1...' +const privateKey = '0x...' +const subdenom = 'inj-test' +const denom = `factory/${injectiveAddress}/${subdenom}` + +const msg = MsgChangeAdmin.fromJSON({ + denom, + sender: injectiveAddress, + newAdmin: '' /** SET TO BLANK STRING */, +}) + +const txHash = await new MsgBroadcasterWithPk({ + privateKey, + network: Network.Testnet, +}).broadcast({ + msgs: msg, +}) + +console.log(txHash) +``` diff --git a/.gitbook/core-modules/wasm.md b/.gitbook/core-modules/wasm.md index 1f085d820..a257716e7 100644 --- a/.gitbook/core-modules/wasm.md +++ b/.gitbook/core-modules/wasm.md @@ -1,6 +1,6 @@ # Wasm -The `wasm` module is heart of interacting with the wasm smart contracts deployed on the injective chain, here you can find a list of [smart contracts](https://explorer.injective.network/contracts/) that are deployed on the Injective chain. +The `wasm` module is the heart of interacting with the wasm smart contracts deployed on the injective chain, here you can find a list of [smart contracts](https://explorer.injective.network/contracts/) that are deployed on the Injective chain. ### MsgExecuteContract (Transfer) diff --git a/.gitbook/querying/querying-api/querying-indexer-account.md b/.gitbook/querying/querying-api/querying-indexer-account.md index 347f32f76..591af8de0 100644 --- a/.gitbook/querying/querying-api/querying-indexer-account.md +++ b/.gitbook/querying/querying-api/querying-indexer-account.md @@ -4,7 +4,7 @@ Example code snippets to query the indexer for subaccount related data. ### Using gRPC -- Get the user's portfolio details, such as their available balance, unrealized Pnl, or their portfolio value. +* Get the user's portfolio details, such as their available balance, unrealized Pnl, or their portfolio value (deprecated -> use [Portfolio](querying-indexer-portfolio.md#using-grpc) instead) ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -20,7 +20,7 @@ const portfolio = await indexerGrpcAccountApi.fetchPortfolio(injectiveAddress) console.log(portfolio) ``` -- Get the user's trading rewards per epoch +* Get the user's trading rewards per epoch ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -40,7 +40,7 @@ const tradingRewards = await indexerGrpcAccountApi.fetchRewards({ console.log(tradingRewards) ``` -- Get a list of subaccounts associated with an injective address +* Get a list of subaccounts associated with an injective address ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -58,7 +58,7 @@ const subaccountsList = await indexerGrpcAccountApi.fetchSubaccountsList( console.log(subaccountsList) ``` -- Get the balance of a subaccount for a specific denom +* Get the balance of a subaccount for a specific denom ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -78,7 +78,7 @@ const subaccountBalance = await indexerGrpcAccountApi.fetchSubaccountBalance( console.log(subaccountBalance) ``` -- Get a list of balances for a subaccount +* Get a list of balances for a subaccount ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -95,7 +95,7 @@ const subaccountBalanceList = console.log(subaccountBalanceList) ``` -- Get the history of a subaccount +* Get the history of a subaccount ```ts import { PaginationOption, IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -117,7 +117,7 @@ const subaccountHistory = await indexerGrpcAccountApi.fetchSubaccountHistory({ console.log(subaccountHistory) ``` -- Get a summary of a subaccount's orders +* Get a summary of a subaccount's orders ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' @@ -139,7 +139,7 @@ const orderSummary = await indexerGrpcAccountApi.fetchSubaccountOrderSummary({ console.log(orderSummary) ``` -- Get states of a list of spot and/or derivatives orders +* Get states of a list of spot and/or derivatives orders ```ts import { IndexerGrpcAccountApi } from '@injectivelabs/sdk-ts' diff --git a/.gitbook/querying/querying-api/querying-indexer-oracle.md b/.gitbook/querying/querying-api/querying-indexer-oracle.md index 1f1451950..79419c01b 100644 --- a/.gitbook/querying/querying-api/querying-indexer-oracle.md +++ b/.gitbook/querying/querying-api/querying-indexer-oracle.md @@ -4,7 +4,7 @@ Example code snippets to query the indexer for oracle module related data. ### Using gRPC -- Get a list of oracles +* Get a list of oracles ```ts import { IndexerGrpcOracleApi } from '@injectivelabs/sdk-ts' @@ -18,18 +18,25 @@ const oracleList = await indexerGrpcOracleApi.fetchOracleList() console.log(oracleList) ``` -- Get price from oracle +* Get price from the oracle + +Base and Quote oracle symbols are always fetched from the market itself. They can be in a different representation than plain symbols (i.e hashes for `pyth` oracle). ```ts -import { IndexerGrpcOracleApi } from '@injectivelabs/sdk-ts' +import { IndexerGrpcOracleApi, IndexerGrpcDerivativeApi } from '@injectivelabs/sdk-ts' import { getNetworkEndpoints, Network } from '@injectivelabs/networks' const endpoints = getNetworkEndpoints(Network.Testnet) +const markets = new IndexerGrpcDerivativeApi(endpoints.indexer) const indexerGrpcOracleApi = new IndexerGrpcOracleApi(endpoints.indexer) -const baseSymbol = 'INJ' -const quoteSymbol = 'USDT' -const oracleType = 'bandibc' // primary oracle we use +const market = markets.find(market => market.ticker === 'INJ/USDT PERP') + +// These values are a part of the market object +// fetched from the chain i.e `oracle_base` and `oracle_quote` +const baseSymbol = market.oracle_base +const quoteSymbol = market.oracle_quote +const oracleType = market.oracle_type const oraclePrice = await indexerGrpcOracleApi.fetchOraclePriceNoThrow({ baseSymbol, diff --git a/.gitbook/querying/querying-api/querying-indexer-portfolio.md b/.gitbook/querying/querying-api/querying-indexer-portfolio.md index a3defb4e0..992f262fd 100644 --- a/.gitbook/querying/querying-api/querying-indexer-portfolio.md +++ b/.gitbook/querying/querying-api/querying-indexer-portfolio.md @@ -4,11 +4,10 @@ Example code snippets to query the indexer for portfolio module related data. ### Using gRPC -- Get a portfolio based off injective address, such as bank balances and subaccount balances +* Get a portfolio based on injective address, such as bank balances and subaccount balances -```ts -import { IndexerGrpcAccountPortfolioApi } from '@injectivelabs/sdk-ts' -import { getNetworkEndpoints, Network } from '@injectivelabs/networks' +
import { IndexerGrpcAccountPortfolioApi } from '@injectivelabs/sdk-ts'
+import { getNetworkEndpoints, Network } from '@injectivelabs/networks'
const endpoints = getNetworkEndpoints(Network.Testnet)
const indexerGrpcAccountPortfolioApi = new IndexerGrpcAccountPortfolioApi(
@@ -17,9 +16,9 @@ const indexerGrpcAccountPortfolioApi = new IndexerGrpcAccountPortfolioApi(
const injectiveAddress = 'inj...'
-const portfolio = await indexerGrpcAccountPortfolioApi.fetchAccountPortfolio(
+const portfolio = await indexerGrpcAccountPortfolioApi.fetchAccountPortfolioBalances(
injectiveAddress,
)
console.log(portfolio)
-```
+
diff --git a/.gitbook/querying/querying-api/streaming/README.md b/.gitbook/querying/querying-api/streaming/README.md
index d73271352..952eb2dfc 100644
--- a/.gitbook/querying/querying-api/streaming/README.md
+++ b/.gitbook/querying/querying-api/streaming/README.md
@@ -9,7 +9,7 @@
| Account Module | Streaming data from the account module |
| Auction Module | Streaming data from the auction module |
| Derivatives Module | Stream data from the derivatives module |
-| Explorer Module | Stream data from the the explorer module |
-| Oracle Module | Stream data from the the oracle |
-| Portfolio Module | Stream data from the the portfolio module |
+| Explorer Module | Stream data from the explorer module |
+| Oracle Module | Stream data from the oracle |
+| Portfolio Module | Stream data from the portfolio module |
| Spot Module | Stream data from the spot module |
diff --git a/.gitbook/querying/querying-chain/README.md b/.gitbook/querying/querying-chain/README.md
index 46d167930..37b04f896 100644
--- a/.gitbook/querying/querying-chain/README.md
+++ b/.gitbook/querying/querying-chain/README.md
@@ -21,4 +21,6 @@
| [Wasm](querying-chain-wasm.md) | Query data from the wasm module |
| [WasmX](querying-chain-wasmx.md) | Query data from the wasmX module |
| [Tendermint](querying-chain-tendermint.md) | Query data related to the tendermint api |
+| [Token Factory](token-factory.md) | Query data from the token factory module |
+***
diff --git a/.gitbook/querying/querying-chain/querying-chain-bank-module.md b/.gitbook/querying/querying-chain/querying-chain-bank-module.md
index a6f1def36..640080e90 100644
--- a/.gitbook/querying/querying-chain/querying-chain-bank-module.md
+++ b/.gitbook/querying/querying-chain/querying-chain-bank-module.md
@@ -1,14 +1,13 @@
-# Querying Chain: Bank Module
+# Bank
Example code snippets to query the chain for bank module related data.
### Using gRPC
-- Get bank module params
+* Get bank module params
-```ts
-import { ChainGrpcBankApi } from '@injectivelabs/sdk-ts'
-import { getNetworkEndpoints, Network } from '@injectivelabs/networks'
+import { ChainGrpcBankApi } from '@injectivelabs/sdk-ts'
+import { getNetworkEndpoints, Network } from '@injectivelabs/networks'
const endpoints = getNetworkEndpoints(Network.Testnet)
const chainGrpcBankApi = new ChainGrpcBankApi(endpoints.grpc)
@@ -16,9 +15,9 @@ const chainGrpcBankApi = new ChainGrpcBankApi(endpoints.grpc)
const moduleParams = await chainGrpcBankApi.fetchModuleParams()
console.log(moduleParams)
-```
+
-- Fetching injective address's balances
+* Fetching injective address's balances
```ts
import { ChainGrpcBankApi } from '@injectivelabs/sdk-ts'
@@ -34,7 +33,7 @@ const balances = await chainGrpcBankApi.fetchBalances(injectiveAddress)
console.log(balances)
```
-- Fetching cosmos address' balances per base denom
+* Fetching cosmos address' balances per base denom
```ts
import { ChainGrpcBankApi } from '@injectivelabs/sdk-ts'
@@ -54,7 +53,7 @@ const balance = await chainGrpcBankApi.fetchBalance({
console.log(balance)
```
-- Fetching total supply on chain
+* Fetching total supply on chain
```ts
import { PaginationOption, ChainGrpcBankApi } from '@injectivelabs/sdk-ts'
@@ -74,7 +73,7 @@ console.log(totalSupply)
### Using HTTP REST
-- Fetching address's balances
+* Fetching address's balances
```ts
import { ChainRestBankApi } from '@injectivelabs/sdk-ts'
@@ -90,7 +89,7 @@ const balances = await chainGrpcBankApi.fetchBalances(injectiveAddress)
console.log(balances)
```
-- Fetching cosmos address' balances per base denom
+* Fetching cosmos address' balances per base denom
```ts
import { ChainRestBankApi } from '@injectivelabs/sdk-ts'
diff --git a/.gitbook/querying/querying-chain/querying-chain-wasm.md b/.gitbook/querying/querying-chain/querying-chain-wasm.md
index 5295bf6aa..27ac78a2c 100644
--- a/.gitbook/querying/querying-chain/querying-chain-wasm.md
+++ b/.gitbook/querying/querying-chain/querying-chain-wasm.md
@@ -1,10 +1,10 @@
-# Querying Chain: Wasm
+# Wasm
Example code snippets to query the wasm module on chain
### Using gRPC
-- Get a contacts' account balance Note that pagination parameters can be passed to obtain additional accounts.
+* Get a contacts' account balance Note that pagination parameters can be passed to obtain additional accounts.
```ts
import { ChainGrpcWasmApi, PaginationOption } from '@injectivelabs/sdk-ts'
@@ -24,7 +24,7 @@ const contractAccountsBalance = await chainGrpcWasmApi.fetchContractAccountsBala
console.log(contractAccountsBalance)
```
-- Get info related to a contract
+* Get info related to a contract
```ts
import { ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
@@ -40,7 +40,7 @@ const contractInfo = await chainGrpcWasmApi.fetchContractInfo(contractAddress)
console.log(contractInfo)
```
-- Get contract history
+* Get contract history
```ts
import { ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
@@ -58,10 +58,10 @@ const contractHistory = await chainGrpcWasmApi.fetchContractHistory(
console.log(contractHistory)
```
-- Get the state of a smart contract
+* Get the state of a smart contract
```ts
-import { ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
+import { ChainGrpcWasmApi, toBase64 } from '@injectivelabs/sdk-ts'
import { getNetworkEndpoints, Network } from '@injectivelabs/networks'
const endpoints = getNetworkEndpoints(Network.Testnet)
@@ -69,16 +69,17 @@ const chainGrpcWasmApi = new ChainGrpcWasmApi(endpoints.grpc)
const contractAddress = 'inj...'
const query = '...'
+const queryFromObject = toBase64({ get_coin: {} })
const contractState = await chainGrpcWasmApi.fetchSmartContractState({
contractAddress,
- query /* optional string query - HAS to be in base64 */,
+ query /* optional string query - HAS to be in base64 or use queryFromObject */,
})
console.log(contractState)
```
-- Get the raw state of a smart contract
+* Get the raw state of a smart contract
```ts
import { ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
@@ -89,16 +90,17 @@ const chainGrpcWasmApi = new ChainGrpcWasmApi(endpoints.grpc)
const contractAddress = 'inj...'
const query = '...'
+const queryFromObject = toBase64({ get_coin: {} })
const rawContractState = await chainGrpcWasmApi.fetchRawContractState({
contractAddress,
- query /* optional string query - HAS to be in base64 */,
+ query /* optional string query - HAS to be in base64 or use queryFromObject */,
})
console.log(rawContractState)
```
-- Get the codes associated with a contract
+* Get the codes associated with a contract
```ts
import { PaginationOption, ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
@@ -117,7 +119,7 @@ pagination /* optional pagination options */
console.log(rawContractState)
```
-- Get info associated with a contract code
+* Get info associated with a contract code
```ts
import { ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
@@ -133,7 +135,7 @@ const codeDetails = await chainGrpcWasmApi.fetchContractCode(codeId)
console.log(codeDetails)
```
-- Get the contracts associated with a code
+* Get the contracts associated with a code
```ts
import { PaginationOption, ChainGrpcWasmApi } from '@injectivelabs/sdk-ts'
diff --git a/.gitbook/querying/querying-chain/token-factory.md b/.gitbook/querying/querying-chain/token-factory.md
new file mode 100644
index 000000000..517a40632
--- /dev/null
+++ b/.gitbook/querying/querying-chain/token-factory.md
@@ -0,0 +1,35 @@
+# Token Factory
+
+Example code snippets to query the chain for token factory module related data.
+
+### Using gRPC
+
+* Fetch all denoms created by _creator_
+
+import { ChainGrpcTokenFactoryApi } from '@injectivelabs/sdk-ts'
+import { getNetworkEndpoints, Network } from '@injectivelabs/networks'
+
+const endpoints = getNetworkEndpoints(Network.Testnet)
+const chainGrpcTokenFactoryApi = new ChainGrpcTokenFactoryApi(endpoints.grpc)
+
+const creator = 'inj...'
+const denoms = await chainGrpcTokenFactoryApi.fetchDenomsFromCreator(creator)
+
+console.log(denoms)
+
+
+* Fetch denom authority metadata (i.e fetch admin of a token)
+
+```ts
+import { ChainGrpcTokenFactoryApi } from '@injectivelabs/sdk-ts'
+import { getNetworkEndpoints, Network } from '@injectivelabs/networks'
+
+const endpoints = getNetworkEndpoints(Network.Testnet)
+const chainGrpcTokenFactoryApi = new ChainGrpcTokenFactoryApi(endpoints.grpc)
+
+const creator = 'inj...'
+const subdenom = 'NINJA'
+const metadata = await chainGrpcTokenFactoryApi.fetchDenomAuthorityMetadata(creator, subdenom)
+
+console.log(metadata)
+```
diff --git a/.gitbook/readme/application-concepts.md b/.gitbook/readme/application-concepts.md
index f5f67cc37..defff8ec0 100644
--- a/.gitbook/readme/application-concepts.md
+++ b/.gitbook/readme/application-concepts.md
@@ -6,7 +6,7 @@ In this section we are going to explain some application (Injective) specific co
The Token Factory module on Injective which allows users and contracts to create new native tokens and swap native tokens with CW20 tokens using the Mint + Burn model. This is an important feature to have on chain because representing assets from different sources to a native bank denom is crucial to allow users to access the rest of the on-chain modules like exchange, auction, insurance funds, etc. The token factory denoms are in the following format `factory/{creator address}/{subdenom}`.
-Combined with the `CW20AdapterContract` which acts as an creator, we allow CW20 assets to be natively represented on Injective as Token Factory denoms. The way it works is that CW20 assets are held by the `CW20AdapterContract` and minted as a factory denom for the injective address and when we want to redeem them back to CW20, they are burned from the bank module and unlocked from the `CW20AdapterContract` back to the owner address.
+Combined with the `CW20AdapterContract` which acts as a creator, we allow CW20 assets to be natively represented on Injective as Token Factory denoms. The way it works is that CW20 assets are held by the `CW20AdapterContract` and minted as a factory denom for the injective address and when we want to redeem them back to CW20, they are burned from the bank module and unlocked from the `CW20AdapterContract` back to the owner address.
Example on how to redeem a factory denom to CW20:
diff --git a/.gitbook/readme/denoms-(tokens)/README.md b/.gitbook/readme/denoms-(tokens)/README.md
index fb99b555d..69617444c 100644
--- a/.gitbook/readme/denoms-(tokens)/README.md
+++ b/.gitbook/readme/denoms-(tokens)/README.md
@@ -17,7 +17,7 @@ Token is simply a denom on the Injective chain with some meta information. The m
# Token Metadata
-Assets on Injective are represented as denoms. Denoms (and the amounts) are not human readable and this is why we need to have a way to "attach" token metadata information for a particular denom. This is achievable using the `@injectivelabs/token-metadata` package.
+Assets on Injective are represented as denoms. Denoms (and the amounts) are not humanly readable and this is why we need to have a way to "attach" token metadata information for a particular denom. This is achievable using the `@injectivelabs/token-metadata` package.
Let's recap the types of denoms we have in the Getting Started section:
diff --git a/.gitbook/readme/getting-started-cosmjs.md b/.gitbook/readme/getting-started-cosmjs.md
index 8309051ad..d795bfe9a 100644
--- a/.gitbook/readme/getting-started-cosmjs.md
+++ b/.gitbook/readme/getting-started-cosmjs.md
@@ -1,8 +1,10 @@
-# Getting Started - Cosmjs
+# CosmJs Support
Injective is not natively supported on the `@cosmjs` packages. It's highly recommended to use our `@injectivelabs` packages to interact with Injective.
-If you are familiar with the `@cosmjs` packages we are exporting similar interfaces/classes that work exactly the same as the classes on `@cosmjs` but have support for Injective as well.
+If you are familiar with the `@cosmjs` packages we are exporting similar interfaces/classes that work the same as the classes on `@cosmjs` but have support for Injective as well.
+
+Again, keep in mind that the recommended approach is to use the Injective's standard approach, which you can learn more about [here](../transactions/transactions-cosmos/).
### Usage using Keplr
@@ -66,7 +68,9 @@ import { assertIsBroadcastTxSuccess } from '@cosmjs/stargate'
### Usage in a CLI/Node environment
-Here is an example on how to use the `@injectivelabs` alternatives from the `@cosmjs` packages in a node or CLI environment:
+Here is an example on how to use the `@injectivelabs` alternatives from the `@cosmjs` packages in a node or CLI environment.
+
+Again, keep in mind that the recommended approach is to use the [MsgBroadcasterWithPk](../transactions/private-key.md#example-with-msgbroadcasterwithpk) abstraction to follow the Injective's standard approach.
```ts
import {
diff --git a/.gitbook/readme/running-examples.md b/.gitbook/readme/running-examples.md
new file mode 100644
index 000000000..c487f0917
--- /dev/null
+++ b/.gitbook/readme/running-examples.md
@@ -0,0 +1,9 @@
+---
+description: Each of these examples can be run in a simple TypeScript environment.
+---
+
+# Running examples
+
+You can clone this open-sourced repository [https://github.com/InjectiveLabs/injective-ts-examples](https://github.com/InjectiveLabs/injective-ts-examples) and follow the steps in **📚 Getting Started** to get started with your examples!
+
+You can check the two examples in the repository to make everything work out of the box in a Node environment, querying and sending a transaction.
diff --git a/.gitbook/readme/token-metadata/README.md b/.gitbook/readme/token-metadata/README.md
index 9ed1b4671..ff9b6e507 100644
--- a/.gitbook/readme/token-metadata/README.md
+++ b/.gitbook/readme/token-metadata/README.md
@@ -1,4 +1,4 @@
-# Token Metadata
+# Assets (Token Metadata)
## Denom
@@ -51,3 +51,12 @@ export interface Token {
```
There are other ways to define a token metadata for a denom on Injective and we'll explain more in the next page.
+
+### Token Verification
+
+Verifying your token's metadata can be done in a couple of ways. Here are the verification levels and what they mean:
+
+* **Verified** -> Your asset metadata has been added to the `@injectivelabs/token-metadata` package. You can find a tutorial on how to add your token's metadata to the package [here](../../../packages/token-metadata/CONTRIBUTING.md).
+* **Internal** -> Your asset's metadata has been verified on-chain using the `MsgSetDenomMetadata` message, as explained [here](https://docs.ts.injective.network/core-modules/token-factory#msgsetdenommetadata).
+* **External** -> Your asset's metadata has been verified on some external source like from Ethereum's contract details, etc.
+* **Unverified** -> Your asset's metadata has not been provided anywhere.
diff --git a/.gitbook/readme/token-metadata/creating-tokens.md b/.gitbook/readme/token-metadata/creating-tokens.md
index 016ff789a..87d614329 100644
--- a/.gitbook/readme/token-metadata/creating-tokens.md
+++ b/.gitbook/readme/token-metadata/creating-tokens.md
@@ -7,7 +7,7 @@ A single account can create multiple denoms, by providing a unique subdenom for
* Mint their denom to any account
* Burn their denom from any account
* Create a transfer of their denom between any two accounts
-* Change the admin. In the future, more admin capabilities may be added. Admins can choose to share admin privileges with other accounts using the authz module. The ChangeAdmin functionality allows changing the master admin account, or even setting it to "", meaning no account has admin privileges over the asset.
+* Change the admin. In the future, more admin capabilities may be added. Admins can choose to share admin privileges with other accounts using the authz module. The ChangeAdmin functionality allows changing the master admin account, or even setting it to the zero address `inj1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqe2hm49`, meaning no account has admin privileges over the asset.
* Set their token metadata on chain
To start creating your denoms, head to our [TokenFactory Core Module page ](../../core-modules/token-factory.md)to see examples.
diff --git a/.gitbook/transactions/README.md b/.gitbook/transactions/README.md
index 8c3da9e2f..e3da6f9fa 100644
--- a/.gitbook/transactions/README.md
+++ b/.gitbook/transactions/README.md
@@ -33,13 +33,13 @@ Every transaction we want to broadcast to Injective has the same flow. The flow
### Topics
-| Topic | Description |
-| --------------------------------------------------- | ---------------------------------------------------------- |
-| [Using the Ethereum approach](ethereum.md) | Prepare/Sign EIP712 typed data then broadcast |
-| [Using the Cosmos approach](transactions-cosmos.md) | Prepare/Sign/Broadcast Cosmos transactions |
-| [Using a Private Key](private-key.md) | Prepare/Sign/Broadcast Cosmos transaction with private key |
-| [Web3Gateway Microservice](web3-gateway.md) | A microservice for supporting fee Delegation |
-| [Msg Broadcaster](msgbroadcaster.md) | Abstraction for broadcasting messages |
+| Topic | Description |
+| ------------------------------------------------- | ---------------------------------------------------------- |
+| [Using the Ethereum approach](ethereum.md) | Prepare/Sign EIP712 typed data then broadcast |
+| [Using the Cosmos approach](transactions-cosmos/) | Prepare/Sign/Broadcast Cosmos transactions |
+| [Using a Private Key](private-key.md) | Prepare/Sign/Broadcast Cosmos transaction with private key |
+| [Web3Gateway Microservice](web3-gateway.md) | A microservice for supporting fee Delegation |
+| [Msg Broadcaster](msgbroadcaster.md) | Abstraction for broadcasting messages |
diff --git a/.gitbook/transactions/ethereum.md b/.gitbook/transactions/ethereum.md
index fa415f959..0176a5380 100644
--- a/.gitbook/transactions/ethereum.md
+++ b/.gitbook/transactions/ethereum.md
@@ -150,47 +150,56 @@ import {
ChainRestAuthApi,
ChainRestTendermintApi,
BaseAccount,
- DEFAULT_STD_FEE,
getEip712TypedData,
-} from '@injectivelabs/sdk-ts'
+ getEthereumAddress,
+ recoverTypedSignaturePubKey,
+ hexToBase64,
+ createTransaction,
+ SIGN_AMINO,
+ createWeb3Extension,
+ createTxRawEIP712,
+ TxRestClient,
+} from "@injectivelabs/sdk-ts";
import {
+ BigNumberInBase,
DEFAULT_STD_FEE,
DEFAULT_BLOCK_TIMEOUT_HEIGHT,
-} from '@injectivelabs/utils'
-import { ChainId } from '@injectivelabs/ts-types'
-import { Network, getNetworkEndpoints } from '@injectivelabs/networks'
-
-const injectiveAddress = 'inj1'
-const chainId = 'injective-1' /* ChainId.Mainnet */
-const restEndpoint =
- 'https://lcd.injective.network' /* getNetworkEndpoints(Network.Mainnet).rest */
+} from "@injectivelabs/utils";
+import { ChainId } from "@injectivelabs/ts-types";
+import { Network, getNetworkEndpoints } from "@injectivelabs/networks";
+
+const injectiveAddress = "inj1";
+const ethereumAddress = getEthereumAddress(injectiveAddress)
+const chainId = "injective-1"; /* ChainId.Mainnet */
+const ethereumChainId = 1; /* ChainId.EthereumMainnet */
+const restEndpoint = getNetworkEndpoints(Network.MainnetSentry).rest;
const amount = {
amount: new BigNumberInBase(0.01).toWei().toFixed(),
- denom: 'inj',
-}
+ denom: "inj",
+};
/** Account Details **/
-const chainRestAuthApi = new ChainRestAuthApi(restEndpoint)
+const chainRestAuthApi = new ChainRestAuthApi(restEndpoint);
const accountDetailsResponse = await chainRestAuthApi.fetchAccount(
- injectiveAddress,
-)
-const baseAccount = BaseAccount.fromRestApi(accountDetailsResponse)
-const accountDetails = baseAccount.toAccountDetails()
+ injectiveAddress
+);
+const baseAccount = BaseAccount.fromRestApi(accountDetailsResponse);
+const accountDetails = baseAccount.toAccountDetails();
/** Block Details */
-const chainRestTendermintApi = new ChainRestTendermintApi(restEndpoint)
-const latestBlock = await chainRestTendermintApi.fetchLatestBlock()
-const latestHeight = latestBlock.header.height
+const chainRestTendermintApi = new ChainRestTendermintApi(restEndpoint);
+const latestBlock = await chainRestTendermintApi.fetchLatestBlock();
+const latestHeight = latestBlock.header.height;
const timeoutHeight = new BigNumberInBase(latestHeight).plus(
- DEFAULT_BLOCK_TIMEOUT_HEIGHT,
-)
+ DEFAULT_BLOCK_TIMEOUT_HEIGHT
+);
/** Preparing the transaction */
const msg = MsgSend.fromJSON({
amount,
srcInjectiveAddress: injectiveAddress,
dstInjectiveAddress: injectiveAddress,
-})
+});
/** EIP712 for signing on Ethereum wallets */
const eip712TypedData = getEip712TypedData({
@@ -202,21 +211,22 @@ const eip712TypedData = getEip712TypedData({
chainId: chainId,
},
ethereumChainId: ethereumChainId,
-})
+});
/** Use your preferred approach to sign EIP712 TypedData, example with Metamask */
const signature = await window.ethereum.request({
- method: 'eth_signTypedData_v4',
+ method: "eth_signTypedData_v4",
params: [ethereumAddress, JSON.stringify(eip712TypedData)],
-})
+});
/** Get Public Key of the signer */
-const publicKeyHex = recoverTypedSignaturePubKey(eip712TypedData, signature)
-const publicKeyBase64 = hexToBase64(publicKeyHex)
+const publicKeyHex = recoverTypedSignaturePubKey(eip712TypedData, signature);
+const publicKeyBase64 = hexToBase64(publicKeyHex);
+const signatureBuff = Buffer.from(signature.replace('0x', ''), "hex");
const { txRaw } = createTransaction({
- message: msgs,
- memo: memo,
+ message: [msg],
+ memo: '',
signMode: SIGN_AMINO,
fee: DEFAULT_STD_FEE,
pubKey: publicKeyBase64,
@@ -224,20 +234,20 @@ const { txRaw } = createTransaction({
timeoutHeight: timeoutHeight.toNumber(),
accountNumber: baseAccount.accountNumber,
chainId: chainId,
-})
+});
const web3Extension = createWeb3Extension({
ethereumChainId,
-})
-const txRawEip712 = createTxRawEIP712(txRaw, web3Extension)
+});
+const txRawEip712 = createTxRawEIP712(txRaw, web3Extension);
/** Append Signatures */
-txRawEip712.signatures = [signatureBuff]
+txRawEip712.signatures = [signatureBuff];
/** Broadcast the Transaction */
-const txRestClient = new TxRestClient(restEndpoint)
+const txRestClient = new TxRestClient(restEndpoint);
-const txHash = await txRestClient.broadcast(txRawEip712)
-const response = await txRestClient.fetchTxPoll(txHash)
+const txResponse = await txRestClient.broadcast(txRawEip712);
+const response = await txRestClient.fetchTxPoll(txResponse.txHash);
```
### Example with WalletStrategy (Prepare + Sign + Broadcast)
diff --git a/.gitbook/transactions/private-key.md b/.gitbook/transactions/private-key.md
index 888432219..6ec2af05b 100644
--- a/.gitbook/transactions/private-key.md
+++ b/.gitbook/transactions/private-key.md
@@ -1,5 +1,7 @@
# Private Key
+In this document, we are going to show you how to use a PrivateKey to sign transactions on Injective.
+
Every transaction on Injective follows the same flow. The flow consists of three steps: preparing, signing and broadcasting the transaction. Let's dive into each step separately and explain the process in-depth (including examples) so we can understand the whole transaction flow.
### Preparing a transaction
@@ -220,7 +222,9 @@ import { BigNumberInBase, DEFAULT_STD_FEE } from '@injectivelabs/utils'
### Example with MsgBroadcasterWithPk
-You can use the `MsgBroadcasterWithPk` class from the `@injectivelabs/sdk-ts` package which abstracts away most of the logic written above into a single class.
+You can use the `MsgBroadcasterWithPk` class from the `@injectivelabs/sdk-ts` package which abstracts away most of the logic written above into a single class.
+
+**This abstraction allows you to sign transactions in a Node/CLI environment.**
```ts
import { MsgSend, MsgBroadcasterWithPk } from '@injectivelabs/sdk-ts'
@@ -231,7 +235,7 @@ const privateKey = '0x...'
const injectiveAddress = 'inj1...'
const amount = {
denom: 'inj',
- amount: new BigNumberInBase(1).toWei(),
+ amount: new BigNumberInBase(1).toWei().toFixed(),
}
const msg = MsgSend.fromJSON({
amount,
diff --git a/.gitbook/transactions/transactions-cosmos.md b/.gitbook/transactions/transactions-cosmos/README.md
similarity index 96%
rename from .gitbook/transactions/transactions-cosmos.md
rename to .gitbook/transactions/transactions-cosmos/README.md
index f5e96c69c..1d7a2fad8 100644
--- a/.gitbook/transactions/transactions-cosmos.md
+++ b/.gitbook/transactions/transactions-cosmos/README.md
@@ -108,7 +108,12 @@ Once we have the signature ready, we need to broadcast the transaction to the In
```ts
import { ChainId } from '@injectivelabs/ts-types'
-import { CosmosTxV1Beta1Tx, getTxRawFromTxRawOrDirectSignResponse, TxRestClient } from '@injectivelabs/sdk-ts'
+import {
+ BroadcastModeKeplr,
+ CosmosTxV1Beta1Tx,
+ getTxRawFromTxRawOrDirectSignResponse,
+ TxRestClient
+} from '@injectivelabs/sdk-ts'
import { Network, getNetworkEndpoints } from '@injectivelabs/networks'
/**
@@ -137,7 +142,7 @@ const broadcastTx = async (chainId, txRaw) => {
const result = await keplr.sendTx(
chainId,
CosmosTxV1Beta1Tx.TxRaw.encode(txRaw).finish(),
- BroadcastMode.Sync,
+ BroadcastModeKeplr.Sync,
)
if (!result || result.length === 0) {
@@ -177,6 +182,7 @@ import {
ChainRestAuthApi,
createTransaction,
CosmosTxV1Beta1Tx,
+ BroadcastModeKeplr,
ChainRestTendermintApi,
} from '@injectivelabs/sdk-ts'
import {
@@ -201,7 +207,7 @@ const broadcastTx = async (chainId, txRaw) => {
const result = await keplr.sendTx(
chainId,
CosmosTxV1Beta1Tx.TxRaw.encode(txRaw).finish(),
- BroadcastMode.Sync,
+ BroadcastModeKeplr.Sync,
)
if (!result || result.length === 0) {
@@ -214,8 +220,10 @@ const broadcastTx = async (chainId, txRaw) => {
return Buffer.from(result).toString('hex')
}
-const injectiveAddress = 'inj1'
const chainId = 'injective-1' /* ChainId.Mainnet */
+const { key } = await getKeplr(chainId)
+const pubKey = Buffer.from(key.pubKey).toString('base64')
+const injectiveAddress = key.bech32Address
const restEndpoint =
'https://lcd.injective.network' /* getNetworkEndpoints(Network.Mainnet).rest */
const amount = {
@@ -246,9 +254,6 @@ const msg = MsgSend.fromJSON({
dstInjectiveAddress: injectiveAddress,
})
-/** Get the PubKey of the Signer from the Wallet/Private Key */
-const pubKey = await getPubKey()
-
/** Prepare the Transaction **/
const { txRaw, signDoc } = createTransaction({
pubKey,
diff --git a/.gitbook/transactions/transactions-cosmos/ledger-through-keplr-wallet.md b/.gitbook/transactions/transactions-cosmos/ledger-through-keplr-wallet.md
new file mode 100644
index 000000000..5ebcd4f63
--- /dev/null
+++ b/.gitbook/transactions/transactions-cosmos/ledger-through-keplr-wallet.md
@@ -0,0 +1,233 @@
+# Ledger through Keplr Wallet
+
+On this page, we are going to have a look at the implementation for Injective when your users are using a Ledger device through the Keplr wallet.
+
+As explained before, Injective uses a different derivation curve from the rest of the Cosmos chains which means that the users have to use the Ethereum app (for now) to interact with Injective.
+
+The easiest way all of the edge cases covered and a full out-of-the-box solution for all of the supported wallets on Injective I suggest you have a look at the [MsgBroadcaster + WalletStrategy ](../msgbroadcaster.md#msgbroadcaster-+-wallet-strategy)abstraction. If you want to do your own implementation, let's go through the code example together.
+
+### Overview
+
+Keplr exposes a `experimentalSignEIP712CosmosTx_v0` method which can be utilized to sign EIP712 typed data (automatically generated on the Keplr side by passing a Cosmos StdSignDoc to the method above) and allow EVM-compatible chains to get proper signatures when we have Ledger devices connected through Keplr.
+
+Here is the function's signature:
+
+```typescript
+/**
+ * Sign the sign doc with ethermint's EIP-712 format.
+ * The difference from signEthereum(..., EthSignType.EIP712) is that this api returns a new sign doc changed by the user's fee setting and the signature for that sign doc.
+ * Encoding tx to EIP-712 format should be done on the side using this api.
+ * Not compatible with cosmjs.
+ * The returned signature is (r | s | v) format which used in ethereum.
+ * v should be 27 or 28 which is used in the ethereum mainnet regardless of chain.
+ * @param chainId
+ * @param signer
+ * @param eip712
+ * @param signDoc
+ * @param signOptions
+ */
+experimentalSignEIP712CosmosTx_v0(chainId: string, signer: string, eip712: {
+ types: RecordGenerated using TypeDoc
validator defines the validator info.
+Generated using TypeDoc
QueryValidatorResponse is response type for the Query/Validator RPC method