Skip to content

Commit

Permalink
Merge pull request #516 from InjectiveLabs/chore/cw20-convert-docs
Browse files Browse the repository at this point in the history
chore: cw20 to bank convert docs
  • Loading branch information
ThomasRalee authored Nov 29, 2024
2 parents bddcbfc + b88b459 commit 594206a
Show file tree
Hide file tree
Showing 28 changed files with 543 additions and 364 deletions.
1 change: 1 addition & 0 deletions .gitbook/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
- [Contracts](contracts/README.md)
- [Injective Name Service](contracts/injective-name-service.md)
- [Neptune Service](contracts/neptune-service.md)
- [CW20 to Bank & Market Order in One Transaction](contracts/cw20-convert-and-market-order-example.md)
- [Building dApps](building-dapps/README.md)
- [Configuring Nuxt](building-dapps/configuring-nuxt.md)
- [Configuring React](building-dapps/configuring-react.md)
Expand Down
11 changes: 6 additions & 5 deletions .gitbook/contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Contracts

#### [What is CosmWasm?](./#what-is-cosmwasm-)[](https://docs.injective.network/develop/guides/cosmwasm-dapps/#what-is-cosmwasm) <a href="#user-content-what-is-cosmwasm" id="user-content-what-is-cosmwasm"></a>
#### What is CosmWasm?

