Use Cosmos Kit with Keplr Extension support.

This commit is contained in:
Noah Saso 2023-10-11 16:36:14 -07:00
parent 8b1c9e669d
commit dfe0a27f77
85 changed files with 1776 additions and 1004 deletions

View File

@ -1,6 +1,5 @@
import { toUtf8 } from '@cosmjs/encoding'
import clsx from 'clsx'
import { useWallet } from 'contexts/wallet'
import React, { useState } from 'react'
import { toast } from 'react-hot-toast'
import { SG721_NAME_ADDRESS } from 'utils/constants'
@ -8,6 +7,7 @@ import { csvToArray } from 'utils/csvToArray'
import type { AirdropAllocation } from 'utils/isValidAccountsFile'
import { isValidAccountsFile } from 'utils/isValidAccountsFile'
import { isValidAddress } from 'utils/isValidAddress'
import { useWallet } from 'utils/wallet'
interface AirdropUploadProps {
onChange: (data: AirdropAllocation[]) => void
@ -22,8 +22,10 @@ export const AirdropUpload = ({ onChange }: AirdropUploadProps) => {
await new Promise((resolve) => {
let i = 0
allocationData.map(async (data) => {
if (!wallet.client) throw new Error('Wallet not connected')
await wallet.client
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -5,8 +5,8 @@ import { toUtf8 } from '@cosmjs/encoding'
import clsx from 'clsx'
import React, { useState } from 'react'
import { toast } from 'react-hot-toast'
import { useWallet } from 'utils/wallet'
import { useWallet } from '../contexts/wallet'
import { SG721_NAME_ADDRESS } from '../utils/constants'
import { isValidAddress } from '../utils/isValidAddress'
@ -22,8 +22,10 @@ export const BadgeAirdropListUpload = ({ onChange }: BadgeAirdropListUploadProps
await new Promise((resolve) => {
let i = 0
names.map(async (name) => {
if (!wallet.client) throw new Error('Wallet not connected')
await wallet.client
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -6,13 +6,13 @@ import { Anchor } from 'components/Anchor'
import type { Timezone } from 'contexts/globalSettings'
import { setTimezone } from 'contexts/globalSettings'
import { setLogItemList, useLogStore } from 'contexts/log'
import { useWallet } from 'contexts/wallet'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { FaCog } from 'react-icons/fa'
// import BrandText from 'public/brand/brand-text.svg'
import { footerLinks, socialsLinks } from 'utils/links'
import { useWallet } from 'utils/wallet'
import { BADGE_HUB_ADDRESS, BASE_FACTORY_ADDRESS, NETWORK, OPEN_EDITION_FACTORY_ADDRESS } from '../utils/constants'
import { Conditional } from './Conditional'
@ -268,7 +268,7 @@ export const Sidebar = () => {
</label>
</div>
{/* Stargaze network status */}
<div className="text-sm capitalize">Network: {wallet.network}</div>
<div className="text-sm capitalize">Network: {wallet.chain.pretty_name}</div>
{/* footer reference links */}
<ul className="text-sm list-disc list-inside">

View File

@ -1,36 +1,61 @@
import type { Coin } from '@cosmjs/proto-signing'
import { Popover, Transition } from '@headlessui/react'
import clsx from 'clsx'
import { useWallet, useWalletStore } from 'contexts/wallet'
import { Fragment } from 'react'
import { Fragment, useEffect, useState } from 'react'
import { FaCopy, FaPowerOff, FaRedo } from 'react-icons/fa'
import { copy } from 'utils/clipboard'
import { convertDenomToReadable } from 'utils/convertDenomToReadable'
import { getShortAddress } from 'utils/getShortAddress'
import { useWallet } from 'utils/wallet'
import { WalletButton } from './WalletButton'
import { WalletPanelButton } from './WalletPanelButton'
export const WalletLoader = () => {
const { address, balance, connect, disconnect, initializing: isLoading, initialized: isReady } = useWallet()
const {
address = '',
username,
connect,
disconnect,
isWalletConnecting,
isWalletConnected,
getStargateClient,
} = useWallet()
const displayName = useWalletStore((store) => store.name || getShortAddress(store.address))
// Once wallet connects, load balances.
const [balances, setBalances] = useState<readonly Coin[] | undefined>()
useEffect(() => {
if (!isWalletConnected) {
setBalances(undefined)
return
}
const loadBalances = async () => {
const client = await getStargateClient()
setBalances(await client.getAllBalances(address))
}
loadBalances().catch(console.error)
}, [isWalletConnected, getStargateClient, address])
return (
<Popover className="mt-4 mb-2">
{({ close }) => (
<>
<div className="grid -mx-4">
{!isReady && (
<WalletButton className="w-full" isLoading={isLoading} onClick={() => void connect()}>
{isWalletConnected ? (
<Popover.Button as={WalletButton} className="w-full">
{username || address}
</Popover.Button>
) : (
<WalletButton
className="w-full"
isLoading={isWalletConnecting}
onClick={() => void connect().catch(console.error)}
>
Connect Wallet
</WalletButton>
)}
{isReady && (
<Popover.Button as={WalletButton} className="w-full" isLoading={isLoading}>
{displayName}
</Popover.Button>
)}
</div>
<Transition
@ -54,7 +79,7 @@ export const WalletLoader = () => {
{getShortAddress(address)}
</span>
<div className="font-bold">Your Balances</div>
{balance.map((val) => (
{balances?.map((val) => (
<span key={`balance-${val.denom}`}>
{convertDenomToReadable(val.amount)} {val.denom.slice(1, val.denom.length)}
</span>

View File

@ -0,0 +1,31 @@
// Styles required for @cosmos-kit/react modal
import '@interchain-ui/react/styles'
import { GasPrice } from '@cosmjs/stargate'
import { wallets as keplrExtensionWallets } from '@cosmos-kit/keplr-extension'
import { ChainProvider } from '@cosmos-kit/react'
import { assets, chains } from 'chain-registry'
import { getConfig } from 'config'
import type { ReactNode } from 'react'
import { NETWORK } from 'utils/constants'
export const WalletProvider = ({ children }: { children: ReactNode }) => {
const { gasPrice, feeToken } = getConfig(NETWORK)
return (
<ChainProvider
assetLists={assets}
chains={chains}
signerOptions={{
signingCosmwasm: () => ({
gasPrice: GasPrice.fromString(`${gasPrice}${feeToken}`),
}),
signingStargate: () => ({
gasPrice: GasPrice.fromString(`${gasPrice}${feeToken}`),
}),
}}
wallets={keplrExtensionWallets}
>
{children}
</ChainProvider>
)
}

View File

@ -1,12 +1,12 @@
import { toUtf8 } from '@cosmjs/encoding'
import clsx from 'clsx'
import { useWallet } from 'contexts/wallet'
import React, { useState } from 'react'
import { toast } from 'react-hot-toast'
import { SG721_NAME_ADDRESS } from 'utils/constants'
import { csvToFlexList } from 'utils/csvToFlexList'
import { isValidAddress } from 'utils/isValidAddress'
import { isValidFlexListFile } from 'utils/isValidFlexListFile'
import { useWallet } from 'utils/wallet'
export interface WhitelistFlexMember {
address: string
@ -26,8 +26,10 @@ export const WhitelistFlexUpload = ({ onChange }: WhitelistFlexUploadProps) => {
await new Promise((resolve) => {
let i = 0
memberData.map(async (data) => {
if (!wallet.client) throw new Error('Wallet not connected')
await wallet.client
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -5,8 +5,8 @@ import { toUtf8 } from '@cosmjs/encoding'
import clsx from 'clsx'
import React, { useState } from 'react'
import { toast } from 'react-hot-toast'
import { useWallet } from 'utils/wallet'
import { useWallet } from '../contexts/wallet'
import { SG721_NAME_ADDRESS } from '../utils/constants'
import { isValidAddress } from '../utils/isValidAddress'
@ -22,8 +22,10 @@ export const WhitelistUpload = ({ onChange }: WhitelistUploadProps) => {
await new Promise((resolve) => {
let i = 0
names.map(async (name) => {
if (!wallet.client) throw new Error('Wallet not connected')
await wallet.client
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -20,7 +20,6 @@ import { useMetadataAttributesState } from 'components/forms/MetadataAttributes.
import { JsonPreview } from 'components/JsonPreview'
import { TransactionHash } from 'components/TransactionHash'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useWallet } from 'contexts/wallet'
import type { Badge, BadgeHubInstance } from 'contracts/badgeHub'
import sizeof from 'object-sizeof'
import type { FormEvent } from 'react'
@ -32,6 +31,7 @@ import * as secp256k1 from 'secp256k1'
import { generateKeyPairs, sha256 } from 'utils/hash'
import { isValidAddress } from 'utils/isValidAddress'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import { BadgeAirdropListUpload } from '../../BadgeAirdropListUpload'
import { AddressInput, NumberInput, TextInput } from '../../forms/FormInput'
@ -266,7 +266,7 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
nft: nftState.value,
badgeHubMessages,
badgeHubContract: badgeHubContractAddress,
txSigner: wallet.address,
txSigner: wallet.address || '',
type,
}
@ -397,7 +397,7 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
const { isLoading, mutate } = useMutation(
async (event: FormEvent) => {
if (!wallet.client) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
event.preventDefault()
@ -412,8 +412,10 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
throw new Error('Please enter a valid private key.')
}
if (wallet.client && type === 'edit_badge') {
const feeRateRaw = await wallet.client.queryContractRaw(
if (type === 'edit_badge') {
const feeRateRaw = await (
await wallet.getCosmWasmClient()
).queryContractRaw(
badgeHubContractAddress,
toUtf8(Buffer.from(Buffer.from('fee_rate').toString('hex'), 'hex').toString()),
)
@ -421,7 +423,9 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
await toast
.promise(
wallet.client.queryContractSmart(badgeHubContractAddress, {
(
await wallet.getCosmWasmClient()
).queryContractSmart(badgeHubContractAddress, {
badge: { id: badgeId },
}),
{

View File

@ -12,12 +12,12 @@ import { useInputState, useNumberInputState } from 'components/forms/FormInput.h
import { useMetadataAttributesState } from 'components/forms/MetadataAttributes.hooks'
import { InputDateTime } from 'components/InputDateTime'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { Trait } from 'contracts/badgeHub'
import type { ChangeEvent } from 'react'
import { useEffect, useRef, useState } from 'react'
import { toast } from 'react-hot-toast'
import { BADGE_HUB_ADDRESS } from 'utils/constants'
import { useWallet } from 'utils/wallet'
import { AddressInput, NumberInput, TextInput } from '../../forms/FormInput'
import { MetadataAttributes } from '../../forms/MetadataAttributes'
@ -47,7 +47,7 @@ export interface BadgeDetailsDataProps {
}
export const BadgeDetails = ({ metadataSize, onChange, uploadMethod }: BadgeDetailsProps) => {
const wallet = useWallet()
const { address = '', isWalletConnected, getCosmWasmClient } = useWallet()
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [transferrable, setTransferrable] = useState<boolean>(false)
@ -61,7 +61,7 @@ export const BadgeDetails = ({ metadataSize, onChange, uploadMethod }: BadgeDeta
name: 'manager',
title: 'Manager',
subtitle: 'Badge Hub Manager',
defaultValue: wallet.address ? wallet.address : '',
defaultValue: address,
})
const nameState = useInputState({
@ -247,8 +247,10 @@ export const BadgeDetails = ({ metadataSize, onChange, uploadMethod }: BadgeDeta
useEffect(() => {
const retrieveFeeRate = async () => {
try {
if (wallet.client) {
const feeRateRaw = await wallet.client.queryContractRaw(
if (isWalletConnected) {
const feeRateRaw = await (
await getCosmWasmClient()
).queryContractRaw(
BADGE_HUB_ADDRESS,
toUtf8(Buffer.from(Buffer.from('fee_rate').toString('hex'), 'hex').toString()),
)
@ -263,7 +265,7 @@ export const BadgeDetails = ({ metadataSize, onChange, uploadMethod }: BadgeDeta
}
}
void retrieveFeeRate()
}, [wallet.client])
}, [isWalletConnected, getCosmWasmClient])
return (
<div>

View File

@ -10,7 +10,6 @@ import type { BadgeHubInstance } from 'contracts/badgeHub'
import { toast } from 'react-hot-toast'
import { useQuery } from 'react-query'
import { useWallet } from '../../../contexts/wallet'
import type { MintRule } from '../creation/ImageUploadDetails'
interface BadgeQueriesProps {
@ -20,8 +19,6 @@ interface BadgeQueriesProps {
mintRule: MintRule
}
export const BadgeQueries = ({ badgeHubContractAddress, badgeId, badgeHubMessages, mintRule }: BadgeQueriesProps) => {
const wallet = useWallet()
const comboboxState = useQueryComboboxState()
const type = comboboxState.value?.id

View File

@ -18,7 +18,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { Tooltip } from 'components/Tooltip'
import { TransactionHash } from 'components/TransactionHash'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { BaseMinterInstance } from 'contracts/baseMinter'
import type { OpenEditionMinterInstance } from 'contracts/openEditionMinter'
import type { RoyaltyRegistryInstance } from 'contracts/royaltyRegistry'
@ -32,6 +31,7 @@ import { useMutation } from 'react-query'
import { ROYALTY_REGISTRY_ADDRESS } from 'utils/constants'
import type { AirdropAllocation } from 'utils/isValidAccountsFile'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import type { CollectionInfo } from '../../../contracts/sg721/contract'
import { TextInput } from '../../forms/FormInput'
@ -246,7 +246,7 @@ export const CollectionActions = ({
recipient: resolvedRecipientAddress,
recipients: airdropArray,
tokenRecipients: airdropAllocationArray,
txSigner: wallet.address,
txSigner: wallet.address || '',
type,
price: priceState.value.toString(),
baseUri: baseURIState.value.trim().endsWith('/')
@ -335,13 +335,15 @@ export const CollectionActions = ({
throw new Error('Please enter minter and sg721 contract addresses!')
}
if (wallet.client && type === 'update_mint_price') {
const contractConfig = wallet.client.queryContractSmart(minterContractAddress, {
if (wallet.isWalletConnected && type === 'update_mint_price') {
const contractConfig = (await wallet.getCosmWasmClient()).queryContractSmart(minterContractAddress, {
config: {},
})
await toast
.promise(
wallet.client.queryContractSmart(minterContractAddress, {
(
await wallet.getCosmWasmClient()
).queryContractSmart(minterContractAddress, {
mint_price: {},
}),
{
@ -373,7 +375,9 @@ export const CollectionActions = ({
})
} else {
await contractConfig.then(async (config) => {
const factoryParameters = await wallet.client?.queryContractSmart(config.factory, {
const factoryParameters = await (
await wallet.getCosmWasmClient()
).queryContractSmart(config.factory, {
params: {},
})
if (
@ -403,8 +407,8 @@ export const CollectionActions = ({
royaltyPaymentAddressState.value &&
!royaltyPaymentAddressState.value.trim().endsWith('.stars')
) {
const contractInfoResponse = await wallet.client
?.queryContractRaw(
const contractInfoResponse = await (await wallet.getCosmWasmClient())
.queryContractRaw(
royaltyPaymentAddressState.value.trim(),
toUtf8(Buffer.from(Buffer.from('contract_info').toString('hex'), 'hex').toString()),
)

View File

@ -8,10 +8,10 @@ import clsx from 'clsx'
import { Alert } from 'components/Alert'
import { Conditional } from 'components/Conditional'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useWallet } from 'contexts/wallet'
import React, { useCallback, useEffect, useState } from 'react'
import { toast } from 'react-hot-toast'
import { API_URL } from 'utils/constants'
import { useWallet } from 'utils/wallet'
import { useDebounce } from '../../../utils/debounce'
import { TextInput } from '../../forms/FormInput'
@ -56,7 +56,7 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
const fetchMinterContracts = async (): Promise<MinterInfo[]> => {
const contracts: MinterInfo[] = await axios
.get(`${API_URL}/api/v1beta/collections/${wallet.address}`)
.get(`${API_URL}/api/v1beta/collections/${wallet.address || ''}`)
.then((response) => {
const collectionData = response.data
const minterContracts = collectionData.map((collection: any) => {
@ -70,8 +70,8 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
}
async function getMinterContractType(minterContractAddress: string) {
if (wallet.client && minterContractAddress.length > 0) {
const client = wallet.client
if (wallet.isWalletConnected && minterContractAddress.length > 0) {
const client = await wallet.getCosmWasmClient()
const data = await client.queryContractRaw(
minterContractAddress,
toUtf8(Buffer.from(Buffer.from('contract_info').toString('hex'), 'hex').toString()),
@ -129,8 +129,10 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
const fetchSg721Address = async () => {
if (debouncedExistingBaseMinterContract.length === 0) return
await wallet.client
?.queryContractSmart(debouncedExistingBaseMinterContract, {
await (
await wallet.getCosmWasmClient()
)
.queryContractSmart(debouncedExistingBaseMinterContract, {
config: {},
})
.then((response) => {
@ -145,8 +147,10 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
const fetchCollectionTokenCount = async () => {
if (selectedCollectionAddress === undefined) return
await wallet.client
?.queryContractSmart(selectedCollectionAddress, {
await (
await wallet.getCosmWasmClient()
)
.queryContractSmart(selectedCollectionAddress, {
num_tokens: {},
})
.then((response) => {
@ -164,7 +168,7 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
setMyBaseMinterContracts([])
existingBaseMinterState.onChange('')
void displayToast()
} else if (baseMinterAcquisitionMethod === 'new' || !wallet.initialized) {
} else if (baseMinterAcquisitionMethod === 'new' || !wallet.isWalletConnected) {
setMyBaseMinterContracts([])
existingBaseMinterState.onChange('')
}
@ -194,7 +198,7 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
}, [
existingBaseMinterState.value,
baseMinterAcquisitionMethod,
wallet.initialized,
wallet.isWalletConnected,
selectedCollectionAddress,
collectionTokenCount,
])
@ -270,7 +274,7 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
</Conditional>
<Conditional test={myBaseMinterContracts.length === 0}>
<div className="flex flex-col">
<Conditional test={wallet.initialized}>
<Conditional test={wallet.isWalletConnected}>
<Alert className="my-2 w-[90%]" type="info">
No previous 1/1 collections were found. You may create a new 1/1 collection or fill in the minter
contract address manually.
@ -282,7 +286,7 @@ export const BaseMinterDetails = ({ onChange, minterType, importedBaseMinterDeta
isRequired
/>
</Conditional>
<Conditional test={!wallet.initialized}>
<Conditional test={!wallet.isWalletConnected}>
<Alert className="my-2 w-[90%]" type="warning">
Please connect your wallet first.
</Alert>

View File

@ -10,8 +10,8 @@ import { stars, tokensList } from 'config/token'
import { useGlobalSettings } from 'contexts/globalSettings'
import React, { useEffect, useState } from 'react'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import { useWallet } from '../../../contexts/wallet'
import { NumberInput, TextInput } from '../../forms/FormInput'
import type { UploadMethod } from './UploadDetails'

View File

@ -1,8 +1,8 @@
import { Conditional } from 'components/Conditional'
import { FormGroup } from 'components/FormGroup'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useWallet } from 'contexts/wallet'
import React, { useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import { resolveAddress } from '../../../utils/resolveAddress'
import { NumberInput, TextInput } from '../../forms/FormInput'

View File

@ -10,9 +10,9 @@ import type { WhitelistFlexMember } from 'components/WhitelistFlexUpload'
import { WhitelistFlexUpload } from 'components/WhitelistFlexUpload'
import type { TokenInfo } from 'config/token'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import React, { useEffect, useState } from 'react'
import { isValidAddress } from 'utils/isValidAddress'
import { useWallet } from 'utils/wallet'
import { Conditional } from '../../Conditional'
import { AddressInput, NumberInput } from '../../forms/FormInput'

View File

@ -12,8 +12,8 @@ import type { SG721Instance } from 'contracts/sg721'
import type { VendingMinterInstance } from 'contracts/vendingMinter'
import { toast } from 'react-hot-toast'
import { useQuery } from 'react-query'
import { useWallet } from 'utils/wallet'
import { useWallet } from '../../../contexts/wallet'
import { resolveAddress } from '../../../utils/resolveAddress'
import type { MinterType } from '../actions/Combobox'

View File

@ -1,12 +1,12 @@
import { toUtf8 } from '@cosmjs/encoding'
import { FormControl } from 'components/FormControl'
import { AddressInput } from 'components/forms/FormInput'
import { useWallet } from 'contexts/wallet'
import { useEffect, useId, useMemo } from 'react'
import toast from 'react-hot-toast'
import { FaMinus, FaPlus } from 'react-icons/fa'
import { SG721_NAME_ADDRESS } from 'utils/constants'
import { isValidAddress } from 'utils/isValidAddress'
import { useWallet } from 'utils/wallet'
import { useInputState } from './FormInput.hooks'
@ -66,8 +66,10 @@ export function Address({ id, isLast, onAdd, onChange, onRemove, defaultValue }:
})
const resolveAddress = async (name: string) => {
if (!wallet.client) throw new Error('Wallet not connected')
await wallet.client
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -2,12 +2,12 @@ import { toUtf8 } from '@cosmjs/encoding'
import { FormControl } from 'components/FormControl'
import { AddressInput, NumberInput } from 'components/forms/FormInput'
import type { WhitelistFlexMember } from 'components/WhitelistFlexUpload'
import { useWallet } from 'contexts/wallet'
import { useEffect, useId, useMemo } from 'react'
import toast from 'react-hot-toast'
import { FaMinus, FaPlus } from 'react-icons/fa'
import { SG721_NAME_ADDRESS } from 'utils/constants'
import { isValidAddress } from 'utils/isValidAddress'
import { useWallet } from 'utils/wallet'
import { useInputState, useNumberInputState } from './FormInput.hooks'
@ -75,8 +75,10 @@ export function FlexMemberAttribute({ id, isLast, onAdd, onChange, onRemove, def
}, [addressState.value, mintCountState.value, id])
const resolveAddress = async (name: string) => {
if (!wallet.client) throw new Error('Wallet not connected')
await wallet.client
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -10,8 +10,8 @@ import { stars, tokensList } from 'config/token'
import { useGlobalSettings } from 'contexts/globalSettings'
import React, { useEffect, useState } from 'react'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import { useWallet } from '../../contexts/wallet'
import { NumberInput, TextInput } from '../forms/FormInput'
import type { UploadMethod } from './OffChainMetadataUploadDetails'

View File

@ -7,7 +7,6 @@ import clsx from 'clsx'
import { Conditional } from 'components/Conditional'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useMetadataAttributesState } from 'components/forms/MetadataAttributes.hooks'
import { useWallet } from 'contexts/wallet'
import type { Trait } from 'contracts/badgeHub'
import type { ChangeEvent } from 'react'
import { useEffect, useRef, useState } from 'react'
@ -40,7 +39,6 @@ export const OnChainMetadataInputDetails = ({
uploadMethod,
importedOnChainMetadataInputDetails,
}: OnChainMetadataInputDetailsProps) => {
const wallet = useWallet()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [metadataFile, setMetadataFile] = useState<File>()
const [metadataFeeRate, setMetadataFeeRate] = useState<number>(0)

View File

@ -16,7 +16,6 @@ import { openEditionMinterList } from 'config/minter'
import type { TokenInfo } from 'config/token'
import { useContracts } from 'contexts/contracts'
import { addLogItem } from 'contexts/log'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs as OpenEditionFactoryDispatchExecuteArgs } from 'contracts/openEditionFactory/messages/execute'
import { dispatchExecute as openEditionFactoryDispatchExecute } from 'contracts/openEditionFactory/messages/execute'
import React, { useEffect, useMemo, useState } from 'react'
@ -32,6 +31,7 @@ import type { AssetType } from 'utils/getAssetType'
import { isValidAddress } from 'utils/isValidAddress'
import { checkTokenUri } from 'utils/isValidTokenUri'
import { uid } from 'utils/random'
import { useWallet } from 'utils/wallet'
import { type CollectionDetailsDataProps, CollectionDetails } from './CollectionDetails'
import type { ImageUploadDetailsDataProps } from './ImageUploadDetails'
@ -180,7 +180,7 @@ export const OpenEditionMinterCreator = ({
}
const checkUploadDetails = async () => {
if (!wallet.initialized) throw new Error('Wallet not connected.')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
if (
(metadataStorageMethod === 'off-chain' && !offChainMetadataUploadDetails) ||
(metadataStorageMethod === 'on-chain' && !imageUploadDetails)
@ -338,8 +338,8 @@ export const OpenEditionMinterCreator = ({
}
throw new Error('Invalid royalty payment address')
}
const contractInfoResponse = await wallet.client
?.queryContractRaw(
const contractInfoResponse = await (await wallet.getCosmWasmClient())
.queryContractRaw(
royaltyDetails.paymentAddress.trim(),
toUtf8(Buffer.from(Buffer.from('contract_info').toString('hex'), 'hex').toString()),
)
@ -359,11 +359,11 @@ export const OpenEditionMinterCreator = ({
}
const checkwalletBalance = async () => {
if (!wallet.initialized) throw new Error('Wallet not connected.')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
const amountNeeded = collectionDetails?.updatable
? Number(openEditionMinterUpdatableCreationFee)
: Number(openEditionMinterCreationFee)
await wallet.client?.getBalance(wallet.address, 'ustars').then((balance) => {
await (await wallet.getCosmWasmClient()).getBalance(wallet.address || '', 'ustars').then((balance) => {
if (amountNeeded >= Number(balance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
@ -559,7 +559,7 @@ export const OpenEditionMinterCreator = ({
}
const instantiateOpenEditionMinter = async (uri: string, coverImageUri: string, thumbnailUri?: string) => {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
if (!openEditionFactoryContract) throw new Error('Contract not found')
if (!openEditionMinterContract) throw new Error('Contract not found')
@ -626,7 +626,7 @@ export const OpenEditionMinterCreator = ({
const payload: OpenEditionFactoryDispatchExecuteArgs = {
contract: collectionDetails?.updatable ? updatableFactoryAddressForSelectedDenom : factoryAddressForSelectedDenom,
messages: openEditionFactoryMessages,
txSigner: wallet.address,
txSigner: wallet.address || '',
msg,
funds: [
coin(

View File

@ -1,9 +1,9 @@
import { Conditional } from 'components/Conditional'
import { FormGroup } from 'components/FormGroup'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useWallet } from 'contexts/wallet'
import React, { useEffect, useState } from 'react'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import { NumberInput, TextInput } from '../forms/FormInput'

View File

@ -1,3 +1,2 @@
export * from './app'
export * from './keplr'
export * from './network'

View File

@ -1,76 +0,0 @@
import type { ChainInfo } from '@keplr-wallet/types'
import type { AppConfig } from './app'
export interface KeplrCoin {
readonly coinDenom: string
readonly coinMinimalDenom: string
readonly coinDecimals: number
}
export interface KeplrConfig {
readonly chainId: string
readonly chainName: string
readonly rpc: string
readonly rest?: string
readonly bech32Config: {
readonly bech32PrefixAccAddr: string
readonly bech32PrefixAccPub: string
readonly bech32PrefixValAddr: string
readonly bech32PrefixValPub: string
readonly bech32PrefixConsAddr: string
readonly bech32PrefixConsPub: string
}
readonly currencies: readonly KeplrCoin[]
readonly feeCurrencies: readonly KeplrCoin[]
readonly stakeCurrency: KeplrCoin
readonly gasPriceStep: {
readonly low: number
readonly average: number
readonly high: number
}
readonly bip44: { readonly coinType: number }
readonly coinType: number
}
export const keplrConfig = (config: AppConfig): ChainInfo => ({
chainId: config.chainId,
chainName: config.chainName,
rpc: config.rpcUrl,
rest: config.httpUrl!,
bech32Config: {
bech32PrefixAccAddr: `${config.addressPrefix}`,
bech32PrefixAccPub: `${config.addressPrefix}pub`,
bech32PrefixValAddr: `${config.addressPrefix}valoper`,
bech32PrefixValPub: `${config.addressPrefix}valoperpub`,
bech32PrefixConsAddr: `${config.addressPrefix}valcons`,
bech32PrefixConsPub: `${config.addressPrefix}valconspub`,
},
currencies: [
{
coinDenom: config.coinMap[config.feeToken].denom,
coinMinimalDenom: config.feeToken,
coinDecimals: config.coinMap[config.feeToken].fractionalDigits,
},
],
feeCurrencies: [
{
coinDenom: config.coinMap[config.feeToken].denom,
coinMinimalDenom: config.feeToken,
coinDecimals: config.coinMap[config.feeToken].fractionalDigits,
},
],
stakeCurrency: {
coinDenom: config.coinMap[config.stakingToken].denom,
coinMinimalDenom: config.stakingToken,
coinDecimals: config.coinMap[config.stakingToken].fractionalDigits,
},
gasPriceStep: {
low: config.gasPrice / 2,
average: config.gasPrice,
high: config.gasPrice * 2,
},
bip44: { coinType: 118 },
coinType: 118,
features: ['ibc-transfer', 'cosmwasm', 'ibc-go'],
})

View File

@ -1,4 +1,4 @@
import create from 'zustand'
import { create } from 'zustand'
export const useCollectionStore = create(() => ({
name: 'Example',

View File

@ -18,8 +18,7 @@ import type { UseWhiteListContractProps } from 'contracts/whitelist'
import { useWhiteListContract } from 'contracts/whitelist'
import type { ReactNode, VFC } from 'react'
import { Fragment, useEffect } from 'react'
import type { State } from 'zustand'
import create from 'zustand'
import { create } from 'zustand'
import type { UseSplitsContractProps } from '../contracts/splits/useContract'
import { useSplitsContract } from '../contracts/splits/useContract'
@ -27,7 +26,7 @@ import { useSplitsContract } from '../contracts/splits/useContract'
/**
* Contracts store type definitions
*/
export interface ContractsStore extends State {
export interface ContractsStore {
sg721: UseSG721ContractProps | null
vendingMinter: UseVendingMinterContractProps | null
baseMinter: UseBaseMinterContractProps | null

View File

@ -1,4 +1,4 @@
import create from 'zustand'
import { create } from 'zustand'
export type Timezone = 'UTC' | 'Local'

View File

@ -1,4 +1,4 @@
import create from 'zustand'
import { create } from 'zustand'
export interface LogItem {
id: string

View File

@ -1,4 +1,4 @@
import create from 'zustand'
import { create } from 'zustand'
export const useSidebarStore = create(() => ({ isOpen: true }))

View File

@ -1,289 +0,0 @@
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import { Decimal } from '@cosmjs/math'
import type { OfflineSigner } from '@cosmjs/proto-signing'
import type { Coin } from '@cosmjs/stargate'
import type { AppConfig } from 'config'
import { getConfig, keplrConfig } from 'config'
import type { ReactNode } from 'react'
import { useEffect } from 'react'
import { toast } from 'react-hot-toast'
import { createTrackedSelector } from 'react-tracked'
import { NETWORK } from 'utils/constants'
import type { State } from 'zustand'
import create from 'zustand'
import { subscribeWithSelector } from 'zustand/middleware'
export interface KeplrWalletStore extends State {
accountNumber: number
address: string
balance: Coin[]
client: SigningCosmWasmClient | undefined
config: AppConfig
initialized: boolean
initializing: boolean
name: string
network: string
signer: OfflineSigner | undefined
readonly clear: () => void
readonly connect: (walletChange?: boolean | 'focus') => Promise<void>
readonly disconnect: () => void | Promise<void>
readonly getClient: () => SigningCosmWasmClient
readonly getSigner: () => OfflineSigner
readonly init: (signer?: OfflineSigner) => void
readonly refreshBalance: (address?: string, balance?: Coin[]) => Promise<void>
readonly setNetwork: (network: string) => void
readonly updateSigner: (singer: OfflineSigner) => void
readonly setQueryClient: () => void
}
/**
* Compatibility export for references still using `WalletContextType`
*
* @deprecated replace with {@link KeplrWalletStore}
*/
export type WalletContextType = KeplrWalletStore
/**
* Keplr wallet store default values as a separate variable for reusability
*/
const defaultStates = {
accountNumber: 0,
address: '',
balance: [],
client: undefined,
config: getConfig(NETWORK),
initialized: false,
initializing: true,
name: '',
network: NETWORK,
signer: undefined,
}
/**
* Entrypoint for keplr wallet store using {@link defaultStates}
*/
export const useWalletStore = create(
subscribeWithSelector<KeplrWalletStore>((set, get) => ({
...defaultStates,
clear: () => set({ ...defaultStates }),
connect: async (walletChange = false) => {
try {
if (walletChange !== 'focus') set({ initializing: true })
const { config, init } = get()
const signer = await loadKeplrWallet(config)
init(signer)
if (walletChange) set({ initializing: false })
} catch (err: any) {
toast.error(err?.message, { style: { maxWidth: 'none' } })
set({ initializing: false })
}
},
disconnect: () => {
window.localStorage.clear()
get().clear()
set({ initializing: false })
},
getClient: () => get().client!,
getSigner: () => get().signer!,
init: (signer) => set({ signer }),
refreshBalance: async (address = get().address, balance = get().balance) => {
const { client, config } = get()
if (!client) return
balance.length = 0
for (const denom in config.coinMap) {
// eslint-disable-next-line no-await-in-loop
const coin = await client.getBalance(address, denom)
if (coin) balance.push(coin)
}
set({ balance })
},
setNetwork: (network) => set({ network }),
updateSigner: (signer) => set({ signer }),
setQueryClient: async () => {
try {
const client = (await createQueryClient()) as SigningCosmWasmClient
set({ client })
} catch (err: any) {
toast.error(err?.message, { style: { maxWidth: 'none' } })
set({ initializing: false })
}
},
})),
)
/**
* Proxied keplr wallet store which only rerenders on called state values.
*
* Recommended if only consuming state; to set states, use {@link useWalletStore.setState}.
*
* @example
*
* ```ts
* // this will rerender if any state values has changed
* const { name } = useWalletStore()
*
* // this will rerender if only `name` has changed
* const { name } = useWallet()
* ```
*/
export const useWallet = createTrackedSelector<KeplrWalletStore>(useWalletStore)
/**
* Keplr wallet store provider to easily mount {@link WalletSubscription}
* to listen/subscribe various state changes.
*
*/
export const WalletProvider = ({ children }: { children: ReactNode }) => {
return (
<>
{children}
<WalletSubscription />
</>
)
}
/**
* Keplr wallet subscriptions (side effects)
*/
const WalletSubscription = () => {
/**
* Dispatch reconnecting wallet on first mount and register events to refresh
* on keystore change and window refocus.
*
*/
useEffect(() => {
const walletAddress = window.localStorage.getItem('wallet_address')
if (walletAddress) {
void useWalletStore.getState().connect()
} else {
useWalletStore.setState({ initializing: false })
useWalletStore.getState().setQueryClient()
}
const listenChange = () => {
void useWalletStore.getState().connect(true)
}
const listenFocus = () => {
if (walletAddress) void useWalletStore.getState().connect('focus')
}
window.addEventListener('keplr_keystorechange', listenChange)
window.addEventListener('focus', listenFocus)
return () => {
window.removeEventListener('keplr_keystorechange', listenChange)
window.removeEventListener('focus', listenFocus)
}
}, [])
/**
* Watch signer changes to initialize client state.
*
*/
useEffect(() => {
return useWalletStore.subscribe(
(x) => x.signer,
// eslint-disable-next-line @typescript-eslint/no-misused-promises
async (signer) => {
try {
if (!signer) {
useWalletStore.setState({
client: (await createQueryClient()) as SigningCosmWasmClient,
})
} else {
useWalletStore.setState({
client: await createClient({ signer }),
})
}
} catch (error) {
console.log(error)
}
},
)
}, [])
/**
* Watch client changes to refresh balance and sync wallet states.
*
*/
useEffect(() => {
return useWalletStore.subscribe(
(x) => x.client,
// eslint-disable-next-line @typescript-eslint/no-misused-promises
async (client) => {
const { config, refreshBalance, signer } = useWalletStore.getState()
if (!signer || !client) return
if (!window.keplr) {
throw new Error('window.keplr not found')
}
const balance: Coin[] = []
const address = (await signer.getAccounts())[0].address
const account = await client.getAccount(address)
const key = await window.keplr.getKey(config.chainId)
await refreshBalance(address, balance)
window.localStorage.setItem('wallet_address', address)
useWalletStore.setState({
accountNumber: account?.accountNumber || 0,
address,
balance,
initialized: true,
initializing: false,
name: key.name || '',
})
},
)
}, [])
return null
}
/**
* Function to create signing client based on {@link useWalletStore} resolved
* config state.
*
* @param arg - Object argument requiring `signer`
*/
const createClient = ({ signer }: { signer: OfflineSigner }) => {
const { config } = useWalletStore.getState()
return SigningCosmWasmClient.connectWithSigner(config.rpcUrl, signer, {
gasPrice: {
amount: Decimal.fromUserInput('0.0025', 100),
denom: config.feeToken,
},
})
}
const createQueryClient = () => {
const { config } = useWalletStore.getState()
return SigningCosmWasmClient.connect(config.rpcUrl)
}
/**
* Function to load keplr wallet signer.
*
* @param config - Application configuration
*/
const loadKeplrWallet = async (config: AppConfig) => {
if (!window.getOfflineSigner || !window.keplr || !window.getOfflineSignerAuto) {
throw new Error('Keplr extension is not available')
}
await window.keplr.experimentalSuggestChain(keplrConfig(config))
await window.keplr.enable(config.chainId)
const signer = await window.getOfflineSignerAuto(config.chainId)
Object.assign(signer, {
signAmino: (signer as any).signAmino ?? (signer as any).sign,
})
return signer
}

View File

@ -1,7 +1,7 @@
import type { Coin } from '@cosmjs/proto-signing'
import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { BadgeHubContract, BadgeHubInstance, BadgeHubMessages, MigrateResponse } from './contract'
import { badgeHub as initContract } from './contract'
@ -50,9 +50,19 @@ export function useBadgeHubContract(): UseBadgeHubContractProps {
}, [])
useEffect(() => {
const BadgeHubBaseContract = initContract(wallet.getClient(), wallet.address)
setBadgeHub(BadgeHubBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const BadgeHubBaseContract = initContract(client, wallet.address || '')
setBadgeHub(BadgeHubBaseContract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -65,7 +75,10 @@ export function useBadgeHubContract(): UseBadgeHubContractProps {
reject(new Error('Contract is not initialized.'))
return
}
badgeHub.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
badgeHub
.instantiate(wallet.address || '', codeId, initMsg, label, admin)
.then(resolve)
.catch(reject)
})
},
[badgeHub, wallet],
@ -79,7 +92,10 @@ export function useBadgeHubContract(): UseBadgeHubContractProps {
return
}
console.log(wallet.address, contractAddress, codeId)
badgeHub.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
badgeHub
.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[badgeHub, wallet],

View File

@ -1,5 +1,5 @@
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { BaseFactoryContract, BaseFactoryInstance, BaseFactoryMessages } from './contract'
import { baseFactory as initContract } from './contract'
@ -22,9 +22,19 @@ export function useBaseFactoryContract(): UseBaseFactoryContractProps {
}, [])
useEffect(() => {
const BaseFactoryBaseContract = initContract(wallet.getClient(), wallet.address)
setBaseFactory(BaseFactoryBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const BaseFactoryBaseContract = initContract(client, wallet.address || '')
setBaseFactory(BaseFactoryBaseContract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)

View File

@ -1,7 +1,7 @@
import type { Coin } from '@cosmjs/proto-signing'
import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { BaseMinterContract, BaseMinterInstance, BaseMinterMessages, MigrateResponse } from './contract'
import { baseMinter as initContract } from './contract'
@ -38,9 +38,19 @@ export function useBaseMinterContract(): UseBaseMinterContractProps {
}, [])
useEffect(() => {
const BaseMinterBaseContract = initContract(wallet.getClient(), wallet.address)
setBaseMinter(BaseMinterBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const BaseMinterBaseContract = initContract(client, wallet.address || '')
setBaseMinter(BaseMinterBaseContract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -53,7 +63,10 @@ export function useBaseMinterContract(): UseBaseMinterContractProps {
reject(new Error('Contract is not initialized.'))
return
}
baseMinter.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
baseMinter
.instantiate(wallet.address || '', codeId, initMsg, label, admin)
.then(resolve)
.catch(reject)
})
},
[baseMinter, wallet],
@ -67,7 +80,10 @@ export function useBaseMinterContract(): UseBaseMinterContractProps {
return
}
console.log(wallet.address, contractAddress, codeId)
baseMinter.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
baseMinter
.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[baseMinter, wallet],

View File

@ -1,6 +1,6 @@
import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { OpenEditionFactoryContract, OpenEditionFactoryInstance, OpenEditionFactoryMessages } from './contract'
import { openEditionFactory as initContract } from './contract'
@ -41,9 +41,19 @@ export function useOpenEditionFactoryContract(): UseOpenEditionFactoryContractPr
}, [])
useEffect(() => {
const OpenEditionFactoryBaseContract = initContract(wallet.getClient(), wallet.address)
setOpenEditionFactory(OpenEditionFactoryBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const OpenEditionFactoryBaseContract = initContract(client, wallet.address || '')
setOpenEditionFactory(OpenEditionFactoryBaseContract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)

View File

@ -1,7 +1,7 @@
import type { Coin } from '@cosmjs/proto-signing'
import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type {
MigrateResponse,
@ -55,9 +55,19 @@ export function useOpenEditionMinterContract(): UseOpenEditionMinterContractProp
}, [])
useEffect(() => {
const OpenEditionMinterBaseContract = initContract(wallet.getClient(), wallet.address)
setOpenEditionMinter(OpenEditionMinterBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const OpenEditionMinterBaseContract = initContract(client, wallet.address || '')
setOpenEditionMinter(OpenEditionMinterBaseContract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -70,7 +80,10 @@ export function useOpenEditionMinterContract(): UseOpenEditionMinterContractProp
reject(new Error('Contract is not initialized.'))
return
}
openEditionMinter.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
openEditionMinter
.instantiate(wallet.address || '', codeId, initMsg, label, admin)
.then(resolve)
.catch(reject)
})
},
[openEditionMinter, wallet],
@ -84,7 +97,10 @@ export function useOpenEditionMinterContract(): UseOpenEditionMinterContractProp
return
}
console.log(wallet.address, contractAddress, codeId)
openEditionMinter.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
openEditionMinter
.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[openEditionMinter, wallet],

View File

@ -1,7 +1,7 @@
/* eslint-disable eslint-comments/disable-enable-pair */
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type {
InstantiateResponse,
@ -40,9 +40,19 @@ export function useRoyaltyRegistryContract(): UseRoyaltyRegistryContractProps {
}, [])
useEffect(() => {
const royaltyRegistryContract = initContract(wallet.getClient(), wallet.address)
setRoyaltyRegistry(royaltyRegistryContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const royaltyRegistryContract = initContract(client, wallet.address || '')
setRoyaltyRegistry(royaltyRegistryContract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -69,7 +79,10 @@ export function useRoyaltyRegistryContract(): UseRoyaltyRegistryContractProps {
return
}
console.log(wallet.address, contractAddress, codeId)
royaltyRegistry.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
royaltyRegistry
.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[royaltyRegistry, wallet],

View File

@ -1,6 +1,6 @@
import type { Coin } from '@cosmjs/proto-signing'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { MigrateResponse, SG721Contract, SG721Instance, Sg721Messages } from './contract'
import { SG721 as initContract } from './contract'
@ -35,9 +35,19 @@ export function useSG721Contract(): UseSG721ContractProps {
}, [])
useEffect(() => {
const contract = initContract(wallet.getClient(), wallet.address)
setSG721(contract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const contract = initContract(client, wallet.address || '')
setSG721(contract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -50,7 +60,9 @@ export function useSG721Contract(): UseSG721ContractProps {
reject(new Error('Contract is not initialized.'))
return
}
SG721.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
SG721.instantiate(wallet.address || '', codeId, initMsg, label, admin)
.then(resolve)
.catch(reject)
})
},
[SG721, wallet],
@ -64,7 +76,9 @@ export function useSG721Contract(): UseSG721ContractProps {
return
}
console.log(wallet.address, contractAddress, codeId)
SG721.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
SG721.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[SG721, wallet],

View File

@ -1,7 +1,7 @@
/* eslint-disable eslint-comments/disable-enable-pair */
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { InstantiateResponse, MigrateResponse, SplitsContract, SplitsInstance, SplitsMessages } from './contract'
import { Splits as initContract } from './contract'
@ -34,9 +34,19 @@ export function useSplitsContract(): UseSplitsContractProps {
}, [])
useEffect(() => {
const splitsContract = initContract(wallet.getClient(), wallet.address)
setSplits(splitsContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const contract = initContract(client, wallet.address || '')
setSplits(contract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -63,7 +73,10 @@ export function useSplitsContract(): UseSplitsContractProps {
return
}
console.log(wallet.address, contractAddress, codeId)
splits.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
splits
.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[splits, wallet],

View File

@ -1,6 +1,6 @@
import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { VendingFactoryContract, VendingFactoryInstance, VendingFactoryMessages } from './contract'
import { vendingFactory as initContract } from './contract'
@ -41,9 +41,19 @@ export function useVendingFactoryContract(): UseVendingFactoryContractProps {
}, [])
useEffect(() => {
const VendingFactoryBaseContract = initContract(wallet.getClient(), wallet.address)
setVendingFactory(VendingFactoryBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const contract = initContract(client, wallet.address || '')
setVendingFactory(contract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)

View File

@ -1,7 +1,7 @@
import type { Coin } from '@cosmjs/proto-signing'
import type { logs } from '@cosmjs/stargate'
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { MigrateResponse, VendingMinterContract, VendingMinterInstance, VendingMinterMessages } from './contract'
import { vendingMinter as initContract } from './contract'
@ -50,9 +50,19 @@ export function useVendingMinterContract(): UseVendingMinterContractProps {
}, [])
useEffect(() => {
const VendingMinterBaseContract = initContract(wallet.getClient(), wallet.address)
setVendingMinter(VendingMinterBaseContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const contract = initContract(client, wallet.address || '')
setVendingMinter(contract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)
@ -65,7 +75,10 @@ export function useVendingMinterContract(): UseVendingMinterContractProps {
reject(new Error('Contract is not initialized.'))
return
}
vendingMinter.instantiate(wallet.address, codeId, initMsg, label, admin).then(resolve).catch(reject)
vendingMinter
.instantiate(wallet.address || '', codeId, initMsg, label, admin)
.then(resolve)
.catch(reject)
})
},
[vendingMinter, wallet],
@ -79,7 +92,10 @@ export function useVendingMinterContract(): UseVendingMinterContractProps {
return
}
console.log(wallet.address, contractAddress, codeId)
vendingMinter.migrate(wallet.address, contractAddress, codeId, migrateMsg).then(resolve).catch(reject)
vendingMinter
.migrate(wallet.address || '', contractAddress, codeId, migrateMsg)
.then(resolve)
.catch(reject)
})
},
[vendingMinter, wallet],

View File

@ -1,5 +1,5 @@
import { useWallet } from 'contexts/wallet'
import { useCallback, useEffect, useState } from 'react'
import { useWallet } from 'utils/wallet'
import type { InstantiateResponse, WhiteListContract, WhiteListInstance, WhitelistMessages } from './contract'
import { WhiteList as initContract } from './contract'
@ -30,9 +30,19 @@ export function useWhiteListContract(): UseWhiteListContractProps {
}, [])
useEffect(() => {
const whiteListContract = initContract(wallet.getClient(), wallet.address)
setWhiteList(whiteListContract)
}, [wallet])
if (!wallet.isWalletConnected) {
return
}
const load = async () => {
const client = await wallet.getSigningCosmWasmClient()
const contract = initContract(client, wallet.address || '')
setWhiteList(contract)
}
load().catch(console.error)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected, wallet.address])
const updateContractAddress = (contractAddress: string) => {
setAddress(contractAddress)

4
env.d.ts vendored
View File

@ -68,9 +68,7 @@ declare namespace NodeJS {
}
}
type KeplrWindow = import('@keplr-wallet/types/src/window').Window
declare interface Window extends KeplrWindow {
declare interface Window {
confetti?: (obj: any) => void
}

View File

@ -18,11 +18,11 @@
"@cosmjs/math": "^0",
"@cosmjs/proto-signing": "^0",
"@cosmjs/stargate": "^0",
"@cosmos-kit/keplr": "^2.4.0",
"@cosmos-kit/react": "^2.9.0",
"@fontsource/jetbrains-mono": "^4",
"@fontsource/roboto": "^4",
"@headlessui/react": "^1",
"jscrypto": "^1.0.3",
"@keplr-wallet/cosmos": "^0.9.16",
"@pinata/sdk": "^1.1.26",
"@popperjs/core": "^2",
"@svgr/webpack": "^6",
@ -30,10 +30,12 @@
"@tailwindcss/line-clamp": "^0",
"@typeform/embed-react": "2.21.0",
"axios": "^0",
"chain-registry": "^1.20.0",
"clsx": "^1",
"compare-versions": "^4",
"daisyui": "^2.19.0",
"html-to-image": "1.11.11",
"jscrypto": "^1.0.3",
"match-sorter": "^6",
"next": "^12",
"next-seo": "^4",
@ -51,7 +53,7 @@
"scheduler": "^0",
"secp256k1": "^4.0.3",
"tailwindcss-opentype": "1.1.0",
"zustand": "^3"
"zustand": "^4"
},
"devDependencies": {
"@stargazezone/types": "^0.7.2",

View File

@ -4,9 +4,9 @@ import '../styles/globals.css'
import '../styles/datepicker.css'
import { Layout } from 'components/Layout'
import { WalletProvider } from 'components/WalletProvider'
import { queryClient } from 'config/react-query'
import { ContractsProvider } from 'contexts/contracts'
import { WalletProvider } from 'contexts/wallet'
import type { AppProps } from 'next/app'
import { Toaster } from 'react-hot-toast'
import { QueryClientProvider } from 'react-query'

View File

@ -9,7 +9,6 @@ import { ContractPageHeader } from 'components/ContractPageHeader'
import { AddressInput, NumberInput } from 'components/forms/FormInput'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
import { NextSeo } from 'next-seo'
@ -18,6 +17,7 @@ import toast from 'react-hot-toast'
import { useDebounce } from 'utils/debounce'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
import { BadgeActions } from '../../components/badges/actions/Action'
import { useNumberInputState } from '../../components/forms/FormInput.hooks'
@ -82,8 +82,8 @@ const BadgeActionsPage: NextPage = () => {
useEffect(() => {
async function getMintRule() {
if (wallet.client && debouncedBadgeHubContractState.length > 0 && debouncedBadgeIdState > 0) {
const client = wallet.client
if (wallet.isWalletConnected && debouncedBadgeHubContractState.length > 0 && debouncedBadgeIdState > 0) {
const client = await wallet.getCosmWasmClient()
const data = await toast.promise(
client.queryContractSmart(debouncedBadgeHubContractState, {
badge: {
@ -117,7 +117,8 @@ const BadgeActionsPage: NextPage = () => {
setMintRule('not_resolved')
console.log('Unable to retrieve Mint Rule. Defaulting to "by_key".')
})
}, [debouncedBadgeHubContractState, debouncedBadgeIdState, wallet.client])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [debouncedBadgeHubContractState, debouncedBadgeIdState, wallet.isWalletConnected])
return (
<section className="py-6 px-12 space-y-4">

View File

@ -24,7 +24,6 @@ import { useInputState } from 'components/forms/FormInput.hooks'
import { Tooltip } from 'components/Tooltip'
import { useContracts } from 'contexts/contracts'
import { addLogItem } from 'contexts/log'
import { useWallet } from 'contexts/wallet'
import type { Badge } from 'contracts/badgeHub'
import type { DispatchExecuteArgs as BadgeHubDispatchExecuteArgs } from 'contracts/badgeHub/messages/execute'
import { dispatchExecute as badgeHubDispatchExecute } from 'contracts/badgeHub/messages/execute'
@ -47,6 +46,7 @@ import { links } from 'utils/links'
import { uid } from 'utils/random'
import { resolveAddress } from 'utils/resolveAddress'
import { truncateMiddle } from 'utils/text'
import { useWallet } from 'utils/wallet'
import { generateKeyPairs } from '../../utils/hash'
@ -181,7 +181,7 @@ const BadgeCreationPage: NextPage = () => {
const createNewBadge = async () => {
try {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
if (!badgeHubContract) throw new Error('Contract not found')
setCreatingBadge(true)
const coverUrl = await handleImageUrl()
@ -220,7 +220,7 @@ const BadgeCreationPage: NextPage = () => {
const payload: BadgeHubDispatchExecuteArgs = {
contract: BADGE_HUB_ADDRESS,
messages: badgeHubMessages,
txSigner: wallet.address,
txSigner: wallet.address || '',
badge,
type: 'create_badge',
}
@ -245,7 +245,7 @@ const BadgeCreationPage: NextPage = () => {
setBadgeId(data.split(':')[1])
const res = await toast.promise(
badgeHubContract.use(BADGE_HUB_ADDRESS)?.addKeys(
wallet.address,
wallet.address || '',
Number(data.split(':')[1]),
generatedKeyPairs.map((key) => key.publicKey),
) as Promise<string>,
@ -276,7 +276,7 @@ const BadgeCreationPage: NextPage = () => {
}
const checkImageUploadDetails = () => {
if (!wallet.initialized) throw new Error('Wallet not connected.')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
if (!imageUploadDetails) {
throw new Error('Please specify the image related details.')
}
@ -359,7 +359,7 @@ const BadgeCreationPage: NextPage = () => {
}
const checkwalletBalance = () => {
if (!wallet.initialized) throw new Error('Wallet not connected.')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
// TODO: estimate creation cost and check wallet balance
}
useEffect(() => {

View File

@ -7,7 +7,6 @@ import { Alert } from 'components/Alert'
import { Anchor } from 'components/Anchor'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import { useCallback, useEffect, useState } from 'react'
@ -15,6 +14,7 @@ import { FaSlidersH, FaUser } from 'react-icons/fa'
import { API_URL, BADGE_HUB_ADDRESS, STARGAZE_URL } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const BadgeList: NextPage = () => {
const wallet = useWallet()
@ -23,7 +23,7 @@ const BadgeList: NextPage = () => {
useEffect(() => {
const fetchBadges = async () => {
await axios
.get(`${API_URL}/api/v1beta/badges/${wallet.address}`)
.get(`${API_URL}/api/v1beta/badges/${wallet.address || ''}`)
.then((response) => {
const badgeData = response.data
setMyBadges(badgeData)
@ -90,7 +90,7 @@ const BadgeList: NextPage = () => {
<Anchor
className="text-xl text-plumbus"
external
href={`${STARGAZE_URL}/profile/${wallet.address}`}
href={`${STARGAZE_URL}/profile/${wallet.address || ''}`}
>
<FaUser />
</Anchor>

View File

@ -6,7 +6,6 @@ import { ContractPageHeader } from 'components/ContractPageHeader'
import { AddressInput } from 'components/forms/FormInput'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
import { NextSeo } from 'next-seo'
@ -16,6 +15,7 @@ import { ROYALTY_REGISTRY_ADDRESS } from 'utils/constants'
import { useDebounce } from 'utils/debounce'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
import type { MinterType, Sg721Type } from '../../components/collections/actions/Combobox'
@ -100,8 +100,8 @@ const CollectionActionsPage: NextPage = () => {
useEffect(() => {
async function getMinterContractType() {
if (wallet.client && debouncedMinterContractState.length > 0) {
const client = wallet.client
if (wallet.isWalletConnected && debouncedMinterContractState.length > 0) {
const client = await wallet.getCosmWasmClient()
const data = await toast.promise(
client.queryContractRaw(
debouncedMinterContractState,
@ -133,12 +133,13 @@ const CollectionActionsPage: NextPage = () => {
setMinterType('vending')
console.log('Unable to retrieve contract type. Defaulting to "vending".')
})
}, [debouncedMinterContractState, wallet.client])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [debouncedMinterContractState, wallet.isWalletConnected])
useEffect(() => {
async function getSg721ContractType() {
if (wallet.client && debouncedSg721ContractState.length > 0) {
const client = wallet.client
if (wallet.isWalletConnected && debouncedSg721ContractState.length > 0) {
const client = await wallet.getCosmWasmClient()
const data = await toast.promise(
client.queryContractRaw(
debouncedSg721ContractState,
@ -168,7 +169,8 @@ const CollectionActionsPage: NextPage = () => {
setSg721Type('base')
console.log('Unable to retrieve contract type. Defaulting to "base".')
})
}, [debouncedSg721ContractState, wallet.client])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [debouncedSg721ContractState, wallet.isWalletConnected])
return (
<section className="py-6 px-12 space-y-4">

View File

@ -38,7 +38,6 @@ import { flexibleVendingMinterList, openEditionMinterList, vendingMinterList } f
import type { TokenInfo } from 'config/token'
import { useContracts } from 'contexts/contracts'
import { addLogItem } from 'contexts/log'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs as BaseFactoryDispatchExecuteArgs } from 'contracts/baseFactory/messages/execute'
import { dispatchExecute as baseFactoryDispatchExecute } from 'contracts/baseFactory/messages/execute'
import type { DispatchExecuteArgs as VendingFactoryDispatchExecuteArgs } from 'contracts/vendingFactory/messages/execute'
@ -71,6 +70,7 @@ import { checkTokenUri } from 'utils/isValidTokenUri'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { uid } from 'utils/random'
import { useWallet } from 'utils/wallet'
import type { MinterType } from '../../components/collections/actions/Combobox'
import type { UploadMethod } from '../../components/collections/creation/UploadDetails'
@ -410,7 +410,7 @@ const CollectionCreationPage: NextPage = () => {
const uploadAndMint = async () => {
try {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
if (!baseMinterContract) throw new Error('Contract not found')
setCreatingCollection(true)
setIsMintingComplete(false)
@ -436,7 +436,7 @@ const CollectionCreationPage: NextPage = () => {
.use(baseMinterDetails?.existingBaseMinter as string)
?.mint(
wallet.address,
wallet.address || '',
`ipfs://${baseUri}/${(uploadDetails.baseMinterMetadataFile as File).name.substring(
0,
(uploadDetails.baseMinterMetadataFile as File).name.lastIndexOf('.'),
@ -448,7 +448,7 @@ const CollectionCreationPage: NextPage = () => {
setBaseTokenUri(baseUri)
const result = await baseMinterContract
.use(baseMinterDetails?.existingBaseMinter as string)
?.batchMint(wallet.address, `ipfs://${baseUri}`, uploadDetails.assetFiles.length)
?.batchMint(wallet.address || '', `ipfs://${baseUri}`, uploadDetails.assetFiles.length)
console.log(result)
return result
})
@ -473,7 +473,7 @@ const CollectionCreationPage: NextPage = () => {
setUploading(false)
await baseMinterContract
.use(baseMinterDetails?.existingBaseMinter as string)
?.mint(wallet.address, `${uploadDetails?.baseTokenURI?.trim()}`)
?.mint(wallet.address || '', `${uploadDetails?.baseTokenURI?.trim()}`)
.then((result) => {
toast.success(`Token minted & added to the collection successfully! Tx Hash: ${result}`, {
style: { maxWidth: 'none' },
@ -501,7 +501,7 @@ const CollectionCreationPage: NextPage = () => {
}
const instantiateWhitelist = async () => {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
if (!whitelistContract) throw new Error('Contract not found')
const standardMsg = {
@ -542,7 +542,7 @@ const CollectionCreationPage: NextPage = () => {
}
const instantiateVendingMinter = async (baseUri: string, coverImageUri: string, whitelist?: string) => {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
if (!vendingFactoryContract) throw new Error('Contract not found')
let royaltyInfo = null
@ -591,7 +591,7 @@ const CollectionCreationPage: NextPage = () => {
const payload: VendingFactoryDispatchExecuteArgs = {
contract: vendingFactoryAddress as string,
messages: vendingFactoryMessages,
txSigner: wallet.address,
txSigner: wallet.address || '',
msg,
funds: [
coin(
@ -613,7 +613,7 @@ const CollectionCreationPage: NextPage = () => {
}
const instantiateBaseMinter = async (baseUri: string, coverImageUri: string) => {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected')
if (!baseFactoryContract) throw new Error('Contract not found')
if (!baseMinterContract) throw new Error('Contract not found')
@ -652,7 +652,7 @@ const CollectionCreationPage: NextPage = () => {
const payload: BaseFactoryDispatchExecuteArgs = {
contract: collectionDetails?.updatable ? BASE_FACTORY_UPDATABLE_ADDRESS : BASE_FACTORY_ADDRESS,
messages: baseFactoryMessages,
txSigner: wallet.address,
txSigner: wallet.address || '',
msg,
funds: [
coin(
@ -670,7 +670,7 @@ const CollectionCreationPage: NextPage = () => {
if (uploadDetails?.assetFiles.length === 1 || uploadDetails?.uploadMethod === 'existing') {
await toast
.promise(
baseMinterContract.use(data.baseMinterAddress)?.mint(wallet.address, baseUri) as Promise<string>,
baseMinterContract.use(data.baseMinterAddress)?.mint(wallet.address || '', baseUri) as Promise<string>,
{
loading: 'Minting token...',
success: (result) => {
@ -693,7 +693,11 @@ const CollectionCreationPage: NextPage = () => {
.promise(
baseMinterContract
.use(data.baseMinterAddress)
?.batchMint(wallet.address, baseUri, uploadDetails?.assetFiles.length as number) as Promise<string>,
?.batchMint(
wallet.address || '',
baseUri,
uploadDetails?.assetFiles.length as number,
) as Promise<string>,
{
loading: 'Minting tokens...',
success: (result) => {
@ -883,7 +887,7 @@ const CollectionCreationPage: NextPage = () => {
}
const checkUploadDetails = () => {
if (!wallet.initialized) throw new Error('Wallet not connected.')
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
if (!uploadDetails) {
throw new Error('Please select assets and metadata')
}
@ -1092,8 +1096,8 @@ const CollectionCreationPage: NextPage = () => {
}
throw new Error('Invalid royalty payment address')
}
const contractInfoResponse = await wallet.client
?.queryContractRaw(
const contractInfoResponse = await (await wallet.getCosmWasmClient())
.queryContractRaw(
royaltyDetails.paymentAddress.trim(),
toUtf8(Buffer.from(Buffer.from('contract_info').toString('hex'), 'hex').toString()),
)
@ -1113,8 +1117,8 @@ const CollectionCreationPage: NextPage = () => {
}
const fetchInitialFactoryParameters = async () => {
const client = wallet.client
if (!client) return
if (!wallet.isWalletConnected) return
const client = await wallet.getCosmWasmClient()
if (BASE_FACTORY_ADDRESS) {
const baseFactoryParameters = await client
.queryContractSmart(BASE_FACTORY_ADDRESS, { params: {} })
@ -1193,8 +1197,8 @@ const CollectionCreationPage: NextPage = () => {
}
const fetchOpenEditionFactoryParameters = useCallback(async () => {
const client = wallet.client
if (!client) return
if (!wallet.isWalletConnected) return
const client = await wallet.getCosmWasmClient()
const factoryForSelectedDenom = openEditionMinterList.find(
(minter) =>
minter.supportedToken === openEditionMinterDetails?.mintingDetails?.selectedMintToken &&
@ -1237,15 +1241,16 @@ const CollectionCreationPage: NextPage = () => {
)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
openEditionMinterDetails?.mintingDetails?.selectedMintToken,
openEditionMinterDetails?.collectionDetails?.updatable,
wallet.client,
wallet.isWalletConnected,
])
const fetchVendingFactoryParameters = useCallback(async () => {
const client = wallet.client
if (!client) return
if (!wallet.isWalletConnected) return
const client = await wallet.getCosmWasmClient()
const vendingFactoryForSelectedDenom = vendingMinterList
.concat(flexibleVendingMinterList)
.find(
@ -1280,13 +1285,13 @@ const CollectionCreationPage: NextPage = () => {
}, [
collectionDetails?.updatable,
mintingDetails?.selectedMintToken,
wallet.client,
wallet.isWalletConnected,
whitelistDetails?.whitelistState,
whitelistDetails?.whitelistType,
])
const checkwalletBalance = async () => {
const walletBalance = await wallet.client?.getBalance(wallet.address, 'ustars').then((balance) => {
await (await wallet.getCosmWasmClient()).getBalance(wallet.address || '', 'ustars').then((balance) => {
if (minterType === 'vending' && whitelistDetails?.whitelistState === 'new' && whitelistDetails.memberLimit) {
const amountNeeded =
Math.ceil(Number(whitelistDetails.memberLimit) / 1000) * 100000000 +
@ -1438,7 +1443,8 @@ const CollectionCreationPage: NextPage = () => {
if (!initialParametersFetched) {
void fetchInitialFactoryParameters()
}
}, [wallet.client])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [wallet.isWalletConnected])
useEffect(() => {
void fetchOpenEditionFactoryParameters()

View File

@ -11,7 +11,6 @@ import { Anchor } from 'components/Anchor'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
import { Tooltip } from 'components/Tooltip'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import { useCallback, useEffect, useState } from 'react'
@ -21,6 +20,7 @@ import { API_URL, STARGAZE_URL } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { truncateMiddle } from 'utils/text'
import { useWallet } from 'utils/wallet'
const CollectionList: NextPage = () => {
const wallet = useWallet()
@ -30,8 +30,8 @@ const CollectionList: NextPage = () => {
const [myOpenEditionCollections, setMyOpenEditionCollections] = useState<any[]>([])
async function getMinterContractType(minterContractAddress: string) {
if (wallet.client && minterContractAddress.length > 0) {
const client = wallet.client
if (wallet.isWalletConnected && minterContractAddress.length > 0) {
const client = await wallet.getCosmWasmClient()
const data = await client.queryContractRaw(
minterContractAddress,
toUtf8(Buffer.from(Buffer.from('contract_info').toString('hex'), 'hex').toString()),

View File

@ -28,7 +28,6 @@ import { TransactionHash } from 'components/TransactionHash'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { Badge } from 'contracts/badgeHub'
import type { DispatchExecuteArgs } from 'contracts/badgeHub/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/badgeHub/messages/execute'
@ -53,6 +52,7 @@ import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { truncateMiddle } from 'utils/text'
import { useWallet } from 'utils/wallet'
import { TextInput } from '../../../components/forms/FormInput'
import { MetadataAttributes } from '../../../components/forms/MetadataAttributes'
@ -323,7 +323,7 @@ const BadgeHubExecutePage: NextPage = () => {
editFee,
contract: contractState.value,
messages,
txSigner: wallet.address,
txSigner: wallet.address || '',
type,
}
const { isLoading, mutate } = useMutation(
@ -332,14 +332,15 @@ const BadgeHubExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
if (contractState.value === '') {
throw new Error('Please enter the contract address.')
}
if (wallet.client && type === 'edit_badge') {
const feeRateRaw = await wallet.client.queryContractRaw(
if (type === 'edit_badge') {
const client = await wallet.getCosmWasmClient()
const feeRateRaw = await client.queryContractRaw(
contractAddress,
toUtf8(Buffer.from(Buffer.from('fee_rate').toString('hex'), 'hex').toString()),
)
@ -347,7 +348,7 @@ const BadgeHubExecutePage: NextPage = () => {
await toast
.promise(
wallet.client.queryContractSmart(contractAddress, {
client.queryContractSmart(contractAddress, {
badge: { id: badgeIdState.value },
}),
{

View File

@ -9,7 +9,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { badgeHubLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { InstantiateResponse } from 'contracts/sg721'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
@ -20,6 +19,7 @@ import { useMutation } from 'react-query'
import { BADGE_HUB_CODE_ID } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
export interface FeeRate {
metadata: number

View File

@ -9,7 +9,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { badgeHubLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { MigrateResponse } from 'contracts/badgeHub'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
@ -21,6 +20,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const BadgeHubMigratePage: NextPage = () => {
const { badgeHub: contract } = useContracts()
@ -52,7 +52,7 @@ const BadgeHubMigratePage: NextPage = () => {
if (!contract) {
throw new Error('Smart contract connection failed')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { badgeHubLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/badgeHub/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/badgeHub/messages/query'
import type { NextPage } from 'next'
@ -19,6 +18,7 @@ import { toast } from 'react-hot-toast'
import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
import { BADGE_HUB_ADDRESS } from '../../../utils/constants'
@ -79,7 +79,7 @@ const BadgeHubQueryPage: NextPage = () => {
contractAddress,
type,
contract,
wallet,
wallet.address,
idState.value,
pubkeyState.value,
startAfterNumberState.value,
@ -106,7 +106,7 @@ const BadgeHubQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -13,7 +13,6 @@ import { baseMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/baseMinter/messages/execute'
import { dispatchExecute, previewExecutePayload } from 'contracts/baseMinter/messages/execute'
import type { NextPage } from 'next'
@ -26,6 +25,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const BaseMinterExecutePage: NextPage = () => {
const { baseMinter: contract } = useContracts()
@ -62,7 +62,7 @@ const BaseMinterExecutePage: NextPage = () => {
tokenUri: tokenUriState.value,
contract: contractState.value,
messages,
txSigner: wallet.address,
txSigner: wallet.address || '',
type,
}
const { isLoading, mutate } = useMutation(
@ -71,7 +71,7 @@ const BaseMinterExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
const txHash = await toast.promise(dispatchExecute(payload), {

View File

@ -16,7 +16,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { baseMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import type { FormEvent } from 'react'
@ -27,6 +26,7 @@ import { useMutation } from 'react-query'
import { BASE_FACTORY_ADDRESS } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
import type { CreateBaseMinterResponse } from '../../../contracts/baseFactory/contract'
import { SG721_CODE_ID } from '../../../utils/constants'
@ -149,7 +149,9 @@ const BaseMinterInstantiatePage: NextPage = () => {
return toast.promise(
contract
.use(BASE_FACTORY_ADDRESS)
?.createBaseMinter(wallet.address, msg, [coin('250000000', 'ustars')]) as Promise<CreateBaseMinterResponse>,
?.createBaseMinter(wallet.address || '', msg, [
coin('250000000', 'ustars'),
]) as Promise<CreateBaseMinterResponse>,
{
loading: 'Instantiating contract...',
error: 'Instantiation failed!',

View File

@ -9,7 +9,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { baseMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { MigrateResponse } from 'contracts/baseMinter'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
@ -21,6 +20,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const BaseMinterMigratePage: NextPage = () => {
const { baseMinter: contract } = useContracts()
@ -52,7 +52,7 @@ const BaseMinterMigratePage: NextPage = () => {
if (!contract) {
throw new Error('Smart contract connection failed')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}

View File

@ -7,7 +7,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { baseMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/baseMinter/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/baseMinter/messages/query'
import type { NextPage } from 'next'
@ -18,6 +17,7 @@ import { toast } from 'react-hot-toast'
import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const BaseMinterQueryPage: NextPage = () => {
const { baseMinter: contract } = useContracts()
@ -42,7 +42,7 @@ const BaseMinterQueryPage: NextPage = () => {
const [type, setType] = useState<QueryType>('config')
const { data: response } = useQuery(
[contractAddress, type, contract, wallet, address] as const,
[contractAddress, type, contract, wallet.address, address] as const,
async ({ queryKey }) => {
const [_contractAddress, _type, _contract, _wallet] = queryKey
const messages = contract?.use(_contractAddress)
@ -58,7 +58,7 @@ const BaseMinterQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -15,7 +15,6 @@ import { openEditionMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/openEditionMinter/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/openEditionMinter/messages/execute'
import type { NextPage } from 'next'
@ -29,6 +28,7 @@ import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const OpenEditionMinterExecutePage: NextPage = () => {
const { openEditionMinter: contract } = useContracts()
@ -93,7 +93,7 @@ const OpenEditionMinterExecutePage: NextPage = () => {
contract: contractState.value,
messages,
recipient: resolvedRecipientAddress,
txSigner: wallet.address,
txSigner: wallet.address || '',
price: priceState.value ? priceState.value.toString() : '0',
type,
}
@ -103,20 +103,21 @@ const OpenEditionMinterExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
if (contractState.value === '') {
throw new Error('Please enter the contract address.')
}
if (wallet.client && type === 'update_mint_price') {
const contractConfig = wallet.client.queryContractSmart(contractState.value, {
if (type === 'update_mint_price') {
const client = await wallet.getCosmWasmClient()
const contractConfig = client.queryContractSmart(contractState.value, {
config: {},
})
await toast
.promise(
wallet.client.queryContractSmart(contractState.value, {
client.queryContractSmart(contractState.value, {
mint_price: {},
}),
{
@ -148,7 +149,7 @@ const OpenEditionMinterExecutePage: NextPage = () => {
})
} else {
await contractConfig.then(async (config) => {
const factoryParameters = await wallet.client?.queryContractSmart(config.factory, {
const factoryParameters = await client.queryContractSmart(config.factory, {
params: {},
})
if (

View File

@ -9,7 +9,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { openEditionMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { MigrateResponse } from 'contracts/openEditionMinter'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
@ -21,6 +20,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const OpenEditionMinterMigratePage: NextPage = () => {
const { openEditionMinter: contract } = useContracts()
@ -52,7 +52,7 @@ const OpenEditionMinterMigratePage: NextPage = () => {
if (!contract) {
throw new Error('Smart contract connection failed')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { openEditionMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/openEditionMinter/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/openEditionMinter/messages/query'
import type { NextPage } from 'next'
@ -20,6 +19,7 @@ import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const OpenEditionMinterQueryPage: NextPage = () => {
const { openEditionMinter: contract } = useContracts()
@ -44,7 +44,7 @@ const OpenEditionMinterQueryPage: NextPage = () => {
const [type, setType] = useState<QueryType>('config')
const { data: response } = useQuery(
[contractAddress, type, contract, wallet, address] as const,
[contractAddress, type, contract, wallet.address, address] as const,
async ({ queryKey }) => {
const [_contractAddress, _type, _contract, _wallet] = queryKey
const messages = contract?.use(_contractAddress)
@ -63,7 +63,7 @@ const OpenEditionMinterQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -12,7 +12,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { royaltyRegistryLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/royaltyRegistry/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/royaltyRegistry/messages/execute'
import type { NextPage } from 'next'
@ -26,6 +25,7 @@ import { useMutation } from 'react-query'
import { INFINITY_SWAP_PROTOCOL_ADDRESS, ROYALTY_REGISTRY_ADDRESS } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
export const protocolList = [{ name: 'Infinity Swap', address: INFINITY_SWAP_PROTOCOL_ADDRESS }]
@ -115,7 +115,7 @@ const RoyaltyRegistryExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
const txHash = await toast.promise(dispatchExecute(payload), {

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { royaltyRegistryLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/royaltyRegistry/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/royaltyRegistry/messages/query'
import type { NextPage } from 'next'
@ -21,6 +20,7 @@ import { INFINITY_SWAP_PROTOCOL_ADDRESS, ROYALTY_REGISTRY_ADDRESS } from 'utils/
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import { protocolList } from './execute'
@ -59,7 +59,7 @@ const RoyaltyRegistryQueryPage: NextPage = () => {
const [manualProtocolInput, setManualProtocolInput] = useState(false)
const { data: response } = useQuery(
[contractAddress, type, contract, wallet, collectionAddress, protocolAddress] as const,
[contractAddress, type, contract, wallet.address, collectionAddress, protocolAddress] as const,
async ({ queryKey }) => {
const [_contractAddress, _type, _contract, _wallet, _collectionAddress, _protocolAddress] = queryKey
const messages = contract?.use(contractAddress)
@ -79,7 +79,7 @@ const RoyaltyRegistryQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -11,7 +11,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { sg721LinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/sg721/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/sg721/messages/execute'
import type { NextPage } from 'next'
@ -26,6 +25,7 @@ import { parseJson } from 'utils/json'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const Sg721ExecutePage: NextPage = () => {
const { sg721: contract } = useContracts()
@ -116,7 +116,7 @@ const Sg721ExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
const txHash = await toast.promise(dispatchExecute(payload), {

View File

@ -9,7 +9,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { sg721LinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { MigrateResponse } from 'contracts/sg721'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
@ -21,6 +20,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const Sg721MigratePage: NextPage = () => {
const { sg721: contract } = useContracts()
@ -52,7 +52,7 @@ const Sg721MigratePage: NextPage = () => {
if (!contract) {
throw new Error('Smart contract connection failed')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { sg721LinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/sg721/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/sg721/messages/query'
import type { NextPage } from 'next'
@ -20,6 +19,7 @@ import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const Sg721QueryPage: NextPage = () => {
const { sg721: contract } = useContracts()
@ -55,7 +55,7 @@ const Sg721QueryPage: NextPage = () => {
const tokenIdVisible = ['owner_of', 'approval', 'approvals', 'nft_info', 'all_nft_info'].includes(type)
const { data: response } = useQuery(
[contractAddress, type, contract, wallet, tokenId, address] as const,
[contractAddress, type, contract, wallet.address, tokenId, address] as const,
async ({ queryKey }) => {
const [_contractAddress, _type, _contract, _wallet, _tokenId, _address] = queryKey
const messages = contract?.use(contractAddress)
@ -75,7 +75,7 @@ const Sg721QueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -11,7 +11,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { splitsLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/splits/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/splits/messages/execute'
import type { NextPage } from 'next'
@ -24,6 +23,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const SplitsExecutePage: NextPage = () => {
const { splits: contract } = useContracts()
@ -64,7 +64,7 @@ const SplitsExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
const txHash = await toast.promise(dispatchExecute(payload), {

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { splitsLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { InstantiateResponse } from 'contracts/sg721'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
@ -19,6 +18,7 @@ import { useMutation } from 'react-query'
import { isValidAddress } from 'utils/isValidAddress'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
import { useInputState } from '../../../components/forms/FormInput.hooks'
import type { Attribute } from '../../../components/forms/MemberAttributes'

View File

@ -9,7 +9,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { splitsLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { MigrateResponse } from 'contracts/splits'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
@ -21,6 +20,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const SplitsMigratePage: NextPage = () => {
const { splits: contract } = useContracts()
@ -52,7 +52,7 @@ const SplitsMigratePage: NextPage = () => {
if (!contract) {
throw new Error('Smart contract connection failed')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { splitsLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/splits/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/splits/messages/query'
import type { NextPage } from 'next'
@ -20,6 +19,7 @@ import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const SplitsQueryPage: NextPage = () => {
const { splits: contract } = useContracts()
@ -64,7 +64,7 @@ const SplitsQueryPage: NextPage = () => {
contractAddress,
type,
contract,
wallet,
wallet.address,
memberAddress,
startAfterStringState.value,
paginationLimitState.value,
@ -89,7 +89,7 @@ const SplitsQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -15,7 +15,6 @@ import { vendingMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/vendingMinter/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/vendingMinter/messages/execute'
import type { NextPage } from 'next'
@ -29,6 +28,7 @@ import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const VendingMinterExecutePage: NextPage = () => {
const { vendingMinter: contract } = useContracts()
@ -101,7 +101,7 @@ const VendingMinterExecutePage: NextPage = () => {
tokenId: tokenIdState.value,
messages,
recipient: resolvedRecipientAddress,
txSigner: wallet.address,
txSigner: wallet.address || '',
price: priceState.value ? priceState.value.toString() : '0',
type,
}
@ -111,20 +111,21 @@ const VendingMinterExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
if (contractState.value === '') {
throw new Error('Please enter the contract address.')
}
if (wallet.client && type === 'update_mint_price') {
const contractConfig = wallet.client.queryContractSmart(contractState.value, {
if (type === 'update_mint_price') {
const client = await wallet.getCosmWasmClient()
const contractConfig = client.queryContractSmart(contractState.value, {
config: {},
})
await toast
.promise(
wallet.client.queryContractSmart(contractState.value, {
client.queryContractSmart(contractState.value, {
mint_price: {},
}),
{
@ -156,7 +157,7 @@ const VendingMinterExecutePage: NextPage = () => {
})
} else {
await contractConfig.then(async (config) => {
const factoryParameters = await wallet.client?.queryContractSmart(config.factory, {
const factoryParameters = await client.queryContractSmart(config.factory, {
params: {},
})
if (

View File

@ -16,7 +16,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { vendingMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import type { FormEvent } from 'react'
@ -28,6 +27,7 @@ import { VENDING_FACTORY_ADDRESS } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
import type { CreateVendingMinterResponse } from '../../../contracts/vendingFactory/contract'
@ -211,7 +211,7 @@ const VendingMinterInstantiatePage: NextPage = () => {
return toast.promise(
contract
.use(VENDING_FACTORY_ADDRESS)
?.createVendingMinter(wallet.address, msg, [
?.createVendingMinter(wallet.address || '', msg, [
coin('3000000000', 'ustars'),
]) as Promise<CreateVendingMinterResponse>,
{

View File

@ -9,7 +9,6 @@ import { LinkTabs } from 'components/LinkTabs'
import { vendingMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { MigrateResponse } from 'contracts/vendingMinter'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
@ -21,6 +20,7 @@ import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const VendingMinterMigratePage: NextPage = () => {
const { vendingMinter: contract } = useContracts()
@ -52,7 +52,7 @@ const VendingMinterMigratePage: NextPage = () => {
if (!contract) {
throw new Error('Smart contract connection failed')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { vendingMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/vendingMinter/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/vendingMinter/messages/query'
import type { NextPage } from 'next'
@ -20,6 +19,7 @@ import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const VendingMinterQueryPage: NextPage = () => {
const { vendingMinter: contract } = useContracts()
@ -44,7 +44,7 @@ const VendingMinterQueryPage: NextPage = () => {
const [type, setType] = useState<QueryType>('config')
const { data: response } = useQuery(
[contractAddress, type, contract, wallet, address] as const,
[contractAddress, type, contract, wallet.address, address] as const,
async ({ queryKey }) => {
const [_contractAddress, _type, _contract, _wallet] = queryKey
const messages = contract?.use(_contractAddress)
@ -63,7 +63,7 @@ const VendingMinterQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -24,7 +24,6 @@ import { WhitelistFlexUpload } from 'components/WhitelistFlexUpload'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/whitelist/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/whitelist/messages/execute'
import type { NextPage } from 'next'
@ -39,6 +38,7 @@ import { useDebounce } from 'utils/debounce'
import { isValidAddress } from 'utils/isValidAddress'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const WhitelistExecutePage: NextPage = () => {
const { whitelist: contract } = useContracts()
@ -143,7 +143,7 @@ const WhitelistExecutePage: NextPage = () => {
if (!type) {
throw new Error('Please select message type!')
}
if (!wallet.initialized) {
if (!wallet.isWalletConnected) {
throw new Error('Please connect your wallet.')
}
const txHash = await toast.promise(dispatchExecute(payload), {
@ -186,8 +186,8 @@ const WhitelistExecutePage: NextPage = () => {
useEffect(() => {
async function getWhitelistContractType() {
if (wallet.client && debouncedWhitelistContractState.length > 0) {
const client = wallet.client
if (wallet.isWalletConnected && debouncedWhitelistContractState.length > 0) {
const client = await wallet.getCosmWasmClient()
const data = await toast.promise(
client.queryContractRaw(
debouncedWhitelistContractState,
@ -217,7 +217,8 @@ const WhitelistExecutePage: NextPage = () => {
setWhitelistType('standard')
console.log('Unable to retrieve contract type. Defaulting to "standard".')
})
}, [debouncedWhitelistContractState, wallet.client])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [debouncedWhitelistContractState, wallet.isWalletConnected])
return (
<section className="py-6 px-12 space-y-4">

View File

@ -19,7 +19,6 @@ import { type WhitelistFlexMember, WhitelistFlexUpload } from 'components/Whitel
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { InstantiateResponse } from 'contracts/sg721'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
@ -30,6 +29,7 @@ import { useMutation } from 'react-query'
import { isValidAddress } from 'utils/isValidAddress'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
import { WHITELIST_CODE_ID, WHITELIST_FLEX_CODE_ID } from '../../../utils/constants'

View File

@ -8,7 +8,6 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { whitelistLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { QueryType } from 'contracts/whitelist/messages/query'
import { dispatchQuery, QUERY_LIST } from 'contracts/whitelist/messages/query'
import type { NextPage } from 'next'
@ -20,6 +19,7 @@ import { useQuery } from 'react-query'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const WhitelistQueryPage: NextPage = () => {
const { whitelist: contract } = useContracts()
@ -46,7 +46,7 @@ const WhitelistQueryPage: NextPage = () => {
const addressVisible = type === 'has_member'
const { data: response } = useQuery(
[contractAddress, type, contract, wallet, address] as const,
[contractAddress, type, contract, wallet.address, address] as const,
async ({ queryKey }) => {
const [_contractAddress, _type, _contract, _wallet, _address] = queryKey
const messages = contract?.use(contractAddress)
@ -65,7 +65,7 @@ const WhitelistQueryPage: NextPage = () => {
onError: (error: any) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
},
enabled: Boolean(contractAddress && contract && wallet),
enabled: Boolean(contractAddress && contract && wallet.isWalletConnected),
},
)

View File

@ -4,17 +4,16 @@ import { coins } from '@cosmjs/proto-signing'
import { ContractPageHeader } from 'components/ContractPageHeader'
import { TextInput } from 'components/forms/FormInput'
import { useInputState } from 'components/forms/FormInput.hooks'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import { useState } from 'react'
import toast from 'react-hot-toast'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { useWallet } from 'utils/wallet'
const RevokeAuthorization: NextPage = () => {
const wallet = useWallet()
const client = wallet.getClient()
const [transactionHash, setTransactionHash] = useState<string | undefined>(undefined)
@ -39,9 +38,11 @@ const RevokeAuthorization: NextPage = () => {
const revokeAuthorization = async (granteeAddress: string, msg: string) => {
console.log('Wallet Address: ', wallet.address)
try {
await wallet.connect()
const result = await client.signAndBroadcast(
wallet.address,
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
const result = await (
await wallet.getSigningCosmWasmClient()
).signAndBroadcast(
wallet.address || '',
[
{
typeUrl: '/cosmos.authz.v1beta1.MsgRevoke',

View File

@ -1,4 +0,0 @@
import { useWallet } from 'contexts/wallet'
/** @deprecated replace with {@link useWallet} */
export const useKeplr = useWallet

View File

@ -1,21 +0,0 @@
import { isOfflineDirectSigner } from '@cosmjs/proto-signing'
import { getConfig } from 'config'
import type { WalletContextType } from 'contexts/wallet'
import type { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx'
import { NETWORK } from './constants'
export const getSignatureVerificationData = async (wallet: WalletContextType, signedData: TxRaw) => {
const client = wallet.getClient()
const account = await client.getAccount(wallet.address)
return {
address: wallet.address,
chainId: getConfig(NETWORK).chainId,
signature: Buffer.from(signedData.signatures[0]),
bodyBytes: Buffer.from(signedData.bodyBytes),
authInfoBytes: Buffer.from(signedData.authInfoBytes),
accountNumber: wallet.accountNumber,
sequence: account ? account.sequence - 1 : 0, // Minus 1 because we query after making transaction
isDirectSigner: isOfflineDirectSigner(wallet.getSigner()),
}
}

View File

@ -11,13 +11,11 @@ export const checkFiles = (images: string[], metadata: string[]) => {
}
// Extract fileName from path
const fileName = path.match(
/([a-zA-Z0-9\s_\\.\-:]+)(.png|.jpg|.gif|.json)?$/i
)![1]
const fileName = /([a-zA-Z0-9\s_\\.\-:]+)(.png|.jpg|.gif|.json)?$/i.exec(path)![1]
// Check that file name is an Integer
if (isNaN(parseInt(fileName, 10))) {
throw Error('Filenames must be numbers. Invalid fileName: ' + fileName)
throw Error(`Filenames must be numbers. Invalid fileName: ${fileName}`)
}
return parseInt(fileName, 10)
}

View File

@ -1,15 +1,17 @@
import { toUtf8 } from '@cosmjs/encoding'
import type { ChainContext } from '@cosmos-kit/core'
import toast from 'react-hot-toast'
import type { KeplrWalletStore } from '../contexts/wallet'
import { SG721_NAME_ADDRESS } from './constants'
import { isValidAddress } from './isValidAddress'
export const resolveAddress = async (name: string, wallet: KeplrWalletStore): Promise<string> => {
export const resolveAddress = async (name: string, wallet: ChainContext): Promise<string> => {
if (!name.trim().endsWith('.stars')) return name.trim()
if (wallet.client) {
const tokenUri = await wallet.client
if (wallet.isWalletConnected) {
const tokenUri = await (
await wallet.getCosmWasmClient()
)
.queryContractRaw(
SG721_NAME_ADDRESS,
toUtf8(

View File

@ -1,8 +1,8 @@
// @ts-nocheck
// https://stackoverflow.com/questions/15478954/sort-array-elements-string-with-numbers-natural-sort/15479354#15479354
export function naturalCompare(a: string, b: string) {
var ax = []
var bx = []
const ax = []
const bx = []
a.replace(/(\d+)|(\D+)/g, function (_, $1, $2) {
ax.push([$1 || Infinity, $2 || ''])
})
@ -11,9 +11,9 @@ export function naturalCompare(a: string, b: string) {
})
while (ax.length && bx.length) {
var an = ax.shift()
var bn = bx.shift()
var nn = an[0] - bn[0] || an[1].localeCompare(bn[1])
const an = ax.shift()
const bn = bx.shift()
const nn = an[0] - bn[0] || an[1].localeCompare(bn[1])
if (nn) return nn
}

18
utils/wallet.ts Normal file
View File

@ -0,0 +1,18 @@
import { useChain as useCosmosKitChain } from '@cosmos-kit/react'
import { chains } from 'chain-registry'
import { getConfig } from 'config'
import { NETWORK } from './constants'
/**
* Hook to retrieve the wallet for the current chain.
*/
export const useWallet = () => {
const { chainId } = getConfig(NETWORK)
const chain = chains.find((c) => c.chain_id === chainId)
if (!chain) {
throw new Error('Chain not found')
}
return useCosmosKitChain(chain.chain_name)
}

1541
yarn.lock

File diff suppressed because it is too large Load Diff