Calculate editBadge() fee on the go
This commit is contained in:
parent
e1adf87dac
commit
080c74a110
@ -1,4 +1,5 @@
|
||||
// import { AirdropUpload } from 'components/AirdropUpload'
|
||||
import { toUtf8 } from '@cosmjs/encoding'
|
||||
import type { DispatchExecuteArgs } from 'components/badges/actions/actions'
|
||||
import { dispatchExecute, isEitherType, previewExecutePayload } from 'components/badges/actions/actions'
|
||||
import { ActionsCombobox } from 'components/badges/actions/Combobox'
|
||||
@ -18,6 +19,7 @@ import { useWallet } from 'contexts/wallet'
|
||||
import type { Badge, BadgeHubInstance } from 'contracts/badgeHub'
|
||||
import * as crypto from 'crypto'
|
||||
import { toPng } from 'html-to-image'
|
||||
import sizeof from 'object-sizeof'
|
||||
import { QRCodeCanvas } from 'qrcode.react'
|
||||
import type { FormEvent } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
@ -51,6 +53,8 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
||||
const [badge, setBadge] = useState<Badge>()
|
||||
const [transferrable, setTransferrable] = useState<TransferrableType>(undefined)
|
||||
const [resolvedOwnerAddress, setResolvedOwnerAddress] = useState<string>('')
|
||||
const [editFee, setEditFee] = useState<number | undefined>(undefined)
|
||||
const [dispatch, setDispatch] = useState<boolean>(false)
|
||||
|
||||
const [createdBadgeId, setCreatedBadgeId] = useState<string | undefined>(undefined)
|
||||
const [createdBadgeKey, setCreatedBadgeKey] = useState<string | undefined>(undefined)
|
||||
@ -229,6 +233,7 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
||||
youtube_url: youtubeUrlState.value || undefined,
|
||||
},
|
||||
id: badgeId,
|
||||
editFee,
|
||||
owner: resolvedOwnerAddress,
|
||||
pubkey: pubkeyState.value,
|
||||
signature: signatureState.value,
|
||||
@ -241,6 +246,7 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
||||
txSigner: wallet.address,
|
||||
type,
|
||||
}
|
||||
|
||||
const resolveOwnerAddress = async () => {
|
||||
await resolveAddress(ownerState.value.trim(), wallet).then((resolvedAddress) => {
|
||||
setResolvedOwnerAddress(resolvedAddress)
|
||||
@ -333,6 +339,20 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
||||
maxSupplyState.value,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
if (attributesState.values.length === 0)
|
||||
attributesState.add({
|
||||
trait_type: '',
|
||||
value: '',
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
void dispatchEditBadge().catch((err) => {
|
||||
toast.error(String(err), { style: { maxWidth: 'none' } })
|
||||
})
|
||||
}, [dispatch])
|
||||
|
||||
useEffect(() => {
|
||||
const addresses: string[] = []
|
||||
airdropAllocationArray.forEach((allocation) => {
|
||||
@ -358,53 +378,56 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
||||
throw new Error('Please enter the Badge Hub contract addresses.')
|
||||
}
|
||||
|
||||
// if (wallet.client && type === 'update_mint_price') {
|
||||
// const contractConfig = wallet.client.queryContractSmart(minterContractAddress, {
|
||||
// config: {},
|
||||
// })
|
||||
// await toast
|
||||
// .promise(
|
||||
// wallet.client.queryContractSmart(minterContractAddress, {
|
||||
// mint_price: {},
|
||||
// }),
|
||||
// {
|
||||
// error: `Querying mint price failed!`,
|
||||
// loading: 'Querying current mint price...',
|
||||
// success: (price) => {
|
||||
// console.log('Current mint price: ', price)
|
||||
// return `Current mint price is ${Number(price.public_price.amount) / 1000000} STARS`
|
||||
// },
|
||||
// },
|
||||
// )
|
||||
// .then(async (price) => {
|
||||
// if (Number(price.public_price.amount) / 1000000 <= priceState.value) {
|
||||
// await contractConfig
|
||||
// .then((config) => {
|
||||
// console.log(config.start_time, Date.now() * 1000000)
|
||||
// if (Number(config.start_time) < Date.now() * 1000000) {
|
||||
// throw new Error(
|
||||
// `Minting has already started on ${new Date(
|
||||
// Number(config.start_time) / 1000000,
|
||||
// ).toLocaleString()}. Updated mint price cannot be higher than the current price of ${
|
||||
// Number(price.public_price.amount) / 1000000
|
||||
// } STARS`,
|
||||
// )
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// throw new Error(String(error).substring(String(error).lastIndexOf('Error:') + 7))
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
if (wallet.client && type === 'edit_badge') {
|
||||
const feeRateRaw = await wallet.client.queryContractRaw(
|
||||
badgeHubContractAddress,
|
||||
toUtf8(Buffer.from(Buffer.from('fee_rate').toString('hex'), 'hex').toString()),
|
||||
)
|
||||
const feeRate = JSON.parse(new TextDecoder().decode(feeRateRaw as Uint8Array))
|
||||
|
||||
const txHash = await toast.promise(dispatchExecute(payload), {
|
||||
error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`,
|
||||
loading: 'Executing message...',
|
||||
success: (tx) => `Transaction ${tx} success!`,
|
||||
})
|
||||
if (txHash) {
|
||||
setLastTx(txHash)
|
||||
await toast
|
||||
.promise(
|
||||
wallet.client.queryContractSmart(badgeHubContractAddress, {
|
||||
badge: { id: badgeId },
|
||||
}),
|
||||
{
|
||||
error: `Edit Fee calculation failed!`,
|
||||
loading: 'Calculating Edit Fee...',
|
||||
success: (currentBadge) => {
|
||||
console.log('Current badge: ', currentBadge)
|
||||
return `Current metadata is ${
|
||||
Number(sizeof(currentBadge.metadata)) + Number(sizeof(currentBadge.metadata.attributes))
|
||||
} bytes in size.`
|
||||
},
|
||||
},
|
||||
)
|
||||
.then((currentBadge) => {
|
||||
const currentBadgeMetadataSize =
|
||||
Number(sizeof(currentBadge.metadata)) + Number(sizeof(currentBadge.metadata.attributes))
|
||||
console.log('Current badge metadata size: ', currentBadgeMetadataSize)
|
||||
const newBadgeMetadataSize = Number(sizeof(badge?.metadata)) + Number(sizeof(badge?.metadata.attributes))
|
||||
console.log('New badge metadata size: ', newBadgeMetadataSize)
|
||||
if (newBadgeMetadataSize > currentBadgeMetadataSize) {
|
||||
const calculatedFee = ((newBadgeMetadataSize - currentBadgeMetadataSize) * Number(feeRate.metadata)) / 2
|
||||
setEditFee(calculatedFee)
|
||||
setDispatch(!dispatch)
|
||||
} else {
|
||||
setEditFee(undefined)
|
||||
setDispatch(!dispatch)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
throw new Error(String(error).substring(String(error).lastIndexOf('Error:') + 7))
|
||||
})
|
||||
} else {
|
||||
const txHash = await toast.promise(dispatchExecute(payload), {
|
||||
error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`,
|
||||
loading: 'Executing message...',
|
||||
success: (tx) => `Transaction ${tx} success!`,
|
||||
})
|
||||
if (txHash) {
|
||||
setLastTx(txHash)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -414,6 +437,19 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
||||
},
|
||||
)
|
||||
|
||||
const dispatchEditBadge = async () => {
|
||||
if (type) {
|
||||
const txHash = await toast.promise(dispatchExecute(payload), {
|
||||
error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`,
|
||||
loading: 'Executing message...',
|
||||
success: (tx) => `Transaction ${tx} success!`,
|
||||
})
|
||||
if (txHash) {
|
||||
setLastTx(txHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const airdropFileOnChange = (data: AirdropAllocation[]) => {
|
||||
setAirdropAllocationArray(data)
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ export type DispatchExecuteArgs = {
|
||||
} & (
|
||||
| { type: undefined }
|
||||
| { type: Select<'create_badge'>; badge: Badge }
|
||||
| { type: Select<'edit_badge'>; id: number; metadata: Metadata }
|
||||
| { type: Select<'edit_badge'>; id: number; metadata: Metadata; editFee?: number }
|
||||
| { type: Select<'add_keys'>; id: number; keys: string[] }
|
||||
| { type: Select<'purge_keys'>; id: number; limit?: number }
|
||||
| { type: Select<'purge_owners'>; id: number; limit?: number }
|
||||
@ -120,7 +120,7 @@ export const dispatchExecute = async (args: DispatchExecuteArgs) => {
|
||||
return badgeHubMessages.createBadge(txSigner, args.badge)
|
||||
}
|
||||
case 'edit_badge': {
|
||||
return badgeHubMessages.editBadge(txSigner, args.id, args.metadata)
|
||||
return badgeHubMessages.editBadge(txSigner, args.id, args.metadata, args.editFee)
|
||||
}
|
||||
case 'add_keys': {
|
||||
return badgeHubMessages.addKeys(txSigner, args.id, args.keys)
|
||||
|
@ -15,7 +15,7 @@ import { toast } from 'react-hot-toast'
|
||||
import type { UploadServiceType } from 'services/upload'
|
||||
|
||||
export type UploadMethod = 'new' | 'existing'
|
||||
export type MintRule = 'by_key' | 'by_minter' | 'by_keys'
|
||||
export type MintRule = 'by_key' | 'by_minter' | 'by_keys' | 'not_resolved'
|
||||
|
||||
interface ImageUploadDetailsProps {
|
||||
onChange: (value: ImageUploadDetailsDataProps) => void
|
||||
|
@ -67,7 +67,7 @@ export interface BadgeHubInstance {
|
||||
|
||||
//Execute
|
||||
createBadge: (senderAddress: string, badge: Badge) => Promise<string>
|
||||
editBadge: (senderAddress: string, id: number, metadata: Metadata) => Promise<string>
|
||||
editBadge: (senderAddress: string, id: number, metadata: Metadata, editFee?: number) => Promise<string>
|
||||
addKeys: (senderAddress: string, id: number, keys: string[]) => Promise<string>
|
||||
purgeKeys: (senderAddress: string, id: number, limit?: number) => Promise<string>
|
||||
purgeOwners: (senderAddress: string, id: number, limit?: number) => Promise<string>
|
||||
@ -79,7 +79,7 @@ export interface BadgeHubInstance {
|
||||
|
||||
export interface BadgeHubMessages {
|
||||
createBadge: (badge: Badge) => CreateBadgeMessage
|
||||
editBadge: (id: number, metadata: Metadata) => EditBadgeMessage
|
||||
editBadge: (id: number, metadata: Metadata, editFee?: number) => EditBadgeMessage
|
||||
addKeys: (id: number, keys: string[]) => AddKeysMessage
|
||||
purgeKeys: (id: number, limit?: number) => PurgeKeysMessage
|
||||
purgeOwners: (id: number, limit?: number) => PurgeOwnersMessage
|
||||
@ -314,7 +314,12 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
||||
return res.transactionHash.concat(`:${id}`)
|
||||
}
|
||||
|
||||
const editBadge = async (senderAddress: string, id: number, metadata: Metadata): Promise<string> => {
|
||||
const editBadge = async (
|
||||
senderAddress: string,
|
||||
id: number,
|
||||
metadata: Metadata,
|
||||
editFee?: number,
|
||||
): Promise<string> => {
|
||||
const res = await client.execute(
|
||||
senderAddress,
|
||||
contractAddress,
|
||||
@ -326,6 +331,7 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
||||
},
|
||||
'auto',
|
||||
'',
|
||||
editFee ? [coin(editFee, 'ustars')] : [],
|
||||
)
|
||||
|
||||
return res.transactionHash
|
||||
@ -524,7 +530,7 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
||||
}
|
||||
}
|
||||
|
||||
const editBadge = (id: number, metadata: Metadata): EditBadgeMessage => {
|
||||
const editBadge = (id: number, metadata: Metadata, editFee?: number): EditBadgeMessage => {
|
||||
return {
|
||||
sender: txSigner,
|
||||
contract: contractAddress,
|
||||
@ -534,7 +540,7 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
||||
metadata,
|
||||
},
|
||||
},
|
||||
funds: [],
|
||||
funds: editFee ? [coin(editFee, 'ustars')] : [],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ const BadgeActionsPage: NextPage = () => {
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
setMintRule('by_key')
|
||||
setMintRule('not_resolved')
|
||||
console.log('Unable to retrieve Mint Rule. Defaulting to "by_key".')
|
||||
})
|
||||
}, [debouncedBadgeHubContractState, debouncedBadgeIdState, wallet.client])
|
||||
@ -132,14 +132,16 @@ const BadgeActionsPage: NextPage = () => {
|
||||
<AddressInput {...badgeHubContractState} className="mr-2" />
|
||||
<div className="flex-row">
|
||||
<NumberInput className="w-1/2" {...badgeIdState} />
|
||||
<span className="mt-1 font-bold">Mint Rule: </span>
|
||||
<span>
|
||||
{mintRule
|
||||
.toString()
|
||||
.split('_')
|
||||
.map((s) => s.charAt(0).toUpperCase() + s.substring(1))
|
||||
.join(' ')}
|
||||
</span>
|
||||
<div className="mt-2">
|
||||
<span className="font-bold">Mint Rule: </span>
|
||||
<span>
|
||||
{mintRule
|
||||
.toString()
|
||||
.split('_')
|
||||
.map((s) => s.charAt(0).toUpperCase() + s.substring(1))
|
||||
.join(' ')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
|
Loading…
Reference in New Issue
Block a user