CosmWasm is a novel smart contracting platform built for the Cosmos ecosystem. You can learn more about CosmWasm [here](https://docs.cosmwasm.com/docs/), or see the [CosmWasm Book](https://book.cosmwasm.com/index.html) for a guide on creating CosmWasm smart contracts.

#### Specific Cosmwasm Contracts

| Topic | Description |
| --------------------------------------------------- | ---------------------- |
| [Injective Name Service](injective-name-service.md) | Injective Name Service |
| [Neptune Service](neptune-service.md) | Injective Name Service |
| Topic | Description |
| ------------------------------------------------------------------------------------------ | ---------------------- |
| [Injective Name Service](injective-name-service.md) | Injective Name Service |
| [Neptune Service](neptune-service.md) | Neptune Service |
| [CW20 to Bank & Market Order in One Transaction](cw20-convert-and-market-order-example.md) | Convert Cw20 Example |
54 changes: 54 additions & 0 deletions .gitbook/contracts/cw20-convert-and-market-order-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Convert Cw20 to Bank and Place Market Order In One Transaction Example

This example helps you create messages to convert CW20 tokens to bank tokens on the Injective blockchain. This is particularly useful when you have CW20 tokens and need to convert them to their bank equivalents to perform operations like placing market orders. Note that this flow only works for cw20 tokens and their corresponding [factory tokens](../readme/application-concepts.md).

This guide will walk you through:

- Obtaining the user's CW20 token balance.
- Creating a message to convert CW20 tokens to bank tokens using ConvertCw20ToBankService
- Executing a market order using the converted bank balance and existing bank balance

## Get User's CW20 Balance

[Detailed here](../querying/querying-api/querying-indexer-explorer.md#fetch-cw20-balances)

- Find the cw20 address and balance from the result set that you want to convert to a bank factory token

## Create CW20 to Bank Conversion Message

- create the `convertMsg` using the steps detailed [here](../readme/application-concepts#example-on-how-to-convert-cw20-to-a-factory-denom) in order to convert your cw20 token to a bank factory token. No need to submit the tsx yet.

## Create a `MsgCreateSpotMarketOrder` message

- Create the `msg` using the steps detailed in [MsgCreateSpotMarketOrder](../core-modules/exchange.md#msgcreatespotmarketorder). No need to submit the tsx yet.
- Note that the buy order you create will have access to your converted cw20 balance + existing bank balance. Example:

```ts
const order = {
price: 1,
quantity: 10,
}
```

- If you had 5 Cw20 tokens and 5 bank tokens at a price of $1 each, then the order above will go through because we will convert the cw20 to bank before the chain executes this market order. This will be more clear in the next step.

## Place a Market Order Using Converted CW20 Balance and your existing bank balance

Now that you have both messages formatted, you can convert your cw20 tokens to bank factory tokens and then place a market order using the combined balance, all in one transaction

```ts
import { MsgBroadcasterWithPk } from '@injectivelabs/sdk-ts'
import { Network } from '@injectivelabs/networks'

const privateKey = '0x...'
const injectiveAddress = 'inj1...'

const txHash = await new MsgBroadcasterWithPk({
privateKey,
network: Network.MainnetSentry,
}).broadcast({
msgs: [convertMsg, msg], // the convert to bank message executes first, Then, you will have that additional balance to complete your market order in the following msg
})

console.log(txHash)
```
2 changes: 1 addition & 1 deletion .gitbook/core-modules/auction.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ How to use funds that are currently associated with your Injective Address in ba
- 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/).
For more info, check out the [burn auction pool docs](https://docs.injective.network/developers/modules/injective/auction).

```ts
import {
Expand Down
22 changes: 14 additions & 8 deletions .gitbook/readme/application-concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ Combined with the `CW20AdapterContract` which acts as a creator, we allow CW20 a
Example on how to redeem a factory denom to CW20:

```ts
import { MsgExecuteContractCompat, ExecArgCW20AdapterRedeemAndTransfer } from '@injectivelabs/sdk-ts'
import {
MsgExecuteContractCompat,
ExecArgCW20AdapterRedeemAndTransfer,
} from '@injectivelabs/sdk-ts'

const CW20_ADAPTER_CONTRACT = 'inj...'
const contractCw20Address = 'inj...'
Expand All @@ -22,20 +25,23 @@ const message = MsgExecuteContractCompat.fromJSON({
contractAddress: CW20_ADAPTER_CONTRACT,
funds: {
denom: `factory/${CW20_ADAPTER_CONTRACT}/${contractCw20Address}`,
amount: actualAmount.toFixed()
amount: actualAmount.toFixed(),
},
execArgs: ExecArgCW20AdapterRedeemAndTransfer.fromJSON({
recipient: injectiveAddress
})
recipient: injectiveAddress,
}),
})

// Then pack the message in a transaction, sign it and broadcast to the chain
```

Example on how to convert CW20 to a factory denom:
### Example on how to convert CW20 to a factory denom:

```ts
import { MsgExecuteContractCompat, ExecArgCW20Send } from '@injectivelabs/sdk-ts'
import {
ExecArgCW20Send,
MsgExecuteContractCompat,
} from '@injectivelabs/sdk-ts'

const CW20_ADAPTER_CONTRACT = 'inj...'
const contractCw20Address = 'inj...'
Expand All @@ -47,8 +53,8 @@ const message = MsgExecuteContractCompat.fromJSON({
sender: injectiveAddress,
execArgs: ExecArgCW20Send.fromJSON({
amount,
contractAddress: CW20_ADAPTER_CONTRACT
})
contractAddress: CW20_ADAPTER_CONTRACT,
}),
})

// Then pack the message in a transaction, sign it and broadcast to the chain
Expand Down
2 changes: 1 addition & 1 deletion .gitbook/transactions/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Transactions

