Merge branch 'develop' into noah/cosmos-kit

This commit is contained in:
Serkan Reis 2023-10-15 20:46:20 +03:00 committed by GitHub
commit d6cc8a700f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 159 additions and 26 deletions

View File

@ -3,6 +3,7 @@ APP_VERSION=0.7.11
NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS
NEXT_PUBLIC_SG721_CODE_ID=2595
NEXT_PUBLIC_SG721_UPDATABLE_CODE_ID=2596
NEXT_PUBLIC_STRDST_SG721_CODE_ID=2595
NEXT_PUBLIC_OPEN_EDITION_SG721_CODE_ID=2595
NEXT_PUBLIC_OPEN_EDITION_SG721_UPDATABLE_CODE_ID=2596
NEXT_PUBLIC_VENDING_MINTER_CODE_ID=2600
@ -27,6 +28,7 @@ NEXT_PUBLIC_VENDING_FACTORY_UPDATABLE_FLEX_ADDRESS=
# NEXT_PUBLIC_VENDING_NATIVE_STARDUST_FACTORY_ADDRESS="stars1mxwf2hjcjvqnlw0v3j7m0u34975qesp325wzrgz0ht7vr8ys2zmsenjutf"
# NEXT_PUBLIC_VENDING_NATIVE_STARDUST_UPDATABLE_FACTORY_ADDRESS="stars18gjczf88jd4z3a3megwj9g5c9famu654csxfnnq59mkqeszuzy4ssdgr46"
# NEXT_PUBLIC_VENDING_NATIVE_STRDST_FLEX_FACTORY_ADDRESS="stars1..."
NEXT_PUBLIC_BASE_FACTORY_ADDRESS="stars1a45hcxty3spnmm2f0papl8v4dk5ew29s4syhn4efte8u5haex99qlkrtnx"
NEXT_PUBLIC_BASE_FACTORY_UPDATABLE_ADDRESS="stars100xegx2syry4tclkmejjwxk4nfqahvcqhm9qxut5wxuzhj5d9qfsh5nmym"

View File

