Compare commits

..

1 Commits

Author SHA1 Message Date
Serkan Reis
e319a4306c Update config for fang-1 testnet 2024-05-05 11:41:01 +03:00
20 changed files with 1281 additions and 21454 deletions

1
.env
View File

@ -1 +0,0 @@
CERC_MAX_GENERATE_TIME=180

View File

@ -1,45 +0,0 @@
name: Publish ApplicationRecord to Registry
on:
release:
types: [published]
push:
branches:
- main
- '*'
env:
CERC_REGISTRY_USER_KEY: ${{ secrets.CICD_LACONIC_USER_KEY }}
CERC_REGISTRY_BOND_ID: ${{ secrets.CICD_LACONIC_BOND_ID }}
jobs:
cns_publish:
runs-on: ubuntu-latest
steps:
- name: "Clone project repository"
uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 18 # though you need version 14 with geojson
# - name: "Install exiftool"
# run: |
# apt-get update -y
# apt-get upgrade -y
# apt-get install exiftool -y
#- name: "Exiftool Version"
# run: |
# exiftool -ver
- name: "Install Yarn"
run: npm install -g yarn
- name: "Install registry CLI"
run: |
npm config set @cerc-io:registry https://git.vdb.to/api/packages/cerc-io/npm/
yarn global add @cerc-io/laconic-registry-cli
- name: "Install jq"
uses: dcarbone/install-jq-action@v2.1.0
- name: "Publish App Record"
run: scripts/publish-app-record.sh
#- name: "Create Metadata Record"
# run: scripts/create-metadata-record.sh
- name: "Request Deployment"
run: scripts/request-app-deployment.sh

View File

