mars-v2-frontend/pages/index.tsx
Gustavo Mauricio f709c12da2
Tooling improvements and minor refactor (#19)
* refactor: store selector callbacks less verbose

* chore: prettier tailwind plugin added and respective formatting

* disable metamask connection button
2022-09-30 13:50:16 +01:00

338 lines
9.3 KiB
TypeScript

import React, { useEffect, useState } from 'react'
import type { NextPage } from 'next'
// import Head from "next/head";
// import Image from "next/image";
// import styles from "../styles/Home.module.css";
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
// import { Coin } from "@cosmjs/stargate";
import { toast } from 'react-toastify'
import BigNumber from 'bignumber.js'
import { useQueryClient } from '@tanstack/react-query'
import Container from 'components/Container'
import Button from 'components/Button'
import useWalletStore from 'stores/useWalletStore'
import { chain } from 'utils/chains'
import { contractAddresses } from 'config/contracts'
import { hardcodedFee } from 'utils/contants'
import Spinner from 'components/Spinner'
import useCreditManagerStore from 'stores/useCreditManagerStore'
import { queryKeys } from 'types/query-keys-factory'
const Home: NextPage = () => {
const [sendAmount, setSendAmount] = useState('')
const [recipientAddress, setRecipientAddress] = useState('')
const [allTokens, setAllTokens] = useState<string[] | null>(null)
const [walletTokens, setWalletTokens] = useState<string[] | null>(null)
const [borrowAmount, setBorrowAmount] = useState(0)
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(false)
const address = useWalletStore((s) => s.address)
const selectedAccount = useCreditManagerStore((s) => s.selectedAccount)
const queryClient = useQueryClient()
const [signingClient, setSigningClient] = useState<SigningCosmWasmClient>()
useEffect(() => {
;(async () => {
if (!window.keplr) return
const offlineSigner = window.keplr.getOfflineSigner(chain.chainId)
const clientInstance = await SigningCosmWasmClient.connectWithSigner(chain.rpc, offlineSigner)
setSigningClient(clientInstance)
})()
}, [address])
const handleSendClick = async () => {
setError(null)
setIsLoading(true)
try {
// console.log(await signingClient.getHeight());
// console.log(
// "contract info",
// signingClient.getContract(
// "osmo1zf26ahe5gqjtvnedh7ems7naf2wtw3z4ll6atf3t0hptal8ss4vq2mlx6w"
// )
// );
const res = await signingClient?.sendTokens(
address,
recipientAddress,
[
{
denom: chain.stakeCurrency.coinMinimalDenom,
amount: BigNumber(sendAmount)
.times(10 ** chain.stakeCurrency.coinDecimals)
.toString(),
},
],
hardcodedFee
)
console.log('txResponse', res)
toast.success(
<div>
<a
href={`https://testnet.mintscan.io/osmosis-testnet/txs/${res?.transactionHash}`}
target="_blank"
rel="noreferrer"
>
Check transaction
</a>
</div>,
{ autoClose: false }
)
} catch (e: any) {
console.log(e)
setError(e.message)
} finally {
setIsLoading(false)
}
}
const handleCreateCreditAccount = async () => {
setError(null)
setIsLoading(true)
try {
// 200000 gas used
const executeMsg = {
create_credit_account: {},
}
const createResult = await signingClient?.execute(
address,
contractAddresses.creditManager,
executeMsg,
hardcodedFee
)
console.log('mint result', createResult)
toast.success(
<div>
<a
href={`https://testnet.mintscan.io/osmosis-testnet/txs/${createResult?.transactionHash}`}
target="_blank"
rel="noreferrer"
>
Check transaction
</a>
</div>,
{ autoClose: false }
)
queryClient.invalidateQueries(queryKeys.creditAccounts(address))
} catch (e: any) {
console.log(e)
setError(e.message)
} finally {
setIsLoading(false)
}
}
// https://github.com/mars-protocol/rover/blob/master/scripts/types/generated/account-nft/AccountNft.types.ts
const handleGetCreditAccounts = async () => {
setError(null)
setIsLoading(true)
try {
const allTokensQueryMsg = {
all_tokens: {},
}
const allTokensResponse = await signingClient?.queryContractSmart(
contractAddresses.accountNft,
allTokensQueryMsg
)
setAllTokens(allTokensResponse.tokens)
console.log('all tokens', allTokensResponse)
// Returns de owner of a specific "credit account"
// const ownerOfQueryMsg = {
// owner_of: {
// include_expired: false,
// token_id: "1",
// },
// };
// const ownerResponse = await signingClient.queryContractSmart(
// contractAddresses.accountNft,
// ownerOfQueryMsg
// );
// console.log("res owner", ownerResponse);
const tokensQueryMsg = {
tokens: {
owner: address,
},
}
const tokensResponse = await signingClient?.queryContractSmart(
contractAddresses.accountNft,
tokensQueryMsg
)
console.log('res tokens', tokensResponse)
setWalletTokens(tokensResponse.tokens)
} catch (e: any) {
console.log(e)
setError(e.message)
} finally {
setIsLoading(false)
}
}
const handleBorrowClick = async () => {
setError(null)
setIsLoading(true)
try {
if (!selectedAccount) return
const executeMsg = {
update_credit_account: {
account_id: selectedAccount,
actions: [
{
borrow: {
denom: 'uosmo',
amount: BigNumber(borrowAmount)
.times(10 ** 6)
.toString(),
},
},
],
},
}
const borrowResult = await signingClient?.execute(
address,
contractAddresses.creditManager,
executeMsg,
hardcodedFee
)
console.log('borrow result', borrowResult)
toast.success(
<div>
<a
href={`https://testnet.mintscan.io/osmosis-testnet/txs/${borrowResult?.transactionHash}`}
target="_blank"
rel="noreferrer"
>
Check transaction
</a>
</div>,
{ autoClose: false }
)
queryClient.invalidateQueries(queryKeys.creditAccounts(address))
queryClient.invalidateQueries(queryKeys.creditAccountsPositions(selectedAccount))
queryClient.invalidateQueries(queryKeys.tokenBalance(address, 'uosmo'))
} catch (e: any) {
console.log(e)
setError(e.message)
} finally {
setIsLoading(false)
}
}
return (
<div className="mx-auto flex max-w-6xl flex-col gap-y-6">
<Container>
<h4 className="mb-5 text-xl">Send Tokens</h4>
<div className="mb-5 flex flex-wrap gap-2">
<div>
<p>Address:</p>
<input
className="rounded-lg bg-black/40 px-3 py-1"
value={recipientAddress}
placeholder="address"
onChange={(e) => setRecipientAddress(e.target.value)}
/>
</div>
<div>
<p>Amount:</p>
<input
type="number"
className="rounded-lg bg-black/40 px-3 py-1"
value={sendAmount}
placeholder="amount"
onChange={(e) => setSendAmount(e.target.value)}
/>
</div>
</div>
<Button className="bg-[#524bb1] hover:bg-[#6962cc]" onClick={handleSendClick}>
Send
</Button>
</Container>
<Container>
<h4 className="mb-5 text-xl">Create Credit Account (Mint NFT)</h4>
<Button className="bg-[#524bb1] hover:bg-[#6962cc]" onClick={handleCreateCreditAccount}>
Create
</Button>
</Container>
<Container>
<h4 className="mb-5 text-xl">Get all Credit Accounts</h4>
<Button className="bg-[#524bb1] hover:bg-[#6962cc]" onClick={handleGetCreditAccounts}>
Fetch
</Button>
</Container>
<Container>
<h4 className="mb-5 text-xl">Borrow OSMO</h4>
<input
className="rounded-lg bg-black/40 px-3 py-1"
type="number"
onChange={(e) => setBorrowAmount(e.target.valueAsNumber)}
/>
<Button className="ml-4 bg-[#524bb1] hover:bg-[#6962cc]" onClick={handleBorrowClick}>
Borrow
</Button>
</Container>
<div>
{allTokens && (
<div className="mb-4">
<div className="flex items-end">
<h5 className="text-xl font-medium">All Tokens</h5>
<p className="ml-2 text-sm">- {allTokens.length} total</p>
</div>
{allTokens.map((token) => (
<p key={token}>{token}</p>
))}
</div>
)}
{walletTokens && (
<>
<div className="flex items-end">
<h5 className="text-xl font-medium">Your Tokens</h5>
<p className="ml-2 text-sm">- {walletTokens.length} total</p>
</div>
{walletTokens.map((token) => (
<p key={token}>{token}</p>
))}
</>
)}
</div>
{error && <div className="mt-8 bg-white p-4 text-red-500">{error}</div>}
{isLoading && (
<div>
<Spinner />
</div>
)}
</div>
)
}
export default Home