@ -8,7 +8,7 @@ export function FaviconsMetaTags() {
<link href="/assets/manifest.webmanifest" rel="manifest" />
<meta content="yes" name="mobile-web-app-capable" />
<meta content="#F0827D" name="theme-color" />
<meta content="StargazeStudio" name="application-name" />
<meta content="Stargaze Studio" name="application-name" />
<link href="/assets/apple-touch-icon-57x57.png" rel="apple-touch-icon" sizes="57x57" />
<link href="/assets/apple-touch-icon-60x60.png" rel="apple-touch-icon" sizes="60x60" />
<link href="/assets/apple-touch-icon-72x72.png" rel="apple-touch-icon" sizes="72x72" />
@ -22,7 +22,7 @@ export function FaviconsMetaTags() {
<link href="/assets/apple-touch-icon-1024x1024.png" rel="apple-touch-icon" sizes="1024x1024" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="black-translucent" name="apple-mobile-web-app-status-bar-style" />
<meta content="StargazeStudio" name="apple-mobile-web-app-title" />
<meta content="Stargaze Studio" name="apple-mobile-web-app-title" />
<link
href="/assets/apple-touch-startup-image-640x1136.png"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"

View File

@ -47,9 +47,9 @@ export const Layout = ({ children, metadata = {} }: LayoutProps) => {
<FaDesktop size={48} />
<h1 className="text-2xl font-bold">Unsupported Viewport</h1>
<p>
StargazeStudio is best viewed on the big screen.
Stargaze Studio is best viewed on the big screen.
<br />
Please open StargazeStudio on your tablet or desktop browser.
Please open Stargaze Studio on your tablet or desktop browser.
</p>
</div>
</div>

View File

@ -181,7 +181,9 @@ export const CollectionActions = ({
type !== 'update_royalties_for_infinity_swap'
? 'Percentage of royalties to be paid'
: 'Change in share percentage',
placeholder: '5%',
placeholder: isEitherType(type, ['set_royalties_for_infinity_swap', 'update_royalties_for_infinity_swap'])
? '0.5%'
: '5%',
})
const showTokenUriField = isEitherType(type, ['mint_token_uri', 'update_token_metadata'])
@ -310,6 +312,13 @@ export const CollectionActions = ({
royaltyShareState.value,
])
useEffect(() => {
if (isEitherType(type, ['set_royalties_for_infinity_swap']) && Number(royaltyShareState.value) > 5) {
royaltyShareState.onChange('5')
toast.error('Royalty share cannot be greater than 5% for Infinity Swap')
}
}, [royaltyShareState.value])
useEffect(() => {
const addresses: string[] = []
airdropAllocationArray.forEach((allocation) => {

View File

@ -119,7 +119,7 @@ export const UploadDetails = ({
if (event.target.files === null) return
const thumbnailCompatibleAssetTypes: AssetType[] = ['video', 'audio', 'html']
const thumbnailCompatibleFileNamesList: string[] = []
if (minterType === 'vending' || (minterType === 'base' && event.target.files.length > 1)) {
if (minterType === 'vending') {
//sort the files
const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name))
//check if the sorted file names are in numerical order
@ -146,6 +146,38 @@ export const UploadDetails = ({
return
}
}
} else if (minterType === 'base' && event.target.files.length > 1) {
//sort the files
const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name))
//check if the sorted file names are in numerical order
const sortedFileNames = sortedFiles.map((file) => file.name.split('.')[0])
sortedFiles.map((file) => {
if (thumbnailCompatibleAssetTypes.includes(getAssetType(file.name))) {
thumbnailCompatibleFileNamesList.push(file.name.split('.')[0])
}
})
setThumbnailCompatibleAssetFileNames(thumbnailCompatibleFileNamesList)
console.log('Thumbnail Compatible Files: ', thumbnailCompatibleFileNamesList)
for (let i = 0; i < sortedFileNames.length - 1; i++) {
if (
isNaN(Number(sortedFileNames[i])) ||
isNaN(Number(sortedFileNames[i + 1])) ||
parseInt(sortedFileNames[i]) !== parseInt(sortedFileNames[i + 1]) - 1
) {
toast.error('The file names should be in numerical order.')
setThumbnailCompatibleAssetFileNames([])
addLogItem({
id: uid(),
message: 'The file names should be in numerical order.',
type: 'Error',
timestamp: new Date(),
})
//clear the input
event.target.value = ''
return
}
}
} else if (minterType === 'base' && event.target.files.length === 1) {
if (thumbnailCompatibleAssetTypes.includes(getAssetType(event.target.files[0].name))) {
thumbnailCompatibleFileNamesList.push(event.target.files[0].name.split('.')[0])
@ -186,7 +218,23 @@ export const UploadDetails = ({
event.target.value = ''
return toast.error('The number of metadata files should be equal to the number of asset files.')
}
if (minterType === 'vending' || (minterType === 'base' && assetFilesArray.length > 1)) {
// compare the first file name for asset and metadata files
if (
minterType === 'base' &&
assetFilesArray.length > 1 &&
event.target.files[0].name.split('.')[0] !== assetFilesArray[0].name.split('.')[0]
) {
event.target.value = ''
toast.error('The metadata file names should match the asset file names.')
addLogItem({
id: uid(),
message: 'The metadata file names should match the asset file names.',
type: 'Error',
timestamp: new Date(),
})
return
}
if (minterType === 'vending') {
//sort the files
const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name))
//check if the sorted file names are in numerical order
@ -204,6 +252,28 @@ export const UploadDetails = ({
return
}
}
} else if (minterType === 'base' && assetFilesArray.length > 1) {
//sort the files
const sortedFiles = Array.from(event.target.files).sort((a, b) => naturalCompare(a.name, b.name))
//check if the sorted file names are in numerical order
const sortedFileNames = sortedFiles.map((file) => file.name.split('.')[0])
for (let i = 0; i < sortedFileNames.length - 1; i++) {
if (
isNaN(Number(sortedFileNames[i])) ||
isNaN(Number(sortedFileNames[i + 1])) ||
parseInt(sortedFileNames[i]) !== parseInt(sortedFileNames[i + 1]) - 1
) {
toast.error('The file names should be in numerical order.')
addLogItem({
id: uid(),
message: 'The file names should be in numerical order.',
type: 'Error',
timestamp: new Date(),
})
event.target.value = ''
return
}
}
}
let loadedFileCount = 0
const files: File[] = []

View File

@ -226,7 +226,7 @@ export const CollectionDetails = ({
<FormControl
className={clsx('mt-2')}
htmlId="timestamp"
subtitle="Trading start time offset will be set as 2 weeks by default."
subtitle="Trading start time offset will be set as 1 week by default."
title={`Trading Start Time (optional | ${timezone === 'Local' ? 'local)' : 'UTC)'}`}
>
<InputDateTime

View File

@ -711,7 +711,7 @@ export const OpenEditionMinterCreator = ({
return (
<div>
{/* TODO: Cancel once we're able to index on-chain metadata */}
<Conditional test>
<Conditional test={false}>
<div className="mx-10 mb-4 rounded border-2 border-white/20">
<div className="flex justify-center mb-2">
<div className="mt-3 ml-4 font-bold form-check form-check-inline">

View File

@ -1,9 +1,9 @@
{
"path": "/assets/",
"appName": "StargazeStudio",
"appShortName": "StargazeStudio",
"appName": "Stargaze Studio",
"appShortName": "Stargaze Studio",
"appDescription": "Stargaze Studio is built to provide useful smart contract interfaces that help you build and deploy your own NFT collection in no time.",
"developerName": "StargazeStudio",
"developerName": "Stargaze Studio",
"developerURL": "https://",
"background": "#FFC27D",
"theme_color": "#FFC27D",

View File

@ -6,6 +6,6 @@ export const meta = {
domain: 'stargaze.tools',
url: faviconsJson.developerURL,
twitter: {
username: '@stargazestudio',
username: '@StargazeZone',
},
}

View File

@ -21,6 +21,7 @@ import {
VENDING_IBC_USDC_UPDATABLE_FACTORY_FLEX_ADDRESS,
VENDING_NATIVE_STARDUST_FACTORY_ADDRESS,
VENDING_NATIVE_STARDUST_UPDATABLE_FACTORY_ADDRESS,
VENDING_NATIVE_STRDST_FLEX_FACTORY_ADDRESS,
} from 'utils/constants'
import type { TokenInfo } from './token'
@ -224,6 +225,14 @@ export const flexibleVendingUpdatableIbcUsdcMinter: MinterInfo = {
flexible: true,
}
export const flexibleVendingStrdstMinter: MinterInfo = {
id: 'flexible-vending-native-strdst-minter',
factoryAddress: VENDING_NATIVE_STRDST_FLEX_FACTORY_ADDRESS,
supportedToken: nativeStardust,
updatable: false,
flexible: true,
}
export const flexibleVendingMinterList = [
flexibleVendingStarsMinter,
flexibleVendingUpdatableStarsMinter,
@ -231,4 +240,5 @@ export const flexibleVendingMinterList = [
flexibleVendingUpdatableIbcAtomMinter,
flexibleVendingIbcUsdcMinter,
flexibleVendingUpdatableIbcUsdcMinter,
flexibleVendingStrdstMinter,
]

View File

@ -33,13 +33,13 @@ export interface BaseMinterInstance {
//Execute
mint: (senderAddress: string, tokenUri: string) => Promise<string>
updateStartTradingTime: (senderAddress: string, time?: Timestamp) => Promise<string>
batchMint: (senderAddress: string, recipient: string, batchCount: number) => Promise<string>
batchMint: (senderAddress: string, recipient: string, batchCount: number, startFrom: number) => Promise<string>
}
export interface BaseMinterMessages {
mint: (tokenUri: string) => MintMessage
updateStartTradingTime: (time: Timestamp) => UpdateStartTradingTimeMessage
batchMint: (recipient: string, batchNumber: number) => CustomMessage
batchMint: (recipient: string, batchNumber: number, startFrom: number) => CustomMessage
}
export interface MintMessage {
@ -178,7 +178,12 @@ export const baseMinter = (client: SigningCosmWasmClient, txSigner: string): Bas
return res.transactionHash
}
const batchMint = async (senderAddress: string, baseUri: string, batchCount: number): Promise<string> => {
const batchMint = async (
senderAddress: string,
baseUri: string,
batchCount: number,
startFrom: number,
): Promise<string> => {
const txHash = await getConfig().then(async (response) => {
const factoryParameters = await toast.promise(getFactoryParameters(response?.config?.factory), {
loading: 'Querying Factory Parameters...',
@ -198,7 +203,7 @@ export const baseMinter = (client: SigningCosmWasmClient, txSigner: string): Bas
const executeContractMsgs: MsgExecuteContractEncodeObject[] = []
for (let i = 0; i < batchCount; i++) {
const msg = {
mint: { token_uri: `${baseUri}/${i + 1}` },
mint: { token_uri: `${baseUri}/${i + startFrom}` },
}
const executeContractMsg: MsgExecuteContractEncodeObject = {
typeUrl: '/cosmwasm.wasm.v1.MsgExecuteContract',
@ -282,10 +287,10 @@ export const baseMinter = (client: SigningCosmWasmClient, txSigner: string): Bas
}
}
const batchMint = (baseUri: string, batchCount: number): CustomMessage => {
const batchMint = (baseUri: string, batchCount: number, startFrom: number): CustomMessage => {
const msg: Record<string, unknown>[] = []
for (let i = 0; i < batchCount; i++) {
msg.push({ mint: { token_uri: `${baseUri}/${i + 1}` } })
msg.push({ mint: { token_uri: `${baseUri}/${i + startFrom}` } })
}
return {
sender: txSigner,

2
env.d.ts vendored
View File

@ -16,6 +16,7 @@ declare namespace NodeJS {
readonly NEXT_PUBLIC_SG721_CODE_ID: string
readonly NEXT_PUBLIC_SG721_UPDATABLE_CODE_ID: string
readonly NEXT_PUBLIC_STRDST_SG721_CODE_ID: string
readonly NEXT_PUBLIC_OPEN_EDITION_SG721_CODE_ID: string
readonly NEXT_PUBLIC_OPEN_EDITION_SG721_UPDATABLE_CODE_ID: string
readonly NEXT_PUBLIC_WHITELIST_CODE_ID: string
@ -36,6 +37,7 @@ declare namespace NodeJS {
readonly NEXT_PUBLIC_VENDING_IBC_USDC_UPDATABLE_FACTORY_FLEX_ADDRESS: string
readonly NEXT_PUBLIC_VENDING_NATIVE_STARDUST_FACTORY_ADDRESS: string
readonly NEXT_PUBLIC_VENDING_NATIVE_STARDUST_UPDATABLE_FACTORY_ADDRESS: string
readonly NEXT_PUBLIC_VENDING_NATIVE_STRDST_FLEX_FACTORY_ADDRESS: string
readonly NEXT_PUBLIC_OPEN_EDITION_FACTORY_ADDRESS: string
readonly NEXT_PUBLIC_OPEN_EDITION_UPDATABLE_FACTORY_ADDRESS: string
readonly NEXT_PUBLIC_OPEN_EDITION_IBC_ATOM_FACTORY_ADDRESS: string

View File

@ -59,6 +59,7 @@ import {
SG721_CODE_ID,
SG721_UPDATABLE_CODE_ID,
STARGAZE_URL,
STRDST_SG721_CODE_ID,
SYNC_COLLECTIONS_API_URL,
VENDING_FACTORY_ADDRESS,
VENDING_FACTORY_FLEX_ADDRESS,
@ -448,7 +449,12 @@ 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,
parseInt(uploadDetails.assetFiles[0].name.split('.')[0]),
)
console.log(result)
return result
})
@ -568,7 +574,11 @@ const CollectionCreationPage: NextPage = () => {
whitelist,
},
collection_params: {
code_id: collectionDetails?.updatable ? SG721_UPDATABLE_CODE_ID : SG721_CODE_ID,
code_id: collectionDetails?.updatable
? SG721_UPDATABLE_CODE_ID
: mintingDetails?.selectedMintToken?.displayName === 'STRDST'
? STRDST_SG721_CODE_ID
: SG721_CODE_ID,
name: collectionDetails?.name,
symbol: collectionDetails?.symbol,
info: {
@ -697,6 +707,7 @@ const CollectionCreationPage: NextPage = () => {
wallet.address || '',
baseUri,
uploadDetails?.assetFiles.length as number,
parseInt(uploadDetails?.assetFiles[0].name.split('.')[0] as string),
) as Promise<string>,
{
loading: 'Minting tokens...',

View File

@ -17,6 +17,9 @@ import { LinkTabs } from 'components/LinkTabs'
import { whitelistLinkTabs } from 'components/LinkTabs.data'
import { type WhitelistFlexMember, WhitelistFlexUpload } from 'components/WhitelistFlexUpload'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { vendingMinterList } from 'config/minter'
import type { TokenInfo } from 'config/token'
import { stars, tokensList } from 'config/token'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import type { InstantiateResponse } from 'contracts/sg721'
@ -46,6 +49,8 @@ const WhitelistInstantiatePage: NextPage = () => {
const [whitelistStandardArray, setWhitelistStandardArray] = useState<string[]>([])
const [whitelistFlexArray, setWhitelistFlexArray] = useState<WhitelistFlexMember[]>([])
const [selectedMintToken, setSelectedMintToken] = useState<TokenInfo | undefined>(stars)
const unitPriceState = useNumberInputState({
id: 'unit-price',
name: 'unitPrice',
@ -97,7 +102,7 @@ const WhitelistInstantiatePage: NextPage = () => {
members: whitelistStandardArray,
start_time: (startDate.getTime() * 1_000_000).toString(),
end_time: (endDate.getTime() * 1_000_000).toString(),
mint_price: coin(String(Number(unitPriceState.value) * 1000000), 'ustars'),
mint_price: coin(String(Number(unitPriceState.value) * 1000000), selectedMintToken?.denom || 'ustars'),
per_address_limit: perAddressLimitState.value,
member_limit: memberLimitState.value,
admins: [
@ -114,7 +119,7 @@ const WhitelistInstantiatePage: NextPage = () => {
members: whitelistFlexArray,
start_time: (startDate.getTime() * 1_000_000).toString(),
end_time: (endDate.getTime() * 1_000_000).toString(),
mint_price: coin(String(Number(unitPriceState.value) * 1000000), 'ustars'),
mint_price: coin(String(Number(unitPriceState.value) * 1000000), selectedMintToken?.denom || 'ustars'),
whale_cap: whaleCapState.value || undefined,
member_limit: memberLimitState.value,
admins: [
@ -261,7 +266,23 @@ const WhitelistInstantiatePage: NextPage = () => {
</FormGroup>
<FormGroup subtitle="Information about your minting settings" title="Minting Details">
<NumberInput isRequired {...unitPriceState} />
<div className="flex flex-row items-center">
<NumberInput {...unitPriceState} isRequired />
<select
className="py-[9px] px-4 mt-14 ml-2 placeholder:text-white/50 bg-white/10 rounded border-2 border-white/20 focus:ring focus:ring-plumbus-20"
onChange={(e) => setSelectedMintToken(tokensList.find((t) => t.displayName === e.target.value))}
value={selectedMintToken?.displayName}
>
{vendingMinterList
.filter((minter) => minter.factoryAddress !== undefined && minter.updatable === false)
.map((minter) => (
<option key={minter.id} className="bg-black" value={minter.supportedToken.displayName}>
{minter.supportedToken.displayName}
</option>
))}
</select>
</div>
<NumberInput isRequired {...memberLimitState} />
<Conditional test={whitelistType === 'standard'}>
<NumberInput isRequired {...perAddressLimitState} />

View File

@ -1,6 +1,6 @@
{
"name": "StargazeStudio",
"short_name": "StargazeStudio",
"name": "Stargaze Studio",
"short_name": "Stargaze Studio",
"description": "Stargaze Studio is a dApp that helps you create and manage your collections on Stargaze by providing smart contract front ends",
"dir": "auto",
"lang": "en-US",

View File

@ -1,5 +1,6 @@
export const SG721_CODE_ID = parseInt(process.env.NEXT_PUBLIC_SG721_CODE_ID, 10)
export const SG721_UPDATABLE_CODE_ID = parseInt(process.env.NEXT_PUBLIC_SG721_UPDATABLE_CODE_ID, 10)
export const STRDST_SG721_CODE_ID = parseInt(process.env.NEXT_PUBLIC_STRDST_SG721_CODE_ID, 10)
export const SG721_OPEN_EDITION_CODE_ID = parseInt(process.env.NEXT_PUBLIC_OPEN_EDITION_SG721_CODE_ID, 10)
export const SG721_OPEN_EDITION_UPDATABLE_CODE_ID = parseInt(
process.env.NEXT_PUBLIC_OPEN_EDITION_SG721_UPDATABLE_CODE_ID,
@ -28,6 +29,8 @@ export const VENDING_IBC_USDC_UPDATABLE_FACTORY_FLEX_ADDRESS =
export const VENDING_NATIVE_STARDUST_FACTORY_ADDRESS = process.env.NEXT_PUBLIC_VENDING_NATIVE_STARDUST_FACTORY_ADDRESS
export const VENDING_NATIVE_STARDUST_UPDATABLE_FACTORY_ADDRESS =
process.env.NEXT_PUBLIC_VENDING_NATIVE_STARDUST_UPDATABLE_FACTORY_ADDRESS
export const VENDING_NATIVE_STRDST_FLEX_FACTORY_ADDRESS =
process.env.NEXT_PUBLIC_VENDING_NATIVE_STRDST_FLEX_FACTORY_ADDRESS
export const BASE_FACTORY_ADDRESS = process.env.NEXT_PUBLIC_BASE_FACTORY_ADDRESS
export const BASE_FACTORY_UPDATABLE_ADDRESS = process.env.NEXT_PUBLIC_BASE_FACTORY_UPDATABLE_ADDRESS
export const OPEN_EDITION_FACTORY_ADDRESS = process.env.NEXT_PUBLIC_OPEN_EDITION_FACTORY_ADDRESS