@ -298,16 +298,17 @@ export const Sidebar = () => {
>
<Link href="/contracts/royaltyRegistry/">Royalty Registry</Link>
</li>
<li
className={clsx(
'text-lg font-bold hover:text-white hover:bg-stargaze-80 rounded',
router.asPath.includes('/contracts/upload/') ? 'text-white' : 'text-gray',
)}
tabIndex={-1}
>
<Link href="/contracts/upload/">Upload Contract</Link>
</li>
<Conditional test={NETWORK === 'testnet'}>
<li
className={clsx(
'text-lg font-bold hover:text-white hover:bg-stargaze-80 rounded',
router.asPath.includes('/contracts/upload/') ? 'text-white' : 'text-gray',
)}
tabIndex={-1}
>
<Link href="/contracts/upload/">Upload Contract</Link>
</li>
</Conditional>
</ul>
</li>
</ul>

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
// Styles required for @cosmos-kit/react modal
import '@interchain-ui/react/styles'
@ -7,6 +9,7 @@ import { wallets as leapExtensionWallets } from '@cosmos-kit/leap-extension'
import { ChainProvider } from '@cosmos-kit/react'
import { assets, chains } from 'chain-registry'
import { getConfig } from 'config'
import { fangAssetList, fangTestnet } from 'config/fangTestnet'
import type { ReactNode } from 'react'
import { NETWORK } from 'utils/constants'
@ -14,8 +17,8 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => {
const { gasPrice, feeToken } = getConfig(NETWORK)
return (
<ChainProvider
assetLists={assets}
chains={chains}
assetLists={[...assets, fangAssetList]}
chains={[...chains, fangTestnet]}
endpointOptions={{
endpoints: {
stargaze: {
@ -26,6 +29,10 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => {
rpc: ['https://rpc.elgafar-1.stargaze-apis.com/'],
rest: ['https://rest.elgafar-1.stargaze-apis.com/'],
},
stargazefangtestnet: {
rpc: ['https://rpc.fang-1.stargaze-apis.com/'],
rest: ['https://rest.fang-1.stargaze-apis.com/'],
},
},
isLazy: true,
}}
@ -37,7 +44,7 @@ export const WalletProvider = ({ children }: { children: ReactNode }) => {
gasPrice: GasPrice.fromString(`${gasPrice}${feeToken}`),
}),
signingStargate: () => ({
gasPrice: GasPrice.fromString(`${gasPrice}${feeToken}`),
gasPrice: GasPrice.fromString(`${0.01}${feeToken}`),
}),
}}
wallets={[...keplrExtensionWallets, ...leapExtensionWallets]}

View File

@ -5,7 +5,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { toUtf8 } from '@cosmjs/encoding'
import type { Coin } from '@cosmjs/proto-signing'
import { coin } from '@cosmjs/proto-signing'
import axios from 'axios'
import clsx from 'clsx'
@ -14,7 +13,7 @@ import type { MinterType } from 'components/collections/actions/Combobox'
import { Conditional } from 'components/Conditional'
import { ConfirmationModal } from 'components/ConfirmationModal'
import { LoadingModal } from 'components/LoadingModal'
import { type TokenInfo, tokensList } from 'config/token'
import { type TokenInfo } from 'config/token'
import { useContracts } from 'contexts/contracts'
import { addLogItem } from 'contexts/log'
import type { DispatchExecuteArgs as OpenEditionFactoryDispatchExecuteArgs } from 'contracts/openEditionFactory/messages/execute'
@ -74,7 +73,7 @@ export interface OpenEditionMinterDetailsDataProps {
interface OpenEditionMinterCreatorProps {
onChange: (data: OpenEditionMinterCreatorDataProps) => void
onDetailsChange: (data: OpenEditionMinterDetailsDataProps) => void
openEditionMinterCreationFee?: Coin
openEditionMinterCreationFee?: string
minimumMintPrice?: string
minterType?: MinterType
mintTokenFromFactory?: TokenInfo | undefined
@ -481,45 +480,20 @@ export const OpenEditionMinterCreator = ({
const checkwalletBalance = async () => {
if (!wallet.isWalletConnected) throw new Error('Wallet not connected.')
const queryClient = await wallet.getCosmWasmClient()
const creationFeeDenom = tokensList.find((token) => token.denom === openEditionMinterCreationFee?.denom)
await queryClient.getBalance(wallet.address || '', 'ustars').then(async (starsBalance) => {
await queryClient
.getBalance(wallet.address || '', openEditionMinterCreationFee?.denom as string)
.then((creationFeeDenomBalance) => {
if (whitelistDetails?.whitelistState === 'new' && whitelistDetails.memberLimit) {
const whitelistCreationFee = Math.ceil(Number(whitelistDetails.memberLimit) / 1000) * 100000000
if (openEditionMinterCreationFee?.denom === 'ustars') {
const amountNeeded = whitelistCreationFee + Number(openEditionMinterCreationFee.amount)
if (amountNeeded >= Number(starsBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
amountNeeded / 1000000
).toString()} STARS`,
)
} else {
if (whitelistCreationFee >= Number(starsBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the whitelist. Needed amount: ${(
whitelistCreationFee / 1000000
).toString()} STARS`,
)
if (Number(openEditionMinterCreationFee?.amount) > Number(creationFeeDenomBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
Number(openEditionMinterCreationFee?.amount) / 1000000
).toString()} ${
creationFeeDenom ? creationFeeDenom.displayName : openEditionMinterCreationFee?.denom
}`,
)
}
} else if (Number(openEditionMinterCreationFee?.amount) > Number(creationFeeDenomBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
Number(openEditionMinterCreationFee?.amount) / 1000000
).toString()} ${creationFeeDenom ? creationFeeDenom.displayName : openEditionMinterCreationFee?.denom}`,
)
})
let amountNeeded = 0
if (whitelistDetails?.whitelistState === 'new' && whitelistDetails.memberLimit) {
amountNeeded =
Math.ceil(Number(whitelistDetails.memberLimit) / 1000) * 100000000 + Number(openEditionMinterCreationFee)
} else {
amountNeeded = openEditionMinterCreationFee ? Number(openEditionMinterCreationFee) : 0
}
await (await wallet.getCosmWasmClient()).getBalance(wallet.address || '', 'ustars').then((balance) => {
if (amountNeeded >= Number(balance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
amountNeeded / 1000000
).toString()} STARS`,
)
})
}
@ -925,7 +899,7 @@ export const OpenEditionMinterCreator = ({
messages: openEditionFactoryMessages,
txSigner: wallet.address || '',
msg,
funds: [openEditionMinterCreationFee as Coin],
funds: [coin(openEditionMinterCreationFee as string, 'ustars')],
updatable: collectionDetails?.updatable,
}
await openEditionFactoryDispatchExecute(payload)

127
config/fangTestnet.ts Normal file
View File

@ -0,0 +1,127 @@
import type { AssetList, Chain } from '@chain-registry/types'
export const fangTestnet: Chain = {
$schema: '../../chain.schema.json',
chain_name: 'stargazefangtestnet',
status: 'live',
network_type: 'testnet',
website: 'https://stargaze.zone/',
pretty_name: 'Fang Testnet',
chain_id: 'fang-1',
bech32_prefix: 'stars',
daemon_name: 'starsd',
node_home: '$HOME/.starsd',
slip44: 118,
fees: {
fee_tokens: [
{
denom: 'ustars',
low_gas_price: 0.3,
average_gas_price: 0.4,
high_gas_price: 0.5,
},
],
},
codebase: {
git_repo: 'https://github.com/public-awesome/stargaze',
recommended_version: 'v7.0.0',
compatible_versions: ['v7.0.0'],
cosmos_sdk_version: '0.45',
consensus: {
type: 'tendermint',
version: '0.34',
},
cosmwasm_version: '0.28',
cosmwasm_enabled: true,
genesis: {
genesis_url: 'https://github.com/public-awesome/testnets/blob/main/elgafar-1/genesis/genesis.tar.gz?raw=true',
},
versions: [
{
name: 'v7.0.0',
recommended_version: 'v7.0.0',
compatible_versions: ['v7.0.0'],
cosmos_sdk_version: '0.45',
consensus: {
type: 'tendermint',
version: '0.34',
},
cosmwasm_version: '0.28',
cosmwasm_enabled: true,
},
],
},
peers: {
seeds: [],
persistent_peers: [
{
id: 'e31886cba90a06e165b0df18cc5c8ae015ecd23e',
address: '209.159.152.82:26656',
provider: 'stargaze',
},
{
id: 'de00d2d65594b672469ecd65826a94ec1be80b9f',
address: '208.73.205.226:26656',
provider: 'stargaze',
},
{
id: '496ac0ba20188f70f41e0a814dfd4d9a617338f8',
address: 'stargaze-testnet-seed.ibs.team:16652',
provider: 'Inter Blockchain Services',
},
],
},
apis: {
rpc: [
{
address: 'https://rpc.fang-1.stargaze-apis.com',
provider: 'Stargaze Foundation',
},
],
rest: [
{
address: 'https://rest.fang-1.stargaze-apis.com',
provider: 'Stargaze Foundation',
},
],
grpc: [
{
address: 'http://grpc-1.fang-1.stargaze-apis.com:26660',
provider: 'Stargaze Foundation',
},
],
},
}
export const fangAssetList: AssetList = {
$schema: '../../assetlist.schema.json',
chain_name: 'stargazefangtestnet',
assets: [
{
description: 'The native token of Stargaze',
denom_units: [
{
denom: 'ustars',
exponent: 0,
},
{
denom: 'stars',
exponent: 6,
},
],
base: 'ustars',
name: 'Stargaze',
display: 'stars',
symbol: 'STARS',
logo_URIs: {
png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/stargaze/images/stars.png',
},
coingecko_id: 'stargaze',
images: [
{
png: 'https://raw.githubusercontent.com/cosmos/chain-registry/master/stargaze/images/stars.png',
},
],
},
],
}

View File

@ -19,6 +19,25 @@ export const mainnetConfig: AppConfig = {
},
}
export const fangTestnetConfig: AppConfig = {
chainId: 'fang-1',
chainName: 'fang-1',
addressPrefix: 'stars',
rpcUrl: 'https://rpc.fang-1.stargaze-apis.com/',
httpUrl: 'https://rest.fang-1.stargaze-apis.com/',
feeToken: 'ustars',
stakingToken: 'ustars',
coinMap: {
ustars: { denom: 'STARS', fractionalDigits: 6 },
},
gasPrice: 0.025,
fees: {
upload: 1500000,
init: 500000,
exec: 200000,
},
}
export const testnetConfig: AppConfig = {
chainId: 'elgafar-1',
chainName: 'elgafar-1',
@ -40,5 +59,6 @@ export const testnetConfig: AppConfig = {
export const getConfig = (network: string): AppConfig => {
if (network === 'mainnet') return mainnetConfig
else if (network === 'fang-testnet') return fangTestnetConfig
return testnetConfig
}

View File

@ -342,8 +342,7 @@ export const badgeHub = (client: SigningCosmWasmClient, txSigner: string): Badge
},
'auto',
'',
[coin(200000000, 'ustars')],
// editFee ? [coin(editFee, 'ustars')] : [],
editFee ? [coin(editFee, 'ustars')] : [],
)
return res.transactionHash

View File

@ -1,7 +1,8 @@
/* eslint-disable eslint-comments/disable-enable-pair */
import type { StdFee } from '@cosmjs/amino'
import type { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate'
import type { Coin } from '@cosmjs/proto-signing'
import { type Coin, coins } from '@cosmjs/proto-signing'
import type { logs } from '@cosmjs/stargate'
export interface CreateVendingMinterResponse {
@ -52,6 +53,11 @@ export const vendingFactory = (client: SigningCosmWasmClient, txSigner: string):
const use = (contractAddress: string): VendingFactoryInstance => {
//Query
const defaultFee: StdFee = {
amount: coins('100000', 'ustars'),
gas: '100000',
}
//Execute
const createVendingMinter = async (
senderAddress: string,
@ -63,10 +69,8 @@ export const vendingFactory = (client: SigningCosmWasmClient, txSigner: string):
const result = await client.execute(senderAddress, contractAddress, msg, 'auto', '', funds)
return {
vendingMinterAddress: result.logs[0].events.filter((e) => e.type === 'instantiate')[0].attributes[0].value,
sg721Address: result.logs[0].events
.filter((e) => e.type === 'wasm')
.filter((e) => e.attributes[2]?.key === 'sg721_address')[0].attributes[2].value,
vendingMinterAddress: result.logs[0].events[16].attributes[0].value,
sg721Address: result.logs[0].events[18].attributes[0].value,
transactionHash: result.transactionHash,
logs: result.logs,
}

18257
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,5 @@
{
"private": true,
"name": "@mito/stargaze-studio",
"repository": "https://git.vdb.to/LaconicNetwork/stargaze-studio",
"name": "stargaze-studio",
"version": "0.8.7",
"workspaces": [
"packages/*"
@ -15,21 +13,21 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3",
"@cosmjs/cosmwasm-stargate": "0.32.3",
"@cosmjs/encoding": "0.32.3",
"@cosmjs/math": "0.32.3",
"@cosmjs/proto-signing": "0.32.3",
"@cosmjs/stargate": "0.32.3",
"@cosmos-kit/keplr": "2.8.0",
"@cosmos-kit/leap": "2.8.0",
"@cosmos-kit/leap-metamask-cosmos-snap": "0.8.0",
"@cosmos-kit/react": "2.12.0",
"@cosmjs/cosmwasm-stargate": "0.32.2",
"@cosmjs/encoding": "0.32.2",
"@cosmjs/math": "0.32.2",
"@cosmjs/proto-signing": "0.32.2",
"@cosmjs/stargate": "0.32.2",
"cosmjs-types": "0.9.0",
"@cosmos-kit/keplr": "^2.4.4",
"@cosmos-kit/leap": "^2.4.3",
"@cosmos-kit/leap-metamask-cosmos-snap": "^0.3.3",
"@cosmos-kit/react": "^2.9.3",
"crypto-js": "4.1.1",
"@types/crypto-js": "4.2.1",
"@fontsource/jetbrains-mono": "^4",
"@fontsource/roboto": "^4",
"@headlessui/react": "1.6.0",
"@headlessui/tailwindcss": "0.2.0",
"@heroicons/react": "2.0.18",
"@interchain-ui/react": "1.23.11",
"merkletreejs": "0.3.11",
"@leapwallet/cosmos-snap-provider": "0.1.24",
"@pinata/sdk": "^1.1.26",
"@popperjs/core": "^2",
@ -37,23 +35,20 @@
"@tailwindcss/forms": "^0",
"@tailwindcss/line-clamp": "^0",
"@typeform/embed-react": "2.21.0",
"@types/crypto-js": "4.2.1",
"@types/pako": "^2.0.3",
"axios": "^0",
"chain-registry": "^1.20.0",
"clsx": "^1",
"compare-versions": "^4",
"cosmjs-types": "0.9.0",
"crypto-js": "4.1.1",
"daisyui": "^2.19.0",
"html-to-image": "1.11.11",
"@headlessui/react": "1.6.0",
"@headlessui/tailwindcss": "0.2.0",
"@heroicons/react": "2.0.18",
"jscrypto": "^1.0.3",
"match-sorter": "^6",
"merkletreejs": "0.3.11",
"next": "^12",
"next-seo": "^4",
"nft.storage": "^6.3.0",
"pako": "^2.0.2",
"qrcode.react": "3.1.0",
"react": "^18",
"react-datetime-picker": "^3",
@ -80,8 +75,8 @@
"lint-staged": "^12",
"object-sizeof": "^1.6.0",
"postcss": "^8",
"tailwind-merge": "1.14.0",
"tailwindcss": "^3",
"tailwind-merge": "1.14.0",
"typescript": "^4"
},
"eslintConfig": {

View File

@ -1,132 +0,0 @@
/* eslint-disable eslint-comments/disable-enable-pair */
import { Alert } from 'components/Alert'
import { Button } from 'components/Button'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
import { AddressInput, TextInput } from 'components/forms/FormInput'
import { useInputState } from 'components/forms/FormInput.hooks'
import type { NextPage } from 'next'
import { useRouter } from 'next/router'
import { NextSeo } from 'next-seo'
import { useEffect, useState } from 'react'
import { toast } from 'react-hot-toast'
import { NETWORK } from 'utils/constants'
import { useDebounce } from 'utils/debounce'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { resolveAddress } from 'utils/resolveAddress'
import { useWallet } from 'utils/wallet'
const CancelAuctionPage: NextPage = () => {
const wallet = useWallet()
const [isLoading, setIsLoading] = useState(false)
const [txHash, setTxHash] = useState<string | undefined>(undefined)
const collectionAddressState = useInputState({
id: 'collection-address',
name: 'collectionAddress',
title: 'Collection Contract Address',
defaultValue: '',
placeholder: 'stars1...',
})
const collectionAddress = useDebounce(collectionAddressState.value, 300)
const tokenIdState = useInputState({
id: 'token-id',
name: 'tokenId',
title: 'Token ID',
defaultValue: '',
placeholder: '1',
})
const router = useRouter()
useEffect(() => {
if (collectionAddress.length > 0) {
void router.replace({ query: { contractAddress: collectionAddress } })
}
if (collectionAddress.length === 0) {
void router.replace({ query: {} })
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [collectionAddress])
useEffect(() => {
const initial = new URL(document.URL).searchParams.get('contractAddress')
if (initial && initial.length > 0) collectionAddressState.onChange(initial)
}, [])
const resolveCollectionAddress = async () => {
await resolveAddress(collectionAddressState.value.trim(), wallet).then((resolvedAddress) => {
if (resolvedAddress) {
collectionAddressState.onChange(resolvedAddress)
}
})
}
useEffect(() => {
void resolveCollectionAddress()
}, [collectionAddressState.value])
const handleCancelAuction = async () => {
if (!wallet.isWalletConnected) return toast.error('Please connect your wallet.')
if (!collectionAddressState.value) return toast.error('Please enter a collection address.')
const client = await wallet.getSigningCosmWasmClient()
setTxHash(undefined)
setIsLoading(true)
try {
const result = await client.execute(
wallet.address as string,
NETWORK === 'mainnet'
? 'stars1vvdkcn393ddyd47v9g3qv6mvne59d0ykzy9wre3ga0c58dtdg4ksm776jg'
: 'stars1dnadsd7tx0dmnpp26ms7d66zsp7tduygwjgfjzueh0lg9t5lq5vq9kn47c',
{
cancel_auction: {
collection: collectionAddressState.value,
token_id: tokenIdState.value,
},
},
'auto',
)
toast.success('Auction successfully cancelled.')
setTxHash(result.transactionHash)
} catch (error: any) {
toast.error(error.message, { style: { maxWidth: 'none' } })
setTxHash(undefined)
} finally {
setIsLoading(false)
}
}
return (
<section className="py-6 px-12 space-y-4">
<NextSeo title="Cancel Auction" />
<ContractPageHeader link={links.Documentation} title="Cancel Auction" />
<div className="space-y-2">
<AddressInput {...collectionAddressState} />
<TextInput className="w-1/4" {...tokenIdState} />
</div>
<div className="flex flex-row content-center mt-4">
<Button
isDisabled={collectionAddressState.value === ''}
isLoading={isLoading}
onClick={() => {
void handleCancelAuction()
}}
>
Cancel Auction
</Button>
</div>
<Conditional test={txHash !== undefined}>
<Alert type="info">
<b>Transaction Hash:</b> {txHash}
</Alert>
</Conditional>
</section>
)
}
export default withMetadata(CancelAuctionPage, { center: false })

View File

@ -7,7 +7,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { toUtf8 } from '@cosmjs/encoding'
import type { Coin } from '@cosmjs/proto-signing'
import { coin } from '@cosmjs/proto-signing'
import { Sidetab } from '@typeform/embed-react'
import axios from 'axios'
@ -127,12 +126,12 @@ const CollectionCreationPage: NextPage = () => {
const [royaltyDetails, setRoyaltyDetails] = useState<RoyaltyDetailsDataProps | null>(null)
const [minterType, setMinterType] = useState<MinterType>('vending')
const [vendingMinterCreationFee, setVendingMinterCreationFee] = useState<Coin | null>(null)
const [baseMinterCreationFee, setBaseMinterCreationFee] = useState<Coin | null>(null)
const [vendingMinterUpdatableCreationFee, setVendingMinterUpdatableCreationFee] = useState<Coin | null>(null)
const [openEditionMinterCreationFee, setOpenEditionMinterCreationFee] = useState<Coin | undefined>(undefined)
const [vendingMinterFlexCreationFee, setVendingMinterFlexCreationFee] = useState<Coin | null>(null)
const [baseMinterUpdatableCreationFee, setBaseMinterUpdatableCreationFee] = useState<Coin | null>(null)
const [vendingMinterCreationFee, setVendingMinterCreationFee] = useState<string | null>(null)
const [baseMinterCreationFee, setBaseMinterCreationFee] = useState<string | null>(null)
const [vendingMinterUpdatableCreationFee, setVendingMinterUpdatableCreationFee] = useState<string | null>(null)
const [openEditionMinterCreationFee, setOpenEditionMinterCreationFee] = useState<string | null>(null)
const [vendingMinterFlexCreationFee, setVendingMinterFlexCreationFee] = useState<string | null>(null)
const [baseMinterUpdatableCreationFee, setBaseMinterUpdatableCreationFee] = useState<string | null>(null)
const [minimumMintPrice, setMinimumMintPrice] = useState<string | null>('0')
const [minimumUpdatableMintPrice, setMinimumUpdatableMintPrice] = useState<string | null>('0')
const [minimumOpenEditionMintPrice, setMinimumOpenEditionMintPrice] = useState<string | null>('0')
@ -676,11 +675,14 @@ const CollectionCreationPage: NextPage = () => {
txSigner: wallet.address || '',
msg,
funds: [
whitelistDetails?.whitelistState !== 'none' && whitelistDetails?.whitelistType === 'flex'
? (vendingMinterFlexCreationFee as Coin)
: collectionDetails?.updatable
? (vendingMinterUpdatableCreationFee as Coin)
: (vendingMinterCreationFee as Coin),
coin(
whitelistDetails?.whitelistState !== 'none' && whitelistDetails?.whitelistType === 'flex'
? (vendingMinterFlexCreationFee as string)
: collectionDetails?.updatable
? (vendingMinterUpdatableCreationFee as string)
: (vendingMinterCreationFee as string),
'ustars',
),
],
updatable: collectionDetails?.updatable,
flex: whitelistDetails?.whitelistState !== 'none' && whitelistDetails?.whitelistType === 'flex',
@ -734,7 +736,10 @@ const CollectionCreationPage: NextPage = () => {
txSigner: wallet.address || '',
msg,
funds: [
collectionDetails?.updatable ? (baseMinterUpdatableCreationFee as Coin) : (baseMinterCreationFee as Coin),
coin(
collectionDetails?.updatable ? (baseMinterUpdatableCreationFee as string) : (baseMinterCreationFee as string),
'ustars',
),
],
updatable: collectionDetails?.updatable,
}
@ -1211,7 +1216,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setBaseMinterCreationFee(baseFactoryParameters?.params?.creation_fee)
setBaseMinterCreationFee(baseFactoryParameters?.params?.creation_fee?.amount)
}
if (BASE_FACTORY_UPDATABLE_ADDRESS) {
const baseFactoryUpdatableParameters = await client
@ -1222,7 +1227,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setBaseMinterUpdatableCreationFee(baseFactoryUpdatableParameters?.params?.creation_fee)
setBaseMinterUpdatableCreationFee(baseFactoryUpdatableParameters?.params?.creation_fee?.amount)
}
if (VENDING_FACTORY_ADDRESS) {
const vendingFactoryParameters = await client
@ -1231,7 +1236,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setVendingMinterCreationFee(vendingFactoryParameters?.params?.creation_fee)
setVendingMinterCreationFee(vendingFactoryParameters?.params?.creation_fee?.amount)
setMinimumMintPrice(vendingFactoryParameters?.params?.min_mint_price?.amount)
}
if (VENDING_FACTORY_UPDATABLE_ADDRESS) {
@ -1243,7 +1248,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setVendingMinterUpdatableCreationFee(vendingFactoryUpdatableParameters?.params?.creation_fee)
setVendingMinterUpdatableCreationFee(vendingFactoryUpdatableParameters?.params?.creation_fee?.amount)
setMinimumUpdatableMintPrice(vendingFactoryUpdatableParameters?.params?.min_mint_price?.amount)
}
if (VENDING_FACTORY_FLEX_ADDRESS) {
@ -1255,7 +1260,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setVendingMinterFlexCreationFee(vendingFactoryFlexParameters?.params?.creation_fee)
setVendingMinterFlexCreationFee(vendingFactoryFlexParameters?.params?.creation_fee?.amount)
setMinimumFlexMintPrice(vendingFactoryFlexParameters?.params?.min_mint_price?.amount)
}
if (OPEN_EDITION_FACTORY_ADDRESS) {
@ -1265,7 +1270,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setOpenEditionMinterCreationFee(openEditionFactoryParameters?.params?.creation_fee)
setOpenEditionMinterCreationFee(openEditionFactoryParameters?.params?.creation_fee?.amount)
setMinimumOpenEditionMintPrice(openEditionFactoryParameters?.params?.min_mint_price?.amount)
}
setInitialParametersFetched(true)
@ -1295,7 +1300,7 @@ const CollectionCreationPage: NextPage = () => {
toast.error(`${error.message}`, { style: { maxWidth: 'none' } })
addLogItem({ id: uid(), message: error.message, type: 'Error', timestamp: new Date() })
})
setOpenEditionMinterCreationFee(openEditionFactoryParameters?.params?.creation_fee)
setOpenEditionMinterCreationFee(openEditionFactoryParameters?.params?.creation_fee?.amount)
setMinimumOpenEditionMintPrice(openEditionFactoryParameters?.params?.min_mint_price?.amount)
setMintTokenFromOpenEditionFactory(
tokensList.find((token) => token.denom === openEditionFactoryParameters?.params?.min_mint_price?.denom),
@ -1342,13 +1347,13 @@ const CollectionCreationPage: NextPage = () => {
})
if (whitelistDetails?.whitelistState !== 'none' && whitelistDetails?.whitelistType === 'flex') {
setVendingMinterFlexCreationFee(vendingFactoryParameters?.params?.creation_fee)
setVendingMinterFlexCreationFee(vendingFactoryParameters?.params?.creation_fee?.amount)
setMinimumFlexMintPrice(vendingFactoryParameters?.params?.min_mint_price?.amount)
} else if (collectionDetails?.updatable) {
setVendingMinterUpdatableCreationFee(vendingFactoryParameters?.params?.creation_fee)
setVendingMinterUpdatableCreationFee(vendingFactoryParameters?.params?.creation_fee?.amount)
setMinimumUpdatableMintPrice(vendingFactoryParameters?.params?.min_mint_price?.amount)
} else {
setVendingMinterCreationFee(vendingFactoryParameters?.params?.creation_fee)
setVendingMinterCreationFee(vendingFactoryParameters?.params?.creation_fee?.amount)
setMinimumMintPrice(vendingFactoryParameters?.params?.min_mint_price?.amount)
}
setMintTokenFromVendingFactory(
@ -1367,82 +1372,53 @@ const CollectionCreationPage: NextPage = () => {
])
const checkwalletBalance = async () => {
const queryClient = await wallet.getCosmWasmClient()
const creationFee: Coin | null =
minterType === 'vending'
? whitelistDetails?.whitelistType === 'flex'
? vendingMinterFlexCreationFee
: collectionDetails?.updatable
? vendingMinterUpdatableCreationFee
: vendingMinterCreationFee
: collectionDetails?.updatable
? baseMinterUpdatableCreationFee
: baseMinterCreationFee
const creationFeeDenom = tokensList.find((token) => token.denom === creationFee?.denom)
await queryClient.getBalance(wallet.address || '', 'ustars').then(async (starsBalance) => {
await queryClient
.getBalance(wallet.address || '', creationFee?.denom as string)
.then((creationFeeDenomBalance) => {
if (minterType === 'vending' && whitelistDetails?.whitelistState === 'new') {
if (whitelistDetails.whitelistType !== 'merkletree' && whitelistDetails.memberLimit) {
const whitelistCreationFee = Math.ceil(Number(whitelistDetails.memberLimit) / 1000) * 100000000
if (creationFee?.denom === 'ustars') {
const amountNeeded = whitelistCreationFee + Number(creationFee.amount)
if (amountNeeded >= Number(starsBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
amountNeeded / 1000000
).toString()} STARS`,
)
} else {
if (whitelistCreationFee >= Number(starsBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the whitelist. Needed amount: ${(
whitelistCreationFee / 1000000
).toString()} STARS`,
)
if (Number(creationFee?.amount) > Number(creationFeeDenomBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
Number(creationFee?.amount) / 1000000
).toString()} ${creationFeeDenom ? creationFeeDenom.displayName : creationFee?.denom}`,
)
}
} else if (whitelistDetails.whitelistType === 'merkletree') {
const merkleWhitelistCreationFee = 1000000000
if (creationFee?.denom === 'ustars') {
const amountNeeded = merkleWhitelistCreationFee + Number(creationFee.amount)
if (amountNeeded >= Number(starsBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
amountNeeded / 1000000
).toString()} STARS`,
)
} else {
if (merkleWhitelistCreationFee >= Number(starsBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the whitelist. Needed amount: ${(
merkleWhitelistCreationFee / 1000000
).toString()} STARS`,
)
if (Number(creationFee?.amount) > Number(creationFeeDenomBalance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
Number(creationFee?.amount) / 1000000
).toString()} ${creationFeeDenom ? creationFeeDenom.displayName : creationFee?.denom}`,
)
}
}
} else if (Number(creationFee?.amount) > Number(creationFeeDenomBalance.amount))
await (await wallet.getCosmWasmClient()).getBalance(wallet.address || '', 'ustars').then((balance) => {
if (minterType === 'vending' && whitelistDetails?.whitelistState === 'new') {
if (whitelistDetails.whitelistType !== 'merkletree' && whitelistDetails.memberLimit) {
const amountNeeded =
Math.ceil(Number(whitelistDetails.memberLimit) / 1000) * 100000000 +
(whitelistDetails.whitelistType === 'flex'
? Number(vendingMinterFlexCreationFee)
: collectionDetails?.updatable
? Number(vendingMinterUpdatableCreationFee)
: Number(vendingMinterCreationFee))
if (amountNeeded >= Number(balance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
Number(creationFee?.amount) / 1000000
).toString()} ${creationFeeDenom ? creationFeeDenom.displayName : creationFee?.denom}`,
amountNeeded / 1000000
).toString()} STARS`,
)
})
} else if (whitelistDetails.whitelistType === 'merkletree') {
const amountNeeded =
1000000000 +
(collectionDetails?.updatable
? Number(vendingMinterUpdatableCreationFee)
: Number(vendingMinterCreationFee))
if (amountNeeded >= Number(balance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
amountNeeded / 1000000
).toString()} STARS`,
)
}
} else {
const amountNeeded =
minterType === 'vending'
? whitelistDetails?.whitelistState === 'existing' && whitelistDetails.whitelistType === 'flex'
? Number(vendingMinterFlexCreationFee)
: collectionDetails?.updatable
? Number(vendingMinterUpdatableCreationFee)
: Number(vendingMinterCreationFee)
: collectionDetails?.updatable
? Number(baseMinterUpdatableCreationFee)
: Number(baseMinterCreationFee)
if (amountNeeded >= Number(balance.amount))
throw new Error(
`Insufficient wallet balance to instantiate the required contracts. Needed amount: ${(
amountNeeded / 1000000
).toString()} STARS`,
)
}
})
}
@ -1958,7 +1934,7 @@ const CollectionCreationPage: NextPage = () => {
onChange={setOpenEditionMinterCreatorData}
onDetailsChange={setOpenEditionMinterDetails}
openEditionFactoryAddress={openEditionFactoryAddress}
openEditionMinterCreationFee={openEditionMinterCreationFee}
openEditionMinterCreationFee={openEditionMinterCreationFee as string}
/>
</Conditional>
<div className="mx-10">

View File

@ -60,12 +60,6 @@ const CollectionList: NextPage = () => {
if (minterConfig?.whitelist) collection.whitelist = minterConfig.whitelist
setMyStandardCollections((prevState) => [...prevState, collection])
} else if (contractType?.includes('open-edition')) {
const minterConfig = await (await wallet.getCosmWasmClient())
.queryContractSmart(collection.minter, { config: {} })
.catch(() => {
console.log('Unable to retrieve minter config')
})
if (minterConfig?.whitelist) collection.whitelist = minterConfig.whitelist
setMyOpenEditionCollections((prevState) => [...prevState, collection])
}
})
@ -435,31 +429,6 @@ const CollectionList: NextPage = () => {
</Tooltip>
</span>
</div>
<Conditional test={collection.whitelist}>
<div className="flex flex-row items-center space-x-3">
Whitelist:
<span className="ml-2">
<Tooltip
backgroundColor="bg-blue-500"
label="Click to copy the whitelist contract address"
>
<button
className="group flex space-x-2 font-mono text-base text-white/80 hover:underline"
onClick={() => void copy(collection.whitelist as string)}
type="button"
>
<span>
{truncateMiddle(
collection.whitelist ? (collection.whitelist as string) : '',
36,
)}
</span>
<FaCopy className="opacity-0 group-hover:opacity-100" />
</button>
</Tooltip>
</span>
</div>
</Conditional>
</td>
<th className="bg-black">
<div className="flex items-center space-x-8">
@ -476,14 +445,6 @@ const CollectionList: NextPage = () => {
>
<FaRocket />
</Anchor>
<Conditional test={collection.whitelist}>
<Anchor
className="text-xl text-white"
href={`/contracts/whitelist/execute/?contractAddress=${collection.whitelist}`}
>
<FaList />
</Anchor>
</Conditional>
</div>
</th>
</tr>

View File

@ -1,28 +1,14 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import type { EncodeObject } from '@cosmjs/proto-signing'
import { GasPrice, SigningStargateClient } from '@cosmjs/stargate'
import clsx from 'clsx'
import { Alert } from 'components/Alert'
import { Button } from 'components/Button'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
import { AddressList } from 'components/forms/AddressList'
import { useAddressListState } from 'components/forms/AddressList.hooks'
import { TextInput } from 'components/forms/FormInput'
import { useInputState } from 'components/forms/FormInput.hooks'
import { JsonPreview } from 'components/JsonPreview'
import { getConfig } from 'config'
import { MsgExec } from 'cosmjs-types/cosmos/authz/v1beta1/tx'
import { MsgStoreCode } from 'cosmjs-types/cosmwasm/wasm/v1/tx'
import { AccessConfig, AccessType } from 'cosmjs-types/cosmwasm/wasm/v1/types'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
import pako from 'pako'
import { useEffect, useRef, useState } from 'react'
import { toast } from 'react-hot-toast'
import { FaAsterisk } from 'react-icons/fa'
@ -37,38 +23,9 @@ const UploadContract: NextPage = () => {
const [transactionResult, setTransactionResult] = useState<any>()
const [wasmFile, setWasmFile] = useState<File | null>(null)
const [wasmByteArray, setWasmByteArray] = useState<Uint8Array | null>(null)
const [accessType, setAccessType] = useState<
'ACCESS_TYPE_UNSPECIFIED' | 'ACCESS_TYPE_EVERYBODY' | 'ACCESS_TYPE_ANY_OF_ADDRESSES' | 'ACCESS_TYPE_NOBODY'
>('ACCESS_TYPE_UNSPECIFIED')
const [accessConfig, setAccessConfig] = useState<AccessConfig | undefined>(undefined)
const [isAuthzUpload, setIsAuthzUpload] = useState(false)
const granterAddressState = useInputState({
id: 'address',
name: 'Granter Address',
title: 'Granter Address',
subtitle: 'The address that granted the authorization for contract upload',
defaultValue: '',
placeholder: 'stars1...',
})
const memoState = useInputState({
id: 'memo',
name: 'Memo',
title: 'Transaction Memo',
defaultValue: '',
placeholder: 'My contract',
})
const permittedAddressListState = useAddressListState()
const inputFile = useRef<HTMLInputElement>(null)
interface MsgExecAllowanceEncodeObject extends EncodeObject {
readonly typeUrl: '/cosmos.authz.v1beta1.MsgExec'
readonly value: Partial<MsgExec>
}
const onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files) return
setWasmFile(e.target.files[0])
@ -94,70 +51,20 @@ const UploadContract: NextPage = () => {
try {
if (!wallet.isWalletConnected) return toast.error('Please connect your wallet.')
if (!wasmFile || !wasmByteArray) return toast.error('No file selected.')
if (accessType === 'ACCESS_TYPE_UNSPECIFIED')
return toast.error('Please select an instantiation permission type.', { style: { maxWidth: 'none' } })
setLoading(true)
const client = await wallet.getSigningCosmWasmClient()
if (!isAuthzUpload) {
const result = await client.upload(
wallet.address as string,
wasmByteArray,
'auto',
memoState.value ?? undefined,
accessConfig,
)
setTransactionResult({
transactionHash: result.transactionHash,
codeId: result.codeId,
originalSize: result.originalSize,
compressedSize: result.compressedSize,
originalChecksum: result.checksum,
})
} else {
if (!granterAddressState.value) {
setLoading(false)
return toast.error('Please enter the authorization granter address.', { style: { maxWidth: 'none' } })
}
const compressed = pako.gzip(wasmByteArray, { level: 9 })
const result = await client.upload(wallet.address as string, wasmByteArray, 'auto')
const authzExecuteContractMsg: MsgExecAllowanceEncodeObject = {
typeUrl: '/cosmos.authz.v1beta1.MsgExec',
value: MsgExec.fromPartial({
grantee: wallet.address as string,
msgs: [
{
typeUrl: '/cosmwasm.wasm.v1.MsgStoreCode',
value: MsgStoreCode.encode({
sender: granterAddressState.value,
wasmByteCode: compressed,
instantiatePermission: accessConfig,
}).finish(),
},
],
}),
}
const offlineSigner = wallet.getOfflineSignerDirect()
const stargateClient = await SigningStargateClient.connectWithSigner(getConfig(NETWORK).rpcUrl, offlineSigner, {
gasPrice: GasPrice.fromString('0.025ustars'),
})
const result = await stargateClient.signAndBroadcast(
wallet.address || '',
[authzExecuteContractMsg],
'auto',
memoState.value ?? undefined,
)
setTransactionResult({
transactionHash: result.transactionHash,
codeId: result.events.filter((event) => event.type === 'store_code')[0].attributes[1].value,
originalChecksum: result.events.filter((event) => event.type === 'store_code')[0].attributes[0].value,
})
}
setTransactionResult({
transactionHash: result.transactionHash,
codeId: result.codeId,
originalSize: result.originalSize,
compressedSize: result.compressedSize,
originalChecksum: result.checksum,
})
setLoading(false)
} catch (err: any) {
@ -166,120 +73,55 @@ const UploadContract: NextPage = () => {
}
}
useEffect(() => {
try {
if (accessType === 'ACCESS_TYPE_ANY_OF_ADDRESSES') {
setAccessConfig(
AccessConfig.fromPartial({
permission: AccessType.ACCESS_TYPE_ANY_OF_ADDRESSES,
addresses: permittedAddressListState.entries.map((entry) => entry[1].address).filter(Boolean),
}),
)
} else if (accessType === 'ACCESS_TYPE_NOBODY') {
setAccessConfig(AccessConfig.fromPartial({ permission: AccessType.ACCESS_TYPE_NOBODY }))
} else if (accessType === 'ACCESS_TYPE_EVERYBODY') {
setAccessConfig(AccessConfig.fromPartial({ permission: AccessType.ACCESS_TYPE_EVERYBODY }))
} else if (accessType === 'ACCESS_TYPE_UNSPECIFIED') {
setAccessConfig(undefined)
}
} catch (error: any) {
toast.error(error.message, { style: { maxWidth: 'none' } })
}
}, [accessType, permittedAddressListState.entries])
return (
<section className="py-6 px-12 space-y-4">
<NextSeo title="Upload Contract" />
<ContractPageHeader
description="Here you can upload a contract on Stargaze Testnet."
link=""
title="Upload Contract"
/>
<div className="inset-x-0 bottom-0 border-b-2 border-white/25" />
<div className="flex flex-col w-1/2">
<span className="text-xl font-bold text-white">Authorization Type for Contract Instantiation</span>
<select
className="px-4 pt-2 pb-2 mt-2 w-1/2 placeholder:text-white/50 bg-white/10 rounded border-2 border-white/20 focus:ring focus:ring-plumbus-20"
onChange={(e) => setAccessType(e.target.value as any)}
value={accessType}
>
<option disabled value="ACCESS_TYPE_UNSPECIFIED">
Select Authorization Type
</option>
<option value="ACCESS_TYPE_EVERYBODY">Everybody</option>
<option value="ACCESS_TYPE_ANY_OF_ADDRESSES">Any of Addresses</option>
<option value="ACCESS_TYPE_NOBODY">Nobody</option>
</select>
</div>
<div className="my-2 w-1/2">
<TextInput {...memoState} />
</div>
<div className="flex flex-row justify-start">
<h1 className="mt-2 font-bold text-md">Authz Upload?</h1>
<label className="justify-start ml-6 cursor-pointer label">
<input
checked={isAuthzUpload}
className={`${isAuthzUpload ? `bg-stargaze` : `bg-gray-600`} checkbox`}
onClick={() => {
setIsAuthzUpload(!isAuthzUpload)
}}
type="checkbox"
/>
</label>
</div>
<Conditional test={isAuthzUpload}>
<div className="my-2 w-3/4">
<TextInput {...granterAddressState} />
</div>
</Conditional>
<Conditional test={accessType === 'ACCESS_TYPE_ANY_OF_ADDRESSES'}>
<div className="my-2 w-3/4">
<AddressList
entries={permittedAddressListState.entries}
onAdd={permittedAddressListState.add}
onChange={permittedAddressListState.update}
onRemove={permittedAddressListState.remove}
subtitle="The list of addresses permitted to instantiate the contract"
title="Permitted Addresses"
/>
</div>
</Conditional>
<Conditional test={Boolean(transactionResult)}>
<Alert type="info">
<b>Upload success!</b> Here is the transaction result containing the code ID, transaction hash and other data.
</Alert>
<JsonPreview content={transactionResult} title="Transaction Result" />
<br />
</Conditional>
<div
className={clsx(
'flex relative justify-center items-center space-y-4 h-32',
'rounded border-2 border-white/20 border-dashed',
)}
>
<input
accept=".wasm"
className={clsx(
'file:py-2 file:px-4 file:mr-4 file:bg-plumbus-light file:rounded file:border-0 cursor-pointer',
'before:absolute before:inset-0 before:hover:bg-white/5 before:transition',
)}
onChange={onFileChange}
ref={inputFile}
type="file"
<Conditional test={NETWORK === 'testnet'}>
<NextSeo title="Upload Contract" />
<ContractPageHeader
description="Here you can upload a contract on Stargaze Testnet."
link=""
title="Upload Contract"
/>
</div>
<div className="inset-x-0 bottom-0 border-b-2 border-white/25" />
<div className="flex justify-end pb-6">
<Button isDisabled={!wasmFile} isLoading={loading} isWide leftIcon={<FaAsterisk />} onClick={upload}>
Upload Contract
</Button>
</div>
<Conditional test={Boolean(transactionResult)}>
<Alert type="info">
<b>Upload success!</b> Here is the transaction result containing the code ID, transaction hash and other
data.
</Alert>
<JsonPreview content={transactionResult} title="Transaction Result" />
<br />
</Conditional>
<div
className={clsx(
'flex relative justify-center items-center space-y-4 h-32',
'rounded border-2 border-white/20 border-dashed',
)}
>
<input
accept=".wasm"
className={clsx(
'file:py-2 file:px-4 file:mr-4 file:bg-plumbus-light file:rounded file:border-0 cursor-pointer',
'before:absolute before:inset-0 before:hover:bg-white/5 before:transition',
)}
onChange={onFileChange}
ref={inputFile}
type="file"
/>
</div>
<div className="flex justify-end pb-6">
<Button isDisabled={!wasmFile} isLoading={loading} isWide leftIcon={<FaAsterisk />} onClick={upload}>
Upload Contract
</Button>
</div>
</Conditional>
<Conditional test={NETWORK === 'mainnet'}>
<NextSeo title="Upload Contract" />
<ContractPageHeader description="" link="" title="Upload Contract" />
<Alert type="info">Permissionless upload of contracts is only supported for testnet currently.</Alert>
</Conditional>
</section>
)
}

View File

@ -1,4 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable tailwindcss/classnames-order */
@ -211,7 +212,11 @@ const Tokenfactory: NextPage = () => {
setLoading(true)
const offlineSigner = wallet.getOfflineSignerDirect()
const stargateClient = await SigningStargateClient.connectWithSigner(
NETWORK === 'testnet' ? 'https://rpc.elgafar-1.stargaze-apis.com/' : 'https://rpc.stargaze-apis.com/',
NETWORK === 'fang-testnet'
? 'https://rpc.fang-1.stargaze-apis.com/'
: NETWORK === 'testnet'
? 'https://rpc.fang-1.stargaze-apis.com/'
: 'https://rpc.stargaze-apis.com/',
offlineSigner,
{
gasPrice: GasPrice.fromString('0.025ustars'),

View File

@ -1,69 +0,0 @@
#!/bin/bash
set -e
RECORD_FILE=tmp.rf.$$
CONFIG_FILE=`mktemp`
CERC_APP_TYPE=${CERC_APP_TYPE:-"webapp"}
CERC_REPO_REF=${CERC_REPO_REF:-${GITHUB_SHA:-`git log -1 --format="%H"`}}
CERC_IS_LATEST_RELEASE=${CERC_IS_LATEST_RELEASE:-"true"}
rcd_name=$(jq -r '.name' package.json | sed 's/null//')
rcd_desc=$(jq -r '.description' package.json | sed 's/null//')
rcd_repository=$(jq -r '.repository' package.json | sed 's/null//')
rcd_homepage=$(jq -r '.homepage' package.json | sed 's/null//')
rcd_license=$(jq -r '.license' package.json | sed 's/null//')
rcd_author=$(jq -r '.author' package.json | sed 's/null//')
rcd_app_version=$(jq -r '.version' package.json | sed 's/null//')
cat <<EOF > "$CONFIG_FILE"
services:
cns:
restEndpoint: '${CERC_REGISTRY_REST_ENDPOINT:-http://23.111.69.218:1317}'
gqlEndpoint: '${CERC_REGISTRY_GQL_ENDPOINT:-https://lx-daemon.audubon.app/api}'
chainId: ${CERC_REGISTRY_CHAIN_ID:-laconic_9000-1}
gas: 9550000
fees: 500000aphoton
EOF
next_ver=$(laconic -c $CONFIG_FILE cns record list --type ApplicationRecord --all --name "$rcd_name" 2>/dev/null | jq -r -s ".[] | sort_by(.createTime) | reverse | [ .[] | select(.bondId == \"$CERC_REGISTRY_BOND_ID\") ] | .[0].attributes.version" | awk -F. -v OFS=. '{$NF += 1 ; print}')
if [ -z "$next_ver" ] || [ "1" == "$next_ver" ]; then
next_ver=0.0.1
fi
cat <<EOF | sed '/.*: ""$/d' > "$RECORD_FILE"
record:
type: ApplicationRecord
version: ${next_ver}
name: "$rcd_name"
description: "$rcd_desc"
homepage: "$rcd_homepage"
license: "$rcd_license"
author: "$rcd_author"
repository:
- "$rcd_repository"
repository_ref: "$CERC_REPO_REF"
app_version: "$rcd_app_version"
app_type: "$CERC_APP_TYPE"
EOF
cat $RECORD_FILE
RECORD_ID=$(laconic -c $CONFIG_FILE cns record publish --filename $RECORD_FILE --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} | jq -r '.id')
echo $RECORD_ID
if [ -z "$CERC_REGISTRY_APP_CRN" ]; then
authority=$(echo "$rcd_name" | cut -d'/' -f1 | sed 's/@//')
app=$(echo "$rcd_name" | cut -d'/' -f2-)
CERC_REGISTRY_APP_CRN="crn://$authority/applications/$app"
fi
laconic -c $CONFIG_FILE cns name set --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} "$CERC_REGISTRY_APP_CRN@${rcd_app_version}" "$RECORD_ID"
laconic -c $CONFIG_FILE cns name set --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} "$CERC_REGISTRY_APP_CRN@${CERC_REPO_REF}" "$RECORD_ID"
if [ "true" == "$CERC_IS_LATEST_RELEASE" ]; then
laconic -c $CONFIG_FILE cns name set --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} "$CERC_REGISTRY_APP_CRN" "$RECORD_ID"
fi
rm -f $RECORD_FILE $CONFIG_FILE

View File

@ -1,56 +0,0 @@
#!/bin/bash
set -e
RECORD_FILE=tmp.rf.$$
CONFIG_FILE=`mktemp`
rcd_name=$(jq -r '.name' package.json | sed 's/null//' | sed 's/^@//')
rcd_app_version=$(jq -r '.version' package.json | sed 's/null//')
cat <<EOF > "$CONFIG_FILE"
services:
cns:
restEndpoint: '${CERC_REGISTRY_REST_ENDPOINT:-http://23.111.69.218:1317}'
gqlEndpoint: '${CERC_REGISTRY_GQL_ENDPOINT:-https://lx-daemon.audubon.app/api}'
chainId: ${CERC_REGISTRY_CHAIN_ID:-laconic_9000-1}
gas: 550000
fees: 200000aphoton
EOF
if [ -z "$CERC_REGISTRY_APP_CRN" ]; then
authority=$(echo "$rcd_name" | cut -d'/' -f1 | sed 's/@//')
app=$(echo "$rcd_name" | cut -d'/' -f2-)
CERC_REGISTRY_APP_CRN="crn://$authority/applications/$app"
fi
APP_RECORD=$(laconic -c $CONFIG_FILE cns name resolve "$CERC_REGISTRY_APP_CRN" | jq '.[0]')
if [ -z "$APP_RECORD" ] || [ "null" == "$APP_RECORD" ]; then
echo "No record found for $CERC_REGISTRY_APP_CRN."
exit 1
fi
cat <<EOF | sed '/.*: ""$/d' > "$RECORD_FILE"
record:
type: ApplicationDeploymentRequest
version: 1.0.0
name: "$rcd_name@$rcd_app_version"
application: "$CERC_REGISTRY_APP_CRN@$rcd_app_version"
dns: "$CERC_REGISTRY_DEPLOYMENT_SHORT_HOSTNAME"
deployment: "$CERC_REGISTRY_DEPLOYMENT_CRN"
config:
env:
# this overrides the setting in `.env`
CERC_WEBAPP_DEBUG: "$rcd_app_version"
CERC_MAX_GENERATE_TIME: "600"
meta:
note: "Added by CI @ `date`"
repository: "`git remote get-url origin`"
repository_ref: "${GITHUB_SHA:-`git log -1 --format="%H"`}"
EOF
cat $RECORD_FILE
RECORD_ID=$(laconic -c $CONFIG_FILE cns record publish --filename $RECORD_FILE --user-key "${CERC_REGISTRY_USER_KEY}" --bond-id ${CERC_REGISTRY_BOND_ID} | jq -r '.id')
echo $RECORD_ID
rm -f $RECORD_FILE $CONFIG_FILE

View File

@ -1,6 +1,7 @@
import { useChain as useCosmosKitChain } from '@cosmos-kit/react'
import { chains } from 'chain-registry'
import { getConfig } from 'config'
import { fangTestnet } from 'config/fangTestnet'
import { NETWORK } from './constants'
@ -9,7 +10,7 @@ import { NETWORK } from './constants'
*/
export const useWallet = () => {
const { chainId } = getConfig(NETWORK)
const chain = chains.find((c) => c.chain_id === chainId)
const chain = chains.concat([fangTestnet]).find((c) => c.chain_id === chainId)
if (!chain) {
throw new Error('Chain not found')
}

3393
yarn.lock

File diff suppressed because it is too large Load Diff