diff --git a/.env.example b/.env.example
index e2e1a0a..386ce93 100644
--- a/.env.example
+++ b/.env.example
@@ -1,4 +1,4 @@
-APP_VERSION=0.3.5
+APP_VERSION=0.3.7
NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS
NEXT_PUBLIC_SG721_CODE_ID=274
diff --git a/components/collections/creation/UploadDetails.tsx b/components/collections/creation/UploadDetails.tsx
index 872e7d3..44ce386 100644
--- a/components/collections/creation/UploadDetails.tsx
+++ b/components/collections/creation/UploadDetails.tsx
@@ -318,11 +318,11 @@ export const UploadDetails = ({ onChange, minterType, baseMinterAcquisitionMetho
and upload your assets & metadata manually to get a base URI for your collection.
-
+
-
+
@@ -342,13 +342,13 @@ export const UploadDetails = ({ onChange, minterType, baseMinterAcquisitionMetho
and upload your asset & metadata manually to get a URI for your token before minting.
-
+
-
+
diff --git a/package.json b/package.json
index d2c8451..f85c38b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "stargaze-studio",
- "version": "0.3.6",
+ "version": "0.3.7",
"workspaces": [
"packages/*"
],
diff --git a/pages/collections/create.tsx b/pages/collections/create.tsx
index 20bf22f..ffec279 100644
--- a/pages/collections/create.tsx
+++ b/pages/collections/create.tsx
@@ -311,7 +311,10 @@ const CollectionCreationPage: NextPage = () => {
return result
})
.then((result) => {
- toast.success(`Minted successfully! Tx Hash: ${result}`, { style: { maxWidth: 'none' }, duration: 5000 })
+ toast.success(`Token minted & appended to the collection successfully! Tx Hash: ${result}`, {
+ style: { maxWidth: 'none' },
+ duration: 5000,
+ })
setIsMintingComplete(true)
})
.catch((error) => {
@@ -327,7 +330,10 @@ const CollectionCreationPage: NextPage = () => {
.use(baseMinterDetails?.existingBaseMinter as string)
?.mint(wallet.address, `${uploadDetails?.baseTokenURI?.trim()}`)
.then((result) => {
- toast.success(`Minted successfully! Tx Hash: ${result}`, { style: { maxWidth: 'none' }, duration: 5000 })
+ toast.success(`Token minted & appended to the collection successfully! Tx Hash: ${result}`, {
+ style: { maxWidth: 'none' },
+ duration: 5000,
+ })
})
.catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
@@ -661,6 +667,8 @@ const CollectionCreationPage: NextPage = () => {
if (!collectionDetails) throw new Error('Please fill out the collection details')
if (collectionDetails.name === '') throw new Error('Collection name is required')
if (collectionDetails.description === '') throw new Error('Collection description is required')
+ if (collectionDetails.description.length > 512)
+ throw new Error('Collection description cannot exceed 512 characters')
if (uploadDetails?.uploadMethod === 'new' && collectionDetails.imageFile.length === 0)
throw new Error('Collection cover image is required')
if (
@@ -673,6 +681,13 @@ const CollectionCreationPage: NextPage = () => {
Number(collectionDetails.startTradingTime) < Number(mintingDetails?.startTime)
)
throw new Error('Trading start time must be after minting start time')
+ if (collectionDetails.externalLink) {
+ try {
+ const url = new URL(collectionDetails.externalLink)
+ } catch (e: any) {
+ throw new Error(`Invalid external link: Make sure to include the protocol (e.g. https://)`)
+ }
+ }
}
const checkMintingDetails = () => {
@@ -787,7 +802,7 @@ const CollectionCreationPage: NextPage = () => {
@@ -795,7 +810,7 @@ const CollectionCreationPage: NextPage = () => {
{minterType === 'base' && baseMinterDetails?.baseMinterAcquisitionMethod === 'existing'
- ? 'Mint Token'
+ ? 'Append Token'
: 'Create Collection'}
@@ -1069,7 +1084,7 @@ const CollectionCreationPage: NextPage = () => {
onClick={performUploadAndMintChecks}
variant="solid"
>
- Upload & Mint Token
+ Mint & Append Token
diff --git a/pages/contracts/whitelist/execute.tsx b/pages/contracts/whitelist/execute.tsx
index 005c8db..b4e54e6 100644
--- a/pages/contracts/whitelist/execute.tsx
+++ b/pages/contracts/whitelist/execute.tsx
@@ -1,3 +1,4 @@
+import { Alert } from 'components/Alert'
import { Button } from 'components/Button'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
@@ -13,6 +14,7 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { whitelistLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
+import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/whitelist/messages/execute'
@@ -25,6 +27,7 @@ import { useEffect, useMemo, useState } from 'react'
import { toast } from 'react-hot-toast'
import { FaArrowRight } from 'react-icons/fa'
import { useMutation } from 'react-query'
+import { isValidAddress } from 'utils/isValidAddress'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
@@ -33,6 +36,7 @@ const WhitelistExecutePage: NextPage = () => {
const wallet = useWallet()
const [lastTx, setLastTx] = useState('')
+ const [memberList, setMemberList] = useState([])
const comboboxState = useExecuteComboboxState()
const type = comboboxState.value?.id
@@ -68,7 +72,14 @@ const WhitelistExecutePage: NextPage = () => {
type,
limit: limitState.value,
timestamp: timestamp ? (timestamp.getTime() * 1_000_000).toString() : '',
- members: addressListState.values.map((a) => a.address),
+ members: [
+ ...new Set(
+ addressListState.values
+ .map((a) => a.address.trim())
+ .filter((address) => address !== '' && isValidAddress(address.trim()) && address.startsWith('stars'))
+ .concat(memberList),
+ ),
+ ],
}
const { isLoading, mutate } = useMutation(
async (event: FormEvent) => {
@@ -145,6 +156,10 @@ const WhitelistExecutePage: NextPage = () => {
subtitle="Enter the member addresses"
title="Addresses"
/>
+
+ You may optionally choose a text file of additional member addresses.
+
+