_Pre-requisite reading:_ [Cosmos SDK Transactions](https://docs.cosmos.network/main/core/transactions.html)
_Pre-requisite reading:_ [Cosmos SDK Transactions](https://docs.cosmos.network/main/learn/advanced/transactions)

State changes on Injective can be done through transactions. Users create transactions, sign them and broadcast them to Injective.

Expand Down
30 changes: 29 additions & 1 deletion packages/sdk-ts/src/core/accounts/PrivateKey.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { generateArbitrarySignDoc } from '../tx/index.js'
import { verifyMessage, Wallet } from 'ethers'
import { toUtf8 } from '../../utils'
import { PrivateKey } from './PrivateKey.js'
import { generateArbitrarySignDoc } from '../tx/index.js'

const pk = process.env.TEST_PRIVATE_KEY as string
const seedPhase = process.env.TEST_SEED_PHASE as string
Expand Down Expand Up @@ -117,6 +119,32 @@ describe('PrivateKey', () => {
//
})

it('returns true when checking a pk signature against the signer public key', async () => {
const message = 'this is a test message'

const wallet = new Wallet(pk)
const ethersSignature = await wallet.signMessage(message)

const privateKey = PrivateKey.fromHex(pk)
const publicKey = privateKey.toHex()

const privKeySignatureArray = privateKey.sign(
Buffer.from(toUtf8(message), 'utf-8'),
)
const privKeySignature = `0x${Buffer.from(privKeySignatureArray).toString(
'hex',
)}`

const ethersVerifiedSigner = verifyMessage(message, ethersSignature)
const ethersSignatureVerifiedCorrectly = ethersVerifiedSigner === publicKey
expect(ethersSignatureVerifiedCorrectly).toBe(true)

const privKeyVerifiedSigner = verifyMessage(message, privKeySignature)
const privKeySignatureVerifiedCorrectly =
privKeyVerifiedSigner === publicKey
expect(privKeySignatureVerifiedCorrectly).toBe(true)
})

it('returns true when verifying arbitrary message', async () => {
const privateKey = PrivateKey.fromHex(pk)

Expand Down
3 changes: 3 additions & 0 deletions packages/utils/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ export const snakeToPascal = (str: string): string => {
)
.join('/')
}

export const capitalize = (str: string): string =>
str[0].toUpperCase() + str.slice(1)
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
/* eslint-disable class-methods-use-this */
import { AccountAddress, EthereumChainId } from '@injectivelabs/ts-types'
import { bufferToHex, addHexPrefix } from 'ethereumjs-util'
import { Common, Chain, Hardfork } from '@ethereumjs/common'
import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx'
import {
ErrorType,
GeneralException,
LedgerException,
TransactionException,
UnspecifiedErrorCode,
WalletException,
GeneralException,
UnspecifiedErrorCode,
TransactionException,
} from '@injectivelabs/exceptions'
import { DirectSignResponse } from '@cosmjs/proto-signing'
import { bufferToHex, addHexPrefix } from 'ethereumjs-util'
import { Common, Chain, Hardfork } from '@ethereumjs/common'
import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx'
import { Alchemy, Network as AlchemyNetwork } from 'alchemy-sdk'
import { AccountAddress, EthereumChainId } from '@injectivelabs/ts-types'
import { TxGrpcApi, TxRaw, TxResponse, toUtf8 } from '@injectivelabs/sdk-ts'
import { TIP_IN_GWEI } from '../../../../utils/constants.js'
import {
LedgerWalletInfo,
SendTransactionOptions,
LedgerDerivationPathType,
} from '../../types.js'
import {
ConcreteWalletStrategy,
EthereumWalletStrategyArgs,
WalletStrategyEthereumOptions,
} from '../../../types/index.js'
import {
LedgerDerivationPathType,
LedgerWalletInfo,
SendTransactionOptions,
} from '../../types.js'
import BaseConcreteStrategy from '../Base.js'
import {
DEFAULT_BASE_DERIVATION_PATH,
DEFAULT_ADDRESS_SEARCH_LIMIT,
DEFAULT_NUM_ADDRESSES_TO_FETCH,
} from '../../constants.js'
import LedgerHW from './hw/index.js'
import BaseConcreteStrategy from '../Base.js'
import { domainHash, messageHash } from './utils.js'
import { WalletAction, WalletDeviceType } from '../../../../types/enums.js'
import { TIP_IN_GWEI } from '../../../../utils/constants.js'
import { getKeyFromRpcUrl } from '../../../../utils/alchemy.js'
import { Alchemy, Network as AlchemyNetwork } from 'alchemy-sdk'
import { WalletAction, WalletDeviceType } from '../../../../types/enums.js'

const getNetworkFromChainId = (chainId: EthereumChainId): Chain => {
if (chainId === EthereumChainId.Goerli) {
Expand Down
30 changes: 20 additions & 10 deletions packages/wallets/wallet-base/src/utils/wallet.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Wallet } from './../types/enums.js'

export const isEthWallet = (wallet: Wallet): boolean =>
export const isEvmWallet = (wallet: Wallet): boolean =>
[
Wallet.Magic,
Wallet.Torus,
Expand All @@ -17,7 +17,25 @@ export const isEthWallet = (wallet: Wallet): boolean =>
Wallet.CosmostationEth,
].includes(wallet)

export const isCosmosWallet = (wallet: Wallet): boolean => !isEthWallet(wallet)
export const isCosmosWallet = (wallet: Wallet): boolean => !isEvmWallet(wallet)

export const isEvmBrowserWallet = (wallet: Wallet) => [
Wallet.BitGet,
Wallet.Phantom,
Wallet.Metamask,
Wallet.OkxWallet,
Wallet.TrustWallet,
].includes(wallet)


export const isCosmosBrowserWallet = (wallet: Wallet): boolean =>
[
Wallet.Leap,
Wallet.Ninji,
Wallet.Keplr,
Wallet.OWallet,
Wallet.Cosmostation,
].includes(wallet)

export const isEip712V2OnlyWallet = (wallet: Wallet): boolean =>
[
Expand All @@ -29,11 +47,3 @@ export const isEip712V2OnlyWallet = (wallet: Wallet): boolean =>

export const isCosmosAminoOnlyWallet = (wallet: Wallet): boolean =>
[Wallet.LedgerCosmos].includes(wallet)

export const COSMOS_WALLETS = [
Wallet.Keplr,
Wallet.Leap,
Wallet.Ninji,
Wallet.Cosmostation,
Wallet.OWallet,
]
2 changes: 1 addition & 1 deletion packages/wallets/wallet-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"@injectivelabs/sdk-ts": "^1.14.33-beta.2",
"@injectivelabs/ts-types": "^1.14.32",
"@injectivelabs/utils": "^1.14.32",
"@injectivelabs/wallet-base": "^0.0.6",
"@injectivelabs/wallet-base": "^1.14.33-beta.2",
"eip1193-provider": "^1.0.1"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { GeneralException, WalletException } from '@injectivelabs/exceptions'
import {
Wallet,
isEthWallet,
isEvmWallet,
isCosmosWallet,
WalletDeviceType,
ConcreteStrategiesArg,
Expand Down Expand Up @@ -151,7 +151,7 @@ export default class BaseWalletStrategy implements WalletStrategyInterface {
signDoc: StdSignDoc
address: string
}): Promise<AminoSignResponse> {
if (isEthWallet(this.wallet)) {
if (isEvmWallet(this.wallet)) {
throw new WalletException(
new Error(`You can't sign Cosmos Transaction using ${this.wallet}`),
)
Expand All @@ -166,7 +166,7 @@ export default class BaseWalletStrategy implements WalletStrategyInterface {
chainId: string
address: string
}): Promise<DirectSignResponse> {
if (isEthWallet(this.wallet)) {
if (isEvmWallet(this.wallet)) {
throw new WalletException(
new Error(`You can't sign Cosmos Transaction using ${this.wallet}`),
)
Expand Down Expand Up @@ -207,7 +207,7 @@ export default class BaseWalletStrategy implements WalletStrategyInterface {
}

public getCosmosWallet(chainId: ChainId): CosmosWalletAbstraction {
if ([Wallet.Keplr, Wallet.Leap].includes(this.getWallet())) {
if (![Wallet.Keplr, Wallet.Leap].includes(this.getWallet())) {
throw new WalletException(
new Error(`You can't use this method outside of Keplr/Leap wallet`),
)
Expand Down
1 change: 1 addition & 0 deletions packages/wallets/wallet-cosmos/src/cosmos.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ declare global {
leap: KeplrWindow['keplr']
keplr: KeplrWindow['keplr']
ninji: KeplrWindow['ninji']
owallet?: KeplrWindow['owallet']
}
}
8 changes: 8 additions & 0 deletions packages/wallets/wallet-cosmos/src/data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Wallet } from '@injectivelabs/wallet-base'

export const cosmosWallets = [
Wallet.Leap,
Wallet.Ninji,
Wallet.Keplr,
Wallet.OWallet,
]
1 change: 1 addition & 0 deletions packages/wallets/wallet-cosmos/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { CosmosWallet } from './wallet.js'
export { CosmosWalletStrategy } from './strategy/strategy.js'
export * from './utils/index.js'
Loading

0 comments on commit 594206a

Please sign in to comment.