From 4f1a37654e8b35330dc9757cc38b2a2f6d478795 Mon Sep 17 00:00:00 2001 From: Serkan Reis Date: Mon, 6 Mar 2023 21:49:05 +0300 Subject: [PATCH] Display badge creation fee estimate --- components/badges/creation/BadgeDetails.tsx | 55 ++++++++++++++++----- pages/badges/create.tsx | 39 +++++++++++++++ 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/components/badges/creation/BadgeDetails.tsx b/components/badges/creation/BadgeDetails.tsx index babf6c4..46a25b3 100644 --- a/components/badges/creation/BadgeDetails.tsx +++ b/components/badges/creation/BadgeDetails.tsx @@ -3,7 +3,9 @@ /* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import { toUtf8 } from '@cosmjs/encoding' import clsx from 'clsx' +import { Conditional } from 'components/Conditional' import { FormControl } from 'components/FormControl' import { useInputState, useNumberInputState } from 'components/forms/FormInput.hooks' import { useMetadataAttributesState } from 'components/forms/MetadataAttributes.hooks' @@ -13,6 +15,7 @@ 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 { AddressInput, NumberInput, TextInput } from '../../forms/FormInput' import { MetadataAttributes } from '../../forms/MetadataAttributes' @@ -22,6 +25,7 @@ interface BadgeDetailsProps { onChange: (data: BadgeDetailsDataProps) => void uploadMethod: UploadMethod | undefined mintRule: MintRule + metadataSize: number } export interface BadgeDetailsDataProps { @@ -39,11 +43,12 @@ export interface BadgeDetailsDataProps { youtube_url?: string } -export const BadgeDetails = ({ onChange }: BadgeDetailsProps) => { +export const BadgeDetails = ({ metadataSize, onChange }: BadgeDetailsProps) => { const wallet = useWallet() const [timestamp, setTimestamp] = useState(undefined) const [transferrable, setTransferrable] = useState(false) const [metadataFile, setMetadataFile] = useState() + const [metadataFeeRate, setMetadataFeeRate] = useState(0) const metadataFileRef = useRef(null) @@ -259,6 +264,26 @@ export const BadgeDetails = ({ onChange }: BadgeDetailsProps) => { youtubeUrlState.value, ]) + useEffect(() => { + const retrieveFeeRate = async () => { + try { + if (wallet.client) { + const feeRateRaw = await wallet.client.queryContractRaw( + BADGE_HUB_ADDRESS, + toUtf8(Buffer.from(Buffer.from('fee_rate').toString('hex'), 'hex').toString()), + ) + console.log('Fee Rate Raw: ', feeRateRaw) + const feeRate = JSON.parse(new TextDecoder().decode(feeRateRaw as Uint8Array)) + setMetadataFeeRate(Number(feeRate.metadata)) + } + } catch (error) { + toast.error('Error retrieving metadata fee rate.') + console.log('Error retrieving fee rate: ', error) + } + } + void retrieveFeeRate() + }, [wallet.client]) + return (
@@ -272,16 +297,24 @@ export const BadgeDetails = ({ onChange }: BadgeDetailsProps) => { setTimestamp(date)} value={timestamp} /> -
- +
+
+ +
+ +
+
Fee Estimate:
+ {(metadataSize * Number(metadataFeeRate)) / 1000000} stars +
+
diff --git a/pages/badges/create.tsx b/pages/badges/create.tsx index 3f510b3..3763984 100644 --- a/pages/badges/create.tsx +++ b/pages/badges/create.tsx @@ -23,12 +23,14 @@ import { useInputState } from 'components/forms/FormInput.hooks' import { Tooltip } from 'components/Tooltip' import { useContracts } from 'contexts/contracts' 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' import * as crypto from 'crypto' import { toPng } from 'html-to-image' import type { NextPage } from 'next' import { NextSeo } from 'next-seo' +import sizeof from 'object-sizeof' import { QRCodeSVG } from 'qrcode.react' import { useEffect, useMemo, useRef, useState } from 'react' import { toast } from 'react-hot-toast' @@ -60,6 +62,7 @@ const BadgeCreationPage: NextPage = () => { const [readyToCreateBadge, setReadyToCreateBadge] = useState(false) const [mintRule, setMintRule] = useState('by_key') const [resolvedMinterAddress, setResolvedMinterAddress] = useState('') + const [tempBadge, setTempBadge] = useState() const [badgeId, setBadgeId] = useState(null) const [imageUrl, setImageUrl] = useState(null) @@ -139,6 +142,37 @@ const BadgeCreationPage: NextPage = () => { void resolveMinterAddress() }, [designatedMinterState.value]) + useEffect(() => { + const badge = { + manager: badgeDetails?.manager as string, + metadata: { + name: badgeDetails?.name || undefined, + description: badgeDetails?.description || undefined, + image: imageUrl || undefined, + image_data: badgeDetails?.image_data || undefined, + external_url: badgeDetails?.external_url || undefined, + attributes: badgeDetails?.attributes || undefined, + background_color: badgeDetails?.background_color || undefined, + animation_url: badgeDetails?.animation_url || undefined, + youtube_url: badgeDetails?.youtube_url || undefined, + }, + transferrable: badgeDetails?.transferrable as boolean, + rule: + mintRule === 'by_key' + ? { + by_key: keyState.value, + } + : mintRule === 'by_minter' + ? { + by_minter: resolvedMinterAddress, + } + : 'by_keys', + expiry: badgeDetails?.expiry || undefined, + max_supply: badgeDetails?.max_supply || undefined, + } + setTempBadge(badge) + }, [badgeDetails, keyState.value, mintRule, resolvedMinterAddress, imageUrl]) + const createNewBadge = async () => { try { if (!wallet.initialized) throw new Error('Wallet not connected') @@ -672,6 +706,11 @@ const BadgeCreationPage: NextPage = () => {