diff --git a/sdk/typescript/docs/code-examples/wallet-connect-code.mdx b/sdk/typescript/docs/code-examples/wallet-connect-code.mdx new file mode 100644 index 0000000000..fb0d786d22 --- /dev/null +++ b/sdk/typescript/docs/code-examples/wallet-connect-code.mdx @@ -0,0 +1,75 @@ +```ts copy filename="FormattedWalletConnectCode.tsx" +import React from 'react'; +import { Coin } from '@cosmjs/stargate'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import TextField from '@mui/material/TextField'; + +export const ConnectWallet = ({ + setMnemonic, + connect, + mnemonic, + accountLoading, + clientLoading, + balanceLoading, + account, + balance, + connectButtonText, + }: { + setMnemonic: (value: string) => void; + connect: () => void; + mnemonic: string; + accountLoading: boolean; + clientLoading: boolean; + balanceLoading: boolean; + account: string; + balance: Coin; + connectButtonText: string; + }) => { + return ( + + + Connect to your account + + + Your account + + + Enter the mnemonic + + setMnemonic(e.target.value)} + fullWidth + multiline + maxRows={4} + sx={{ marginBottom: 3 }} + /> + + + {account && balance ? ( + + Address: {account} + + Balance: {balance?.amount} {balance?.denom} + + + ) : ( + + Please, enter your mnemonic to receive your account information + + )} + + + ); + }; +``` \ No newline at end of file diff --git a/sdk/typescript/docs/code-examples/wallet-delegations-code.mdx b/sdk/typescript/docs/code-examples/wallet-delegations-code.mdx new file mode 100644 index 0000000000..8d087615ff --- /dev/null +++ b/sdk/typescript/docs/code-examples/wallet-delegations-code.mdx @@ -0,0 +1,116 @@ +```ts copy filename="FormattedWalletDelegationsCode.tsx" +import React from 'react'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import Box from '@mui/material/Box'; +import { TableBody, TableCell, TableHead, TableRow, TextField, Typography } from '@mui/material'; +import Table from '@mui/material/Table'; + +export const Delegations = ({ + delegations, + setDelegationNodeId, + setAmountToBeDelegated, + amountToBeDelegated, + delegationNodeId, + doDelegate, + delegationLoader, + undeledationLoader, + doUndelegateAll, + doWithdrawRewards, + withdrawLoading, +}: { + delegations: any; + setDelegationNodeId: (value: string) => void; + setAmountToBeDelegated: (value: string) => void; + amountToBeDelegated: string; + delegationNodeId: string; + doDelegate: ({ mixId, amount }: { mixId: number; amount: number }) => void; + delegationLoader: boolean; + undeledationLoader: boolean; + doUndelegateAll: () => void; + doWithdrawRewards: () => void; + withdrawLoading: boolean; +}) => { + return ( + + + Delegations + + + + Make a delegation + + setDelegationNodeId(e.target.value)} + size="small" + /> + + setAmountToBeDelegated(e.target.value)} + size="small" + /> + + + + + + Your delegations + + {!delegations?.delegations?.length ? ( + You do not have delegations + ) : ( + + + + + MixId + Owner + Amount + Cumulative Reward Ratio + + + + {delegations?.delegations.map((delegation: any) => ( + + {delegation.mix_id} + {delegation.owner} + {delegation.amount.amount} + {delegation.cumulative_reward_ratio} + + ))} + +
+
+ )} +
+ {delegations && ( + + + + )} + + + +
+
+
+ ); +}; + +``` \ No newline at end of file diff --git a/sdk/typescript/docs/code-examples/wallet-example-code.mdx b/sdk/typescript/docs/code-examples/wallet-example-code.mdx deleted file mode 100644 index d7722cadd4..0000000000 --- a/sdk/typescript/docs/code-examples/wallet-example-code.mdx +++ /dev/null @@ -1,395 +0,0 @@ -```ts copy filename="WalletSigningClientExample.tsx" -import React, { useCallback, useEffect, useState } from 'react'; -import { contracts } from '@nymproject/contract-clients'; -import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'; -import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'; -import { Coin, GasPrice } from '@cosmjs/stargate'; -import Button from '@mui/material/Button'; -import Paper from '@mui/material/Paper'; -import Box from '@mui/material/Box'; -import { TableBody, TableCell, TableHead, TableRow, TextField, Typography } from '@mui/material'; -import Table from '@mui/material/Table'; -import { settings } from './client'; - -const signerAccount = async (mnemonic) => { - // create a wallet to sign transactions with the mnemonic - const signer = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { - prefix: 'n', - }); - - return signer; -}; - -const fetchSignerCosmosWasmClient = async (mnemonic: string) => { - const signer = await signerAccount(mnemonic); - - // create a signing client we don't need to set the gas price conversion for queries - const cosmWasmClient = await SigningCosmWasmClient.connectWithSigner(settings.url, signer, { - gasPrice: GasPrice.fromString('0.025unym'), - }); - - return cosmWasmClient; -}; - -const fetchSignerClient = async (mnemonic) => { - const signer = await signerAccount(mnemonic); - - // create a signing client we don't need to set the gas price conversion for queries - // if you want to connect without signer you'd write ".connect" and "url" as param - const cosmWasmClient = await SigningCosmWasmClient.connectWithSigner(settings.url, signer, { - gasPrice: GasPrice.fromString('0.025unym'), - }); - - /** create a mixnet contract client - * @param cosmWasmClient the client to use for signing and querying - * @param settings.address the bech32 address prefix (human readable part) - * @param settings.mixnetContractAddress the bech32 address prefix (human readable part) - * @returns the client in MixnetClient form - */ - - const mixnetClient = new contracts.Mixnet.MixnetClient( - cosmWasmClient, - settings.address, // sender (that account of the signer) - settings.mixnetContractAddress, // contract address (different on mainnet, QA, etc) - ); - - return mixnetClient; -}; - -export const Wallet = () => { - const [mnemonic, setMnemonic] = useState(); - const [signerCosmosWasmClient, setSignerCosmosWasmClient] = useState(); - const [signerClient, setSignerClient] = useState(); - const [account, setAccount] = useState(); - const [accountLoading, setAccountLoading] = useState(false); - const [clientLoading, setClientLoading] = useState(false); - const [balance, setBalance] = useState(); - const [balanceLoading, setBalanceLoading] = useState(false); - const [log, setLog] = useState([]); - const [tokensToSend, setTokensToSend] = useState(); - const [sendingTokensLoader, setSendingTokensLoader] = useState(false); - const [delegations, setDelegations] = useState(); - const [recipientAddress, setRecipientAddress] = useState(''); - const [delegationNodeId, setDelegationNodeId] = useState(); - const [amountToBeDelegated, setAmountToBeDelegated] = useState(); - const [delegationLoader, setDelegationLoader] = useState(false); - const [undeledationLoader, setUndeledationLoader] = useState(false); - const [withdrawLoading, setWithdrawLoading] = useState(false); - const [connectButtonText, setConnectButtonText] = useState('Connect'); - - const getBalance = useCallback(async () => { - setBalanceLoading(true); - try { - const newBalance = await signerCosmosWasmClient?.getBalance(account, 'unym'); - setBalance(newBalance); - } catch (error) { - console.error(error); - } - setBalanceLoading(false); - }, [account, signerCosmosWasmClient]); - - const getSignerAccount = async () => { - setAccountLoading(true); - try { - const signer = await signerAccount(mnemonic); - const accounts = await signer.getAccounts(); - if (accounts[0]) { - setAccount(accounts[0].address); - } - } catch (error) { - console.error(error); - } - setAccountLoading(false); - }; - - const getClients = async () => { - setClientLoading(true); - try { - setSignerCosmosWasmClient(await fetchSignerCosmosWasmClient(mnemonic)); - setSignerClient(await fetchSignerClient(mnemonic)); - } catch (error) { - console.error(error); - } - setClientLoading(false); - }; - - const getDelegations = useCallback(async () => { - const newDelegations = await signerClient.getDelegatorDelegations({ - delegator: settings.address, - }); - setDelegations(newDelegations); - }, [signerClient]); - - const connect = () => { - getSignerAccount(); - getClients(); - }; - - const doUndelegateAll = async () => { - if (!signerClient) { - return; - } - setUndeledationLoader(true); - try { - // eslint-disable-next-line no-restricted-syntax - for (const delegation of delegations.delegations) { - // eslint-disable-next-line no-await-in-loop - await signerClient.undelegateFromMixnode({ mixId: delegation.mix_id }, 'auto'); - } - } catch (error) { - console.error(error); - } - setUndeledationLoader(false); - }; - - const doDelegate = async ({ mixId, amount }: { mixId: number; amount: number }) => { - if (!signerClient) { - return; - } - setDelegationLoader(true); - try { - const res = await signerClient.delegateToMixnode({ mixId }, 'auto', undefined, [ - { amount: `${amount}`, denom: 'unym' }, - ]); - console.log('res', res); - setLog((prev) => [ - ...prev, -
- {new Date().toLocaleTimeString()} -
{JSON.stringify(res, null, 2)}
-
, - ]); - } catch (error) { - console.error(error); - } - setDelegationLoader(false); - }; - // End delegate - - // Sending tokens - const doSendTokens = async () => { - const memo = 'test sending tokens'; - setSendingTokensLoader(true); - try { - const res = await signerCosmosWasmClient.sendTokens( - account, - recipientAddress, - [{ amount: tokensToSend, denom: 'unym' }], - 'auto', - memo, - ); - setLog((prev) => [ - ...prev, -
- {new Date().toLocaleTimeString()} -
{JSON.stringify(res, null, 2)}
-
, - ]); - } catch (error) { - console.error(error); - } - setSendingTokensLoader(false); - }; - // End send tokens - - // Withdraw Rewards - const doWithdrawRewards = async () => { - const delegatorAddress = ''; - const validatorAdress = ''; - const memo = 'test sending tokens'; - setWithdrawLoading(true); - try { - const res = await signerCosmosWasmClient.withdrawRewards(delegatorAddress, validatorAdress, 'auto', memo); - setLog((prev) => [ - ...prev, -
- {new Date().toLocaleTimeString()} -
{JSON.stringify(res, null, 2)}
-
, - ]); - } catch (error) { - console.error(error); - } - setWithdrawLoading(false); - }; - - useEffect(() => { - if (account && signerCosmosWasmClient) { - if (!balance) { - setBalanceLoading(true); - getBalance(); - setBalanceLoading(false); - } - } - }, [account, signerCosmosWasmClient, balance, getBalance]); - - useEffect(() => { - if (signerClient && !delegations) { - console.log('getDelegations'); - getDelegations(); - } - }, [signerClient, getDelegations, delegations]); - - useEffect(() => { - if (accountLoading || clientLoading || balanceLoading) { - setConnectButtonText('Loading...'); - } else if (balance) { - setConnectButtonText('Connected'); - } - setConnectButtonText('Connect'); - }, [accountLoading, clientLoading, balanceLoading]); - - return ( - - - - Connect to your account - - - Your account - - - Enter the mnemonic - - setMnemonic(e.target.value)} - fullWidth - multiline - maxRows={4} - sx={{ marginBottom: 3 }} - /> - - - {account && balance ? ( - - Address: {account} - - Balance: {balance?.amount} {balance?.denom} - - - ) : ( - - Please, enter your mnemonic to receive your account information - - )} - - - - - Send Tokens - - setRecipientAddress(e.target.value)} - size="small" - /> - - setTokensToSend(e.target.value)} - size="small" - /> - - - - - - - - Delegations - - - - Make a delegation - - setDelegationNodeId(e.target.value)} - size="small" - /> - - setAmountToBeDelegated(e.target.value)} - size="small" - /> - - - - - - Your delegations - - {!delegations?.delegations?.length ? ( - You do not have delegations - ) : ( - - - - - MixId - Owner - Amount - Cumulative Reward Ratio - - - - {delegations?.delegations.map((delegation: any) => ( - - {delegation.mix_id} - {delegation.owner} - {delegation.amount.amount} - {delegation.cumulative_reward_ratio} - - ))} - -
-
- )} -
- {delegations && ( - - - - )} - - - -
-
-
- - - Transaction Logs: - {log} - -
- ); -}; -``` \ No newline at end of file diff --git a/sdk/typescript/docs/code-examples/wallet-sendTokens-code.mdx b/sdk/typescript/docs/code-examples/wallet-sendTokens-code.mdx new file mode 100644 index 0000000000..44a36c05de --- /dev/null +++ b/sdk/typescript/docs/code-examples/wallet-sendTokens-code.mdx @@ -0,0 +1,47 @@ +```ts copy filename="FormattedWalletSendTokensCode.tsx" +import React from 'react'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import TextField from '@mui/material/TextField'; + +export const SendTokes = ({ + setRecipientAddress, + setTokensToSend, + doSendTokens, + sendingTokensLoader, +}: { + setRecipientAddress: (value: string) => void; + setTokensToSend: (value: string) => void; + doSendTokens: () => void; + sendingTokensLoader: boolean; +}) => { + return ( + + + Send Tokens + + setRecipientAddress(e.target.value)} + size="small" + /> + + setTokensToSend(e.target.value)} + size="small" + /> + + + + + + ); +}; +``` \ No newline at end of file diff --git a/sdk/typescript/docs/components/wallet.tsx b/sdk/typescript/docs/components/wallet.tsx index 1691d103dd..4c654d4662 100644 --- a/sdk/typescript/docs/components/wallet.tsx +++ b/sdk/typescript/docs/components/wallet.tsx @@ -3,12 +3,12 @@ import { contracts } from '@nymproject/contract-clients'; import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'; import { DirectSecp256k1HdWallet } from '@cosmjs/proto-signing'; import { Coin, GasPrice } from '@cosmjs/stargate'; -import Button from '@mui/material/Button'; -import Paper from '@mui/material/Paper'; import Box from '@mui/material/Box'; -import { TableBody, TableCell, TableHead, TableRow, TextField, Typography } from '@mui/material'; -import Table from '@mui/material/Table'; +import Typography from '@mui/material/Typography'; import { settings } from './client'; +import { ConnectWallet } from './wallet/connect'; +import { SendTokes } from './wallet/sendTokens'; +import { Delegations } from './wallet/delegations'; const signerAccount = async (mnemonic) => { // create a wallet to sign transactions with the mnemonic @@ -55,7 +55,7 @@ const fetchSignerClient = async (mnemonic) => { return mixnetClient; }; -export const Wallet = () => { +export const Wallet = ({ type }: { type: 'connect' | 'sendTokens' | 'delegations' }) => { const [mnemonic, setMnemonic] = useState(); const [signerCosmosWasmClient, setSignerCosmosWasmClient] = useState(); const [signerClient, setSignerClient] = useState(); @@ -240,154 +240,48 @@ export const Wallet = () => { return ( - - - Connect to your account - - - Your account - - - Enter the mnemonic - - setMnemonic(e.target.value)} - fullWidth - multiline - maxRows={4} - sx={{ marginBottom: 3 }} - /> - - - {account && balance ? ( - - Address: {account} - - Balance: {balance?.amount} {balance?.denom} - - - ) : ( - - Please, enter your mnemonic to receive your account information - - )} + {type === 'connect' && ( + + )} + {type === 'sendTokens' && ( + + )} + {type === 'delegations' && ( + + )} + {log.length > 0 && ( + + Transaction Logs: + {log} - - - - Send Tokens - - setRecipientAddress(e.target.value)} - size="small" - /> - - setTokensToSend(e.target.value)} - size="small" - /> - - - - - - - - Delegations - - - - Make a delegation - - setDelegationNodeId(e.target.value)} - size="small" - /> - - setAmountToBeDelegated(e.target.value)} - size="small" - /> - - - - - - Your delegations - - {!delegations?.delegations?.length ? ( - You do not have delegations - ) : ( - - - - - MixId - Owner - Amount - Cumulative Reward Ratio - - - - {delegations?.delegations.map((delegation: any) => ( - - {delegation.mix_id} - {delegation.owner} - {delegation.amount.amount} - {delegation.cumulative_reward_ratio} - - ))} - -
-
- )} -
- {delegations && ( - - - - )} - - - -
-
-
- - - Transaction Logs: - {log} - + )}
); }; diff --git a/sdk/typescript/docs/components/wallet/connect.tsx b/sdk/typescript/docs/components/wallet/connect.tsx new file mode 100644 index 0000000000..c15f148884 --- /dev/null +++ b/sdk/typescript/docs/components/wallet/connect.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { Coin } from '@cosmjs/stargate'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import TextField from '@mui/material/TextField'; + +export const ConnectWallet = ({ + setMnemonic, + connect, + mnemonic, + accountLoading, + clientLoading, + balanceLoading, + account, + balance, + connectButtonText, + }: { + setMnemonic: (value: string) => void; + connect: () => void; + mnemonic: string; + accountLoading: boolean; + clientLoading: boolean; + balanceLoading: boolean; + account: string; + balance: Coin; + connectButtonText: string; + }) => { + return ( + + + Connect to your account + + + Your account + + + Enter the mnemonic + + setMnemonic(e.target.value)} + fullWidth + multiline + maxRows={4} + sx={{ marginBottom: 3 }} + /> + + + {account && balance ? ( + + Address: {account} + + Balance: {balance?.amount} {balance?.denom} + + + ) : ( + + Please, enter your mnemonic to receive your account information + + )} + + + ); + }; + \ No newline at end of file diff --git a/sdk/typescript/docs/components/wallet/delegations.tsx b/sdk/typescript/docs/components/wallet/delegations.tsx new file mode 100644 index 0000000000..03d32d8edd --- /dev/null +++ b/sdk/typescript/docs/components/wallet/delegations.tsx @@ -0,0 +1,113 @@ +import React from 'react'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import Box from '@mui/material/Box'; +import { TableBody, TableCell, TableHead, TableRow, TextField, Typography } from '@mui/material'; +import Table from '@mui/material/Table'; + +export const Delegations = ({ + delegations, + setDelegationNodeId, + setAmountToBeDelegated, + amountToBeDelegated, + delegationNodeId, + doDelegate, + delegationLoader, + undeledationLoader, + doUndelegateAll, + doWithdrawRewards, + withdrawLoading, +}: { + delegations: any; + setDelegationNodeId: (value: string) => void; + setAmountToBeDelegated: (value: string) => void; + amountToBeDelegated: string; + delegationNodeId: string; + doDelegate: ({ mixId, amount }: { mixId: number; amount: number }) => void; + delegationLoader: boolean; + undeledationLoader: boolean; + doUndelegateAll: () => void; + doWithdrawRewards: () => void; + withdrawLoading: boolean; +}) => { + return ( + + + Delegations + + + + Make a delegation + + setDelegationNodeId(e.target.value)} + size="small" + /> + + setAmountToBeDelegated(e.target.value)} + size="small" + /> + + + + + + Your delegations + + {!delegations?.delegations?.length ? ( + You do not have delegations + ) : ( + + + + + MixId + Owner + Amount + Cumulative Reward Ratio + + + + {delegations?.delegations.map((delegation: any) => ( + + {delegation.mix_id} + {delegation.owner} + {delegation.amount.amount} + {delegation.cumulative_reward_ratio} + + ))} + +
+
+ )} +
+ {delegations && ( + + + + )} + + + +
+
+
+ ); +}; diff --git a/sdk/typescript/docs/components/wallet/index.ts b/sdk/typescript/docs/components/wallet/index.ts new file mode 100644 index 0000000000..89ecc6b6ee --- /dev/null +++ b/sdk/typescript/docs/components/wallet/index.ts @@ -0,0 +1,3 @@ +export { ConnectWallet } from './connect'; +export { SendTokes } from './sendTokens'; +export { Delegations } from './delegations'; \ No newline at end of file diff --git a/sdk/typescript/docs/components/wallet/sendTokens.tsx b/sdk/typescript/docs/components/wallet/sendTokens.tsx new file mode 100644 index 0000000000..452fe5e4e0 --- /dev/null +++ b/sdk/typescript/docs/components/wallet/sendTokens.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import TextField from '@mui/material/TextField'; + +export const SendTokes = ({ + setRecipientAddress, + setTokensToSend, + doSendTokens, + sendingTokensLoader, +}: { + setRecipientAddress: (value: string) => void; + setTokensToSend: (value: string) => void; + doSendTokens: () => void; + sendingTokensLoader: boolean; +}) => { + return ( + + + Send Tokens + + setRecipientAddress(e.target.value)} + size="small" + /> + + setTokensToSend(e.target.value)} + size="small" + /> + + + + + + ); +}; \ No newline at end of file diff --git a/sdk/typescript/docs/pages/playground/wallet.mdx b/sdk/typescript/docs/pages/playground/wallet.mdx index 7ceaa1c26d..c5bc5c634e 100644 --- a/sdk/typescript/docs/pages/playground/wallet.mdx +++ b/sdk/typescript/docs/pages/playground/wallet.mdx @@ -2,10 +2,18 @@ import { Wallet } from '../../components/wallet'; import Box from '@mui/material/Box'; -import FormattedWalletExampleCode from '../../code-examples/wallet-example-code.mdx'; +import FormattedWalletConnectCode from '../../code-examples/wallet-connect-code.mdx'; +import FormattedWalletSendTokensCode from '../../code-examples/wallet-sendTokens-code.mdx'; +import FormattedWalletDelegationsCode from '../../code-examples/wallet-delegations-code.mdx'; Here's a small wallet example for you to test out! - - \ No newline at end of file + + + + + + + + \ No newline at end of file