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 { AirdropUpload } from 'components/AirdropUpload'
|
||||||
|
import { toUtf8 } from '@cosmjs/encoding'
|
||||||
import type { DispatchExecuteArgs } from 'components/badges/actions/actions'
|
import type { DispatchExecuteArgs } from 'components/badges/actions/actions'
|
||||||
import { dispatchExecute, isEitherType, previewExecutePayload } from 'components/badges/actions/actions'
|
import { dispatchExecute, isEitherType, previewExecutePayload } from 'components/badges/actions/actions'
|
||||||
import { ActionsCombobox } from 'components/badges/actions/Combobox'
|
import { ActionsCombobox } from 'components/badges/actions/Combobox'
|
||||||
@ -18,6 +19,7 @@ import { useWallet } from 'contexts/wallet'
|
|||||||
import type { Badge, BadgeHubInstance } from 'contracts/badgeHub'
|
import type { Badge, BadgeHubInstance } from 'contracts/badgeHub'
|
||||||
import * as crypto from 'crypto'
|
import * as crypto from 'crypto'
|
||||||
import { toPng } from 'html-to-image'
|
import { toPng } from 'html-to-image'
|
||||||
|
import sizeof from 'object-sizeof'
|
||||||
import { QRCodeCanvas } from 'qrcode.react'
|
import { QRCodeCanvas } from 'qrcode.react'
|
||||||
import type { FormEvent } from 'react'
|
import type { FormEvent } from 'react'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
@ -51,6 +53,8 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
|||||||
const [badge, setBadge] = useState<Badge>()
|
const [badge, setBadge] = useState<Badge>()
|
||||||
const [transferrable, setTransferrable] = useState<TransferrableType>(undefined)
|
const [transferrable, setTransferrable] = useState<TransferrableType>(undefined)
|
||||||
const [resolvedOwnerAddress, setResolvedOwnerAddress] = useState<string>('')
|
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 [createdBadgeId, setCreatedBadgeId] = useState<string | undefined>(undefined)
|
||||||
const [createdBadgeKey, setCreatedBadgeKey] = 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,
|
youtube_url: youtubeUrlState.value || undefined,
|
||||||
},
|
},
|
||||||
id: badgeId,
|
id: badgeId,
|
||||||
|
editFee,
|
||||||
owner: resolvedOwnerAddress,
|
owner: resolvedOwnerAddress,
|
||||||
pubkey: pubkeyState.value,
|
pubkey: pubkeyState.value,
|
||||||
signature: signatureState.value,
|
signature: signatureState.value,
|
||||||
@ -241,6 +246,7 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
|||||||
txSigner: wallet.address,
|
txSigner: wallet.address,
|
||||||
type,
|
type,
|
||||||
}
|
}
|
||||||
|
|
||||||
const resolveOwnerAddress = async () => {
|
const resolveOwnerAddress = async () => {
|
||||||
await resolveAddress(ownerState.value.trim(), wallet).then((resolvedAddress) => {
|
await resolveAddress(ownerState.value.trim(), wallet).then((resolvedAddress) => {
|
||||||
setResolvedOwnerAddress(resolvedAddress)
|
setResolvedOwnerAddress(resolvedAddress)
|
||||||
@ -333,6 +339,20 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
|||||||
maxSupplyState.value,
|
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(() => {
|
useEffect(() => {
|
||||||
const addresses: string[] = []
|
const addresses: string[] = []
|
||||||
airdropAllocationArray.forEach((allocation) => {
|
airdropAllocationArray.forEach((allocation) => {
|
||||||
@ -358,53 +378,56 @@ export const BadgeActions = ({ badgeHubContractAddress, badgeId, badgeHubMessage
|
|||||||
throw new Error('Please enter the Badge Hub contract addresses.')
|
throw new Error('Please enter the Badge Hub contract addresses.')
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (wallet.client && type === 'update_mint_price') {
|
if (wallet.client && type === 'edit_badge') {
|
||||||
// const contractConfig = wallet.client.queryContractSmart(minterContractAddress, {
|
const feeRateRaw = await wallet.client.queryContractRaw(
|
||||||
// config: {},
|
badgeHubContractAddress,
|
||||||
// })
|
toUtf8(Buffer.from(Buffer.from('fee_rate').toString('hex'), 'hex').toString()),
|
||||||
// await toast
|
)
|
||||||
// .promise(
|
const feeRate = JSON.parse(new TextDecoder().decode(feeRateRaw as Uint8Array))
|
||||||
// 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))
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
const txHash = await toast.promise(dispatchExecute(payload), {
|
await toast
|
||||||
error: `${type.charAt(0).toUpperCase() + type.slice(1)} execute failed!`,
|
.promise(
|
||||||
loading: 'Executing message...',
|
wallet.client.queryContractSmart(badgeHubContractAddress, {
|
||||||
success: (tx) => `Transaction ${tx} success!`,
|
badge: { id: badgeId },
|
||||||
})
|
}),
|
||||||
if (txHash) {
|
{
|
||||||
setLastTx(txHash)
|
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[]) => {
|
const airdropFileOnChange = (data: AirdropAllocation[]) => {
|
||||||
setAirdropAllocationArray(data)
|
setAirdropAllocationArray(data)
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ export type DispatchExecuteArgs = {
|
|||||||
} & (
|
} & (
|
||||||
| { type: undefined }
|
| { type: undefined }
|
||||||
| { type: Select<'create_badge'>; badge: Badge }
|
| { 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<'add_keys'>; id: number; keys: string[] }
|
||||||
| { type: Select<'purge_keys'>; id: number; limit?: number }
|
| { type: Select<'purge_keys'>; id: number; limit?: number }
|
||||||
| { type: Select<'purge_owners'>; 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)
|
return badgeHubMessages.createBadge(txSigner, args.badge)
|
||||||
}
|
}
|
||||||
case 'edit_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': {
|
case 'add_keys': {
|
||||||
return badgeHubMessages.addKeys(txSigner, args.id, args.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'
|
import type { UploadServiceType } from 'services/upload'
|
||||||
|
|
||||||
export type UploadMethod = 'new' | 'existing'
|
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 {
|
interface ImageUploadDetailsProps {
|
||||||
onChange: (value: ImageUploadDetailsDataProps) => void
|
onChange: (value: ImageUploadDetailsDataProps) => void
|
||||||
|
@ -67,7 +67,7 @@ export interface BadgeHubInstance {
|
|||||||
|
|
||||||
//Execute
|
//Execute
|
||||||
createBadge: (senderAddress: string, badge: Badge) => Promise<string>
|
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>
|
addKeys: (senderAddress: string, id: number, keys: string[]) => Promise<string>
|
||||||
purgeKeys: (senderAddress: string, id: number, limit?: number) => Promise<string>
|
purgeKeys: (senderAddress: string, id: number, limit?: number) => Promise<string>
|
||||||
purgeOwners: (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 {
|
export interface BadgeHubMessages {
|
||||||
createBadge: (badge: Badge) => CreateBadgeMessage
|
createBadge: (badge: Badge) => CreateBadgeMessage
|
||||||
editBadge: (id: number, metadata: Metadata) => EditBadgeMessage
|
editBadge: (id: number, metadata: Metadata, editFee?: number) => EditBadgeMessage
|
||||||
addKeys: (id: number, keys: string[]) => AddKeysMessage
|
addKeys: (id: number, keys: string[]) => AddKeysMessage
|
||||||
purgeKeys: (id: number, limit?: number) => PurgeKeysMessage
|
purgeKeys: (id: number, limit?: number) => PurgeKeysMessage
|
||||||
purgeOwners: (id: number, limit?: number) => PurgeOwnersMessage
|
purgeOwners: (id: number, limit?: number) => PurgeOwnersMessage
|
||||||
@ -314,7 +314,12 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
|||||||
return res.transactionHash.concat(`:${id}`)
|
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(
|
const res = await client.execute(
|
||||||
senderAddress,
|
senderAddress,
|
||||||
contractAddress,
|
contractAddress,
|
||||||
@ -326,6 +331,7 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
|||||||
},
|
},
|
||||||
'auto',
|
'auto',
|
||||||
'',
|
'',
|
||||||
|
editFee ? [coin(editFee, 'ustars')] : [],
|
||||||
)
|
)
|
||||||
|
|
||||||
return res.transactionHash
|
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 {
|
return {
|
||||||
sender: txSigner,
|
sender: txSigner,
|
||||||
contract: contractAddress,
|
contract: contractAddress,
|
||||||
@ -534,7 +540,7 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
|
|||||||
metadata,
|
metadata,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
funds: [],
|
funds: editFee ? [coin(editFee, 'ustars')] : [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ const BadgeActionsPage: NextPage = () => {
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
setMintRule('by_key')
|
setMintRule('not_resolved')
|
||||||
console.log('Unable to retrieve Mint Rule. Defaulting to "by_key".')
|
console.log('Unable to retrieve Mint Rule. Defaulting to "by_key".')
|
||||||
})
|
})
|
||||||
}, [debouncedBadgeHubContractState, debouncedBadgeIdState, wallet.client])
|
}, [debouncedBadgeHubContractState, debouncedBadgeIdState, wallet.client])
|
||||||
@ -132,14 +132,16 @@ const BadgeActionsPage: NextPage = () => {
|
|||||||
<AddressInput {...badgeHubContractState} className="mr-2" />
|
<AddressInput {...badgeHubContractState} className="mr-2" />
|
||||||
<div className="flex-row">
|
<div className="flex-row">
|
||||||
<NumberInput className="w-1/2" {...badgeIdState} />
|
<NumberInput className="w-1/2" {...badgeIdState} />
|
||||||
<span className="mt-1 font-bold">Mint Rule: </span>
|
<div className="mt-2">
|
||||||
<span>
|
<span className="font-bold">Mint Rule: </span>
|
||||||
{mintRule
|
<span>
|
||||||
.toString()
|
{mintRule
|
||||||
.split('_')
|
.toString()
|
||||||
.map((s) => s.charAt(0).toUpperCase() + s.substring(1))
|
.split('_')
|
||||||
.join(' ')}
|
.map((s) => s.charAt(0).toUpperCase() + s.substring(1))
|
||||||
</span>
|
.join(' ')}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
|
Loading…
Reference in New Issue
Block a user