Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/optional update same token name #1106

Merged
merged 5 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
"@oraichain/ethereum-multicall": "^1.0.2",
"@oraichain/kawaiiverse-txs": "^0.0.3",
"@oraichain/orai-bitcoin": "2.0.0",
"@oraichain/orai-token-inspector": "^0.1.24",
"@oraichain/oraidex-common": "2.0.6",
"@oraichain/orai-token-inspector": "^0.1.25",
"@oraichain/oraidex-common-ui": "1.0.11",
"@oraichain/oraidex-contracts-sdk": "1.0.55",
"@oraichain/oraidex-universal-swap": "1.3.1",
"@oraichain/oraiswap-v3": "1.2.0-beta26",
"@oraichain/proto": "^0.0.7",
"@oraichain/ton-bridge-contracts": "^0.15.8",
"@oraichain/tonbridge-contracts-sdk": "^1.3.1",
"@oraichain/tonbridge-sdk": "^1.3.6",
Expand Down
2 changes: 1 addition & 1 deletion src/libs/cosmjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const getCosmWasmClient = async (
tmClient,
wallet,
options
? { ...options, broadcastPollIntervalMs: 600 }
? { ...options, gasPrice: GasPrice.fromString(network.fee.gasPrice + network.denom), broadcastPollIntervalMs: 600 }
: {
gasPrice: GasPrice.fromString(network.fee.gasPrice + network.denom),
broadcastPollIntervalMs: 600
Expand Down
202 changes: 123 additions & 79 deletions src/pages/Pools/NewTokenModal/NewTokenModal.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,38 @@
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate';
import { AccountData } from '@cosmjs/proto-signing';
import { AccountData, Registry } from '@cosmjs/proto-signing';
import { sha256 } from '@injectivelabs/sdk-ts';
import ArrowDownIcon from 'assets/icons/arrow.svg?react';
import PlusIcon from 'assets/icons/plus.svg?react';
import cn from 'classnames/bind';
import Input from 'components/Input';
import Loader from 'components/Loader';
import Modal from 'components/Modal';
import { TToastType, displayToast } from 'components/Toasts/Toast';
import { displayToast, TToastType } from 'components/Toasts/Toast';
import { getTransactionUrl, handleErrorTransaction } from 'helper';
import useConfigReducer from 'hooks/useConfigReducer';
import useOnClickOutside from 'hooks/useOnClickOutside';
import { network } from 'initCommon';
import { getCosmWasmClient } from 'libs/cosmjs';
import { validateAddressCosmos } from 'libs/utils';
import { FC, useRef, useState } from 'react';
import { InitBalancesItems } from './ItemsComponent';
import styles from './NewTokenModal.module.scss';
import ArrowDownIcon from 'assets/icons/arrow.svg?react';
import NumberFormat from 'react-number-format';
import { inspectToken } from 'reducer/onchainTokens';
import { useDispatch } from 'react-redux';
const cx = cn.bind(styles);
import { InitBalancesItems } from './ItemsComponent';
import styles from './NewTokenModal.module.scss';
import * as cosmwasmTokenfactoryV1beta1TxRegistry from '@oraichain/proto/dist/codegen/cosmwasm/tokenfactory/v1beta1/tx.registry';

import {
MsgCreateDenom,
MsgMint,
MsgSetDenomMetadata
} from '@oraichain/proto/dist/codegen/cosmwasm/tokenfactory/v1beta1/tx';

import { inspectToken, optimisticUpdateToken } from 'reducer/onchainTokens';
import { GasPrice } from '@cosmjs/stargate';
import { OraichainNetworkConfig } from '@oraichain/orai-token-inspector';

const TOKEN_FACTORY_CONTRACT = 'orai1ytjgzxvtsq3ukhzmt39cp85j27zzqf5y706y9qrffrnpn3vd3uds957ydu';
const cx = cn.bind(styles);
// const TOKEN_FACTORY_CONTRACT = 'orai1ytjgzxvtsq3ukhzmt39cp85j27zzqf5y706y9qrffrnpn3vd3uds957ydu';
const DEFAULT_COSMOS_DECIMALS = 6;

interface ModalProps {
Expand Down Expand Up @@ -63,9 +73,19 @@ const NewTokenModal: FC<ModalProps> = ({ isOpen, close, open }) => {
useOnClickOutside(ref, () => handleOutsideClick());

const handleCreateToken = async () => {
const { client, defaultAddress: address } = await getCosmWasmClient({
chainId: network.chainId
});
const {
client,
defaultAddress: address,
wallet
} = await getCosmWasmClient(
{
chainId: network.chainId
},
{
registry: new Registry(cosmwasmTokenfactoryV1beta1TxRegistry.registry)
}
);

if (!oraiAddress)
return displayToast(TToastType.TX_FAILED, {
message: 'Wallet address does not exist!'
Expand Down Expand Up @@ -103,72 +123,96 @@ const NewTokenModal: FC<ModalProps> = ({ isOpen, close, open }) => {
const hash = Buffer.from(sha256(uint8Array)).toString('hex');

const symbol = tokenSymbol.trim();
const createDenomMsg = {
contractAddress: TOKEN_FACTORY_CONTRACT,
msg: {
create_denom: {
metadata: {
base: `factory/${TOKEN_FACTORY_CONTRACT}/${tokenSymbol}`,
denom_units: [
{
denom: `factory/${TOKEN_FACTORY_CONTRACT}/${tokenSymbol}`,
exponent: 0,
aliases: []
},
{
denom: tokenSymbol,
exponent: DEFAULT_COSMOS_DECIMALS,
aliases: []
}
],
description: description,
display: symbol,
name: tokenName.trim(),
symbol: symbol,
uri: tokenLogoUrl,
uri_hash: hash

const createDenomMsg = MsgCreateDenom.fromPartial({
sender: address.address,
subdenom: tokenSymbol
});

const setDenomMetadataMsg = MsgSetDenomMetadata.fromPartial({
sender: address.address,
metadata: {
base: `factory/${address.address}/${tokenSymbol}`,
denomUnits: [
{
denom: `factory/${address.address}/${tokenSymbol}`,
exponent: 0,
aliases: []
},
subdenom: tokenSymbol
}
},
funds: [
{
denom: 'orai',
amount: '1'
}
]
};
{
denom: tokenSymbol,
exponent: DEFAULT_COSMOS_DECIMALS,
aliases: []
}
],
description: description,
display: symbol,
name: tokenName.trim(),
symbol: symbol,
uri: tokenLogoUrl,
uriHash: hash
}
});

const initBalanceMsg = isInitBalances
const mintMsgs = isInitBalances
? initBalances.map((init) => {
console.log(init.amount.toString());
return {
contractAddress: TOKEN_FACTORY_CONTRACT,
msg: {
mint_tokens: {
amount: init.amount.toString(),
denom: `factory/${TOKEN_FACTORY_CONTRACT}/${tokenSymbol}`,
mint_to_address: init.address
}
},
funds: []
};
return MsgMint.fromPartial({
sender: address.address,
mintToAddress: init.address,
amount: {
denom: `factory/${address.address}/${tokenSymbol}`,
amount: init.amount.toString()
}
});
})
: [];

msgs.push(createDenomMsg);
const mintRawMsgs = mintMsgs.map((msg) => ({
typeUrl: '/cosmwasm.tokenfactory.v1beta1.MsgMint',
value: msg
}));

if (initBalances.length > 0) {
msgs.push(...initBalanceMsg);
}
const res = await client.executeMultiple(address.address, msgs, 'auto');
const res = await client.signAndBroadcast(
address.address,
[
{
typeUrl: '/cosmwasm.tokenfactory.v1beta1.MsgCreateDenom',
value: createDenomMsg
},
{
typeUrl: '/cosmwasm.tokenfactory.v1beta1.MsgSetDenomMetadata',
value: setDenomMetadataMsg
},
...mintRawMsgs
],
'auto',
'Create a new token'
);

if (res.transactionHash) {
// find if the initBalances has address of creator
const balance = initBalances.find((init) => init.address === address.address);
// TODO: optimistic update here
dispatch<any>(
inspectToken({
tokenId: `factory/${TOKEN_FACTORY_CONTRACT}/${tokenSymbol}`,
address: oraiAddress,
isUserAdded: true
optimisticUpdateToken({
token: {
denom: `factory/${address.address}/${tokenSymbol}`,
name: tokenSymbol,
decimals: DEFAULT_COSMOS_DECIMALS,
org: tokenName.trim(),
icon: tokenLogoUrl,
iconLight: tokenLogoUrl,
bridgeTo: [],
chainId: network.chainId,
cosmosBased: true,
contractAddress: '',
coinType: OraichainNetworkConfig.coinType,
description: description,
feeCurrencies: network.feeCurrencies,
gasPriceStep: network.feeCurrencies[0].gasPriceStep,
rpc: network.rpc
},
balance: balance ? balance.amount.toString() : '0'
})
);
displayToast(TToastType.TX_SUCCESSFUL, {
Expand Down Expand Up @@ -347,18 +391,18 @@ const NewTokenModal: FC<ModalProps> = ({ isOpen, close, open }) => {
initBalances.map((item, ind) => {
return (
// <div key={ind}>
<InitBalancesItems
key={ind}
item={item}
ind={ind}
selectedInitBalances={selectedInitBalances}
setSelectedInitBalances={setSelectedInitBalances}
setInitBalances={setInitBalances}
initBalances={initBalances}
theme={theme}
decimals={DEFAULT_COSMOS_DECIMALS}
deleteSelectedItem={deleteSelectedItem}
/>
<InitBalancesItems
key={ind}
item={item}
ind={ind}
selectedInitBalances={selectedInitBalances}
setSelectedInitBalances={setSelectedInitBalances}
setInitBalances={setInitBalances}
initBalances={initBalances}
theme={theme}
decimals={DEFAULT_COSMOS_DECIMALS}
deleteSelectedItem={deleteSelectedItem}
/>
// </div>
);
})}
Expand Down
37 changes: 36 additions & 1 deletion src/reducer/onchainTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,20 @@ const initialState: OnchainTokensState = {
export const onchainTokensSlice = createSlice({
name: 'onchainTokens',
initialState,
reducers: {},
reducers: {

},
extraReducers: (builder) => {
builder.addCase(inspectToken.fulfilled, (state, action) => {
const { token } = action.payload;
state.tokens = [onChainTokenToTokenItem(token)];
state.allOnChainTokens = [...state.allOnChainTokens, onChainTokenToTokenItem(token)];
});
builder.addCase(optimisticUpdateToken.fulfilled, (state, action) => {
const { token } = action.payload;
state.tokens = [onChainTokenToTokenItem(token)];
state.allOnChainTokens = [...state.allOnChainTokens, onChainTokenToTokenItem(token)];
});
}
});

Expand All @@ -50,6 +57,34 @@ export const onChainTokenToTokenItem = (token: InspectedToken): TokenItemType =>
};
};

export const optimisticUpdateToken = createAsyncThunk(
'onchainTokens/optimisticUpdateToken',
async (
{
token,
balance
}: {
token: InspectedToken;
balance: string;
},
thunkAPI
) => {
thunkAPI.dispatch(
updateAmounts({
[token.denom]: balance
})
);

const tokenItem = onChainTokenToTokenItem(token);
thunkAPI.dispatch(updateAddedTokens([tokenItem]));

return {
token,
balance
};
}
)

export const inspectToken = createAsyncThunk(
'onchainTokens/inspectToken',
async (
Expand Down
29 changes: 24 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1769,6 +1769,13 @@
resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.4.tgz#a9a717c9fd7b1984d9cefdd0ef6c6f254060c671"
integrity sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w==

"@cosmology/lcd@^0.13.3":
version "0.13.5"
resolved "https://registry.yarnpkg.com/@cosmology/lcd/-/lcd-0.13.5.tgz#1bc4d43d525ecd68d09211d2ce17332a149a1a00"
integrity sha512-CI8KFsJcgp0RINF8wHpv3Y9yR4Fb9ZnGucyoUICjtX2XT4NVBK+fvZuRFj5TP34km8TpEOb+WV2T7IN/pZsD7Q==
dependencies:
axios "1.7.4"

"@dabh/diagnostics@^2.0.2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.3.tgz#7f7e97ee9a725dffc7808d93668cc984e1dc477a"
Expand Down Expand Up @@ -3930,10 +3937,10 @@
serialize-error "^8.1.0"
varuint-bitcoin "^1.1.2"

"@oraichain/orai-token-inspector@^0.1.24":
version "0.1.24"
resolved "https://registry.yarnpkg.com/@oraichain/orai-token-inspector/-/orai-token-inspector-0.1.24.tgz#79d64a20592db4d3b47e35358cf0a7641239eb01"
integrity sha512-0vaNfrV+X4GDZX+WlGMzf6RHNkg5lzLJ3WMA5GRCWvBez8rHwteAm1OHPRfqItlxx/I5Jatefyzzs7OFg4JU+g==
"@oraichain/orai-token-inspector@^0.1.25":
version "0.1.25"
resolved "https://registry.yarnpkg.com/@oraichain/orai-token-inspector/-/orai-token-inspector-0.1.25.tgz#c2ac2e2e19f6d55bcdd4be48e4b7364a0eff6bc2"
integrity sha512-z9DgFJU7QMGpn8Jz4kRfxsvTv4DlBJbtVtKv6ql8iXqpD93ZZXdvFrgbQJ45XsdCqL63CYrPu+a3lzPlpHFgdw==
dependencies:
"@keplr-wallet/types" "0.12.141"
"@metaplex-foundation/mpl-token-metadata" "^3.3.0"
Expand All @@ -3947,6 +3954,7 @@
"@ton-api/ton-adapter" "^0.3.0"
"@ton/core" "^0.59.0"
"@ton/ton" "^15.1.0"
bech32 "^2.0.0"
ethers "5.7.2"
ton-crypto "^3.2.0"

Expand Down Expand Up @@ -4043,6 +4051,17 @@
"@cosmjs/crypto" "0.32.4"
"@cosmjs/proto-signing" "0.32.4"

"@oraichain/proto@^0.0.7":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@oraichain/proto/-/proto-0.0.7.tgz#06b1642eea1b6df0696932dc286d37577d1a5355"
integrity sha512-kmL7Iunve5FEBKlXwlX97p0oix5dgKpLZhp0Bt6zd7CTqF3QANJUMbAPm1AAxkR4r4kkUMYarmjsDdolG6QPIQ==
dependencies:
"@cosmjs/amino" "^0.32.4"
"@cosmjs/proto-signing" "^0.32.4"
"@cosmjs/stargate" "^0.32.4"
"@cosmjs/tendermint-rpc" "^0.32.4"
"@cosmology/lcd" "^0.13.3"

"@oraichain/ton-bridge-contracts@^0.15.8":
version "0.15.9"
resolved "https://registry.yarnpkg.com/@oraichain/ton-bridge-contracts/-/ton-bridge-contracts-0.15.9.tgz#279f78ac434d5df69ccf2e51c01e57484789e91e"
Expand Down Expand Up @@ -8027,7 +8046,7 @@ [email protected]:
tslib "^2.1.0"
util "^0.12.3"

[email protected], [email protected], [email protected], [email protected], axios@^0.21.0, axios@^0.21.1, axios@^0.21.2, axios@^0.26.1, axios@^0.27.2, axios@^1.6.0, axios@^1.6.2, axios@^1.6.7, axios@^1.6.8:
[email protected], [email protected], [email protected], [email protected], axios@1.7.4, axios@^0.21.0, axios@^0.21.1, axios@^0.21.2, axios@^0.26.1, axios@^0.27.2, axios@^1.6.0, axios@^1.6.2, axios@^1.6.7, axios@^1.6.8:
version "0.26.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9"
integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==
Expand Down
Loading