@visualizevalue/mint-app-base 0.1.58 → 0.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +1 -1
- package/app.config.ts +1 -1
- package/components/BlocksTimeAgo.client.vue +1 -1
- package/components/{MintToken.vue → MintToken.client.vue} +4 -4
- package/components/Token/Detail.client.vue +1 -1
- package/components/Token/MintTimeline.client.vue +2 -3
- package/components/Token/OverviewCard.vue +1 -1
- package/components/TransactionFlow.vue +5 -2
- package/composables/collections.ts +20 -16
- package/nuxt.config.ts +1 -1
- package/package.json +2 -2
- package/utils/abis.ts +7 -6
- package/utils/time.ts +4 -4
- package/utils/types.ts +4 -4
package/.env.example
CHANGED
|
@@ -25,5 +25,5 @@ NUXT_PUBLIC_RPC3=
|
|
|
25
25
|
# =========================
|
|
26
26
|
# ONCHAIN
|
|
27
27
|
# =========================
|
|
28
|
-
NUXT_PUBLIC_FACTORY_ADDRESS=
|
|
28
|
+
NUXT_PUBLIC_FACTORY_ADDRESS=0xdc27b70874E36f00290Bd588D5B31AD510ca88a5
|
|
29
29
|
NUXT_PUBLIC_CHAIN_ID=11155111
|
package/app.config.ts
CHANGED
|
@@ -4,7 +4,7 @@ export default defineAppConfig({
|
|
|
4
4
|
component: 'P5',
|
|
5
5
|
name: 'P5 Renderer',
|
|
6
6
|
version: 1n,
|
|
7
|
-
address: '
|
|
7
|
+
address: '0xe7bbcb8aaa9fd0acb720c24b4c44fad521ba621f',
|
|
8
8
|
description: 'Allows using P5 scripts as the artifact content'
|
|
9
9
|
},
|
|
10
10
|
],
|
|
@@ -13,7 +13,7 @@ const props = defineProps({
|
|
|
13
13
|
blocks: BigInt,
|
|
14
14
|
})
|
|
15
15
|
|
|
16
|
-
const seconds = computed(() => blocksToSeconds(props.blocks))
|
|
16
|
+
const seconds = computed(() => Number(blocksToSeconds(props.blocks)))
|
|
17
17
|
const minutes = computed(() => Math.floor(seconds.value / 60))
|
|
18
18
|
const hours = computed(() => Math.floor(minutes.value / 60))
|
|
19
19
|
const days = computed(() => Math.floor(hours.value / 24))
|
|
@@ -53,10 +53,10 @@ const store = useOnchainStore()
|
|
|
53
53
|
const priceFeed = usePriceFeedStore()
|
|
54
54
|
|
|
55
55
|
const { data: currentBlock } = useBlockNumber({ chainId: config.public.chainId })
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
const secondsRemaining = computed(() =>
|
|
59
|
-
const until = computed(() =>
|
|
56
|
+
const blocksRemaining = computed(() => props.token.mintedBlock + 7200n - (currentBlock.value || 0n))
|
|
57
|
+
const mintOpen = computed(() => currentBlock.value && blocksRemaining.value > 0n)
|
|
58
|
+
const secondsRemaining = computed(() => props.token.closeAt - BigInt(nowInSeconds()))
|
|
59
|
+
const until = computed(() => props.token.closeAt)
|
|
60
60
|
|
|
61
61
|
const mintCount = computed(() => props.mintCount)
|
|
62
62
|
const { price, displayPrice } = useMintPrice(mintCount)
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
|
|
56
56
|
<div class="mint-status">
|
|
57
57
|
<p v-if="mintOpen">{{ blocksRemaining }} blocks remaining</p>
|
|
58
|
-
<p v-else-if="currentBlock">Closed at block {{ token.
|
|
58
|
+
<p v-else-if="currentBlock">Closed at block {{ token.mintedBlock + BLOCKS_PER_DAY }}</p>
|
|
59
59
|
<p v-if="ownedBalance">You own {{ ownedBalance }} {{ pluralize('token', Number(ownedBalance)) }}</p>
|
|
60
60
|
</div>
|
|
61
61
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<span class="amount">1<span>×</span></span>
|
|
16
16
|
<span class="price">Artist Mint</span>
|
|
17
17
|
|
|
18
|
-
<span class="time-ago"><BlocksTimeAgo v-if="currentBlock" :blocks="currentBlock -
|
|
18
|
+
<span class="time-ago"><BlocksTimeAgo v-if="currentBlock" :blocks="currentBlock - token.mintedBlock" /></span>
|
|
19
19
|
|
|
20
20
|
<span class="links">
|
|
21
21
|
<NuxtLink :to="`${config.public.blockExplorer}/nft/${token.collection}/${token.tokenId}`" target="_blank">
|
|
@@ -51,8 +51,7 @@ const { token, collection } = defineProps({
|
|
|
51
51
|
const state = useOnchainStore()
|
|
52
52
|
|
|
53
53
|
const mints = computed(() => state.tokenMints(token.collection, token.tokenId))
|
|
54
|
-
const
|
|
55
|
-
const backfillComplete = computed(() => token.mintsBackfilledUntilBlock <= mintedAtBlock.value)
|
|
54
|
+
const backfillComplete = computed(() => token.mintsBackfilledUntilBlock <= token.mintedBlock)
|
|
56
55
|
|
|
57
56
|
const loading = ref(true)
|
|
58
57
|
const loadMore = ref()
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<span v-if="token.description" class="description">{{ shortString(token.description, 60, 30) }}</span>
|
|
31
31
|
</h1>
|
|
32
32
|
<p v-if="mintOpen" class="closes-in">Closes in {{ blocksRemaining }} {{ pluralize('block', Number(blocksRemaining))}}</p>
|
|
33
|
-
<p v-else class="closed-at">Closed at block {{ token.
|
|
33
|
+
<p v-else class="closed-at">Closed at block {{ token.mintedBlock + BLOCKS_PER_DAY }}</p>
|
|
34
34
|
</header>
|
|
35
35
|
<Embed v-if="token.animationUrl" :src="token.animationUrl" />
|
|
36
36
|
<Image v-else-if="token.image" :src="token.image" :alt="token.name" />
|
|
@@ -59,6 +59,10 @@ const props = defineProps({
|
|
|
59
59
|
type: Number,
|
|
60
60
|
default: 2_000,
|
|
61
61
|
},
|
|
62
|
+
delayAutoclose: {
|
|
63
|
+
type: Number,
|
|
64
|
+
default: 2_000,
|
|
65
|
+
},
|
|
62
66
|
skipConfirmation: Boolean,
|
|
63
67
|
autoCloseSuccess: Boolean,
|
|
64
68
|
})
|
|
@@ -146,7 +150,6 @@ const initializeRequest = async (request = cachedRequest.value) => {
|
|
|
146
150
|
waiting.value = true
|
|
147
151
|
const [receiptObject] = await Promise.all([
|
|
148
152
|
waitForTransactionReceipt($wagmi, { hash: tx.value }),
|
|
149
|
-
delay(6_000),
|
|
150
153
|
])
|
|
151
154
|
await delay(props.delayAfter)
|
|
152
155
|
receipt.value = receiptObject
|
|
@@ -165,7 +168,7 @@ const initializeRequest = async (request = cachedRequest.value) => {
|
|
|
165
168
|
waiting.value = false
|
|
166
169
|
|
|
167
170
|
if (props.autoCloseSuccess && step.value === 'complete') {
|
|
168
|
-
await delay(
|
|
171
|
+
await delay(props.delayAutoclose)
|
|
169
172
|
open.value = false
|
|
170
173
|
await delay(300) // Animations...
|
|
171
174
|
}
|
|
@@ -3,7 +3,7 @@ import { type GetBalanceReturnType } from '@wagmi/core'
|
|
|
3
3
|
import { parseAbiItem, type PublicClient } from 'viem'
|
|
4
4
|
import type { MintEvent } from '~/utils/types'
|
|
5
5
|
|
|
6
|
-
export const CURRENT_STATE_VERSION =
|
|
6
|
+
export const CURRENT_STATE_VERSION = 7
|
|
7
7
|
export const MAX_BLOCK_RANGE = 1800n
|
|
8
8
|
export const MINT_BLOCKS = BLOCKS_PER_DAY
|
|
9
9
|
|
|
@@ -301,7 +301,7 @@ export const useOnchainStore = () => {
|
|
|
301
301
|
},
|
|
302
302
|
|
|
303
303
|
async fetchToken (address: `0x${string}`, id: number | string | bigint) {
|
|
304
|
-
const client = getPublicClient($wagmi, { chainId })
|
|
304
|
+
const client = getPublicClient($wagmi, { chainId }) as PublicClient
|
|
305
305
|
const mintContract = getContract({
|
|
306
306
|
address,
|
|
307
307
|
abi: MINT_ABI,
|
|
@@ -319,23 +319,28 @@ export const useOnchainStore = () => {
|
|
|
319
319
|
try {
|
|
320
320
|
console.info(`Fetching token #${tokenId}`)
|
|
321
321
|
|
|
322
|
-
const [data,
|
|
322
|
+
const [data, dataUri, closeAt] = await Promise.all([
|
|
323
|
+
mintContract.read.get([tokenId]) as Promise<[string, string, `0x${string}`[], bigint, bigint, bigint, bigint]>,
|
|
323
324
|
mintContract.read.uri([tokenId], { gas: 100_000_000_000 }) as Promise<string>,
|
|
324
325
|
mintContract.read.mintOpenUntil([tokenId]) as Promise<bigint>,
|
|
325
326
|
])
|
|
326
327
|
|
|
327
|
-
const
|
|
328
|
+
const [ name, description, _artifact, _renderer, mintedBlock, _closeAt, _extraData ] = data
|
|
329
|
+
|
|
330
|
+
const json = Buffer.from(dataUri.substring(29), `base64`).toString()
|
|
328
331
|
const metadata = JSON.parse(json)
|
|
329
332
|
|
|
330
333
|
const token: Token = {
|
|
331
334
|
tokenId,
|
|
332
335
|
collection: address,
|
|
333
|
-
name
|
|
334
|
-
description
|
|
336
|
+
name,
|
|
337
|
+
description,
|
|
335
338
|
image: metadata.image,
|
|
336
339
|
animationUrl: metadata.animation_url,
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
|
|
341
|
+
mintedBlock: BigInt(`${mintedBlock}`), // Force bigint
|
|
342
|
+
closeAt,
|
|
343
|
+
|
|
339
344
|
mintsBackfilledUntilBlock: 0n,
|
|
340
345
|
mintsFetchedUntilBlock: 0n,
|
|
341
346
|
mints: []
|
|
@@ -366,13 +371,13 @@ export const useOnchainStore = () => {
|
|
|
366
371
|
},
|
|
367
372
|
|
|
368
373
|
async fetchTokenMints (token: Token) {
|
|
374
|
+
const storedToken = this.collections[token.collection].tokens[token.tokenId.toString()]
|
|
369
375
|
const client = getPublicClient($wagmi, { chainId }) as PublicClient
|
|
370
376
|
const currentBlock = await client.getBlockNumber()
|
|
371
|
-
const
|
|
372
|
-
const storedToken = this.collections[token.collection].tokens[token.tokenId.toString()]
|
|
377
|
+
const untilBlock = token.mintedBlock + BLOCKS_PER_DAY
|
|
373
378
|
|
|
374
379
|
// We want to sync until now, or when the mint closed
|
|
375
|
-
const toBlock = currentBlock >
|
|
380
|
+
const toBlock = currentBlock > untilBlock ? untilBlock : currentBlock
|
|
376
381
|
|
|
377
382
|
if (token.mintsFetchedUntilBlock >= toBlock) {
|
|
378
383
|
return console.info(`mints for #${token.tokenId} already fetched`)
|
|
@@ -383,9 +388,9 @@ export const useOnchainStore = () => {
|
|
|
383
388
|
const maxRangeBlock = toBlock - MAX_BLOCK_RANGE
|
|
384
389
|
const fromBlock = token.mintsFetchedUntilBlock > maxRangeBlock // If we've already fetched
|
|
385
390
|
? token.mintsFetchedUntilBlock + 1n // we want to continue where we left off
|
|
386
|
-
: maxRangeBlock >
|
|
391
|
+
: maxRangeBlock > token.mintedBlock // Otherwise we'll go back as far as possible
|
|
387
392
|
? maxRangeBlock // (to our max range)
|
|
388
|
-
:
|
|
393
|
+
: token.mintedBlock // (or all the way to when the token minted)
|
|
389
394
|
|
|
390
395
|
// Load mints in range
|
|
391
396
|
this.addTokenMints(token, await this.loadMintEvents(token, fromBlock, toBlock))
|
|
@@ -400,17 +405,16 @@ export const useOnchainStore = () => {
|
|
|
400
405
|
},
|
|
401
406
|
|
|
402
407
|
async backfillTokenMints (token: Token) {
|
|
403
|
-
const mintedAtBlock = token.untilBlock - MINT_BLOCKS
|
|
404
408
|
const storedToken = this.collections[token.collection].tokens[token.tokenId.toString()]
|
|
405
409
|
|
|
406
410
|
// If we've backfilled all the way;
|
|
407
|
-
if (storedToken.mintsBackfilledUntilBlock <=
|
|
411
|
+
if (storedToken.mintsBackfilledUntilBlock <= token.mintedBlock) return
|
|
408
412
|
|
|
409
413
|
// We want to fetch the tokens up until where we stopped backfilling (excluding the last block)
|
|
410
414
|
const toBlock = storedToken.mintsBackfilledUntilBlock - 1n
|
|
411
415
|
|
|
412
416
|
// We want to fetch until our max range (5000), or until when the token minted
|
|
413
|
-
const fromBlock = toBlock - MAX_BLOCK_RANGE >
|
|
417
|
+
const fromBlock = toBlock - MAX_BLOCK_RANGE > token.mintedBlock ? toBlock - MAX_BLOCK_RANGE : token.mintedBlock
|
|
414
418
|
console.info(`Backfilling token mints blocks ${fromBlock}-${toBlock}`)
|
|
415
419
|
|
|
416
420
|
// Finally, we update our database
|
package/nuxt.config.ts
CHANGED
|
@@ -19,7 +19,7 @@ export default defineNuxtConfig({
|
|
|
19
19
|
creatorAddress: '',
|
|
20
20
|
defaultAvatar: '/icons/opepen.svg',
|
|
21
21
|
description: 'To mint is a human right.',
|
|
22
|
-
factoryAddress: '
|
|
22
|
+
factoryAddress: '0xdc27b70874E36f00290Bd588D5B31AD510ca88a5',
|
|
23
23
|
platformUrl: 'https://networked.art',
|
|
24
24
|
rpc1: 'https://ethereum-sepolia.rpc.subquery.network/public',
|
|
25
25
|
rpc2: 'https://ethereum-sepolia-rpc.publicnode.com',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@visualizevalue/mint-app-base",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.60",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"viem": "2.x",
|
|
25
25
|
"vite": "^5.4.3",
|
|
26
26
|
"vue-virtual-scroller": "2.0.0-beta.8",
|
|
27
|
-
"@visualizevalue/mint-utils": "^0.0.
|
|
27
|
+
"@visualizevalue/mint-utils": "^0.0.4"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/codemirror": "^5.60.15",
|
package/utils/abis.ts
CHANGED
|
@@ -45,17 +45,16 @@ export const MINT_ABI = parseAbi([
|
|
|
45
45
|
'event URI(string value, uint256 indexed id)',
|
|
46
46
|
'event Withdrawal(uint256 amount)',
|
|
47
47
|
'function acceptOwnership()',
|
|
48
|
-
'function artifact(uint256 tokenId) view returns (bytes content)',
|
|
49
48
|
'function balanceOf(address account, uint256 id) view returns (uint256)',
|
|
50
49
|
'function balanceOfBatch(address[] accounts, uint256[] ids) view returns (uint256[])',
|
|
51
50
|
'function burn(address account, uint256 tokenId, uint256 amount)',
|
|
52
51
|
'function contractURI() view returns (string)',
|
|
53
|
-
'function create(string tokenName, string tokenDescription, bytes[] tokenArtifact, uint32 tokenRenderer,
|
|
52
|
+
'function create(string tokenName, string tokenDescription, bytes[] tokenArtifact, uint32 tokenRenderer, uint128 tokenData)',
|
|
53
|
+
'function get(uint256 tokenId) view returns (string name, string description, address[] artifact, uint32 renderer, uint32 mintedBlock, uint64 closeAt, uint128 data)',
|
|
54
54
|
'function init(string contractName, string contractSymbol, string contractDescription, bytes[] contractImage, address renderer, address owner)',
|
|
55
55
|
'function initBlock() view returns (uint256)',
|
|
56
56
|
'function isApprovedForAll(address account, address operator) view returns (bool)',
|
|
57
57
|
'function latestTokenId() view returns (uint256)',
|
|
58
|
-
'function metadata() view returns (string name, string symbol, string description)',
|
|
59
58
|
'function mint(uint256 tokenId, uint256 amount) payable',
|
|
60
59
|
'function mintOpenUntil(uint256 tokenId) view returns (uint256)',
|
|
61
60
|
'function owner() view returns (address)',
|
|
@@ -68,7 +67,6 @@ export const MINT_ABI = parseAbi([
|
|
|
68
67
|
'function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes data)',
|
|
69
68
|
'function setApprovalForAll(address operator, bool approved)',
|
|
70
69
|
'function supportsInterface(bytes4 interfaceId) view returns (bool)',
|
|
71
|
-
'function tokens(uint256) view returns (string name, string description, uint32 renderer, uint32 blocks, uint192 data)',
|
|
72
70
|
'function transferOwnership(address newOwner)',
|
|
73
71
|
'function uri(uint256 tokenId) view returns (string)',
|
|
74
72
|
'function version() view returns (uint256)',
|
|
@@ -76,7 +74,10 @@ export const MINT_ABI = parseAbi([
|
|
|
76
74
|
])
|
|
77
75
|
|
|
78
76
|
export const RENDERER_ABI = parseAbi([
|
|
79
|
-
'function name()
|
|
80
|
-
'function version()
|
|
77
|
+
'function name() pure returns (string)',
|
|
78
|
+
'function version() pure returns (uint256)',
|
|
79
|
+
'function uri(uint256 tokenId, (string name, string description, address[] artifact, uint32 renderer, uint32 mintedBlock, uint64 closeAt, uint128 data) token) view returns (string)',
|
|
80
|
+
'function animationURI(uint256, (string name, string description, address[] artifact, uint32 renderer, uint32 mintedBlock, uint64 closeAt, uint128 data)) pure returns (string)',
|
|
81
|
+
'function imageURI(uint256, (string name, string description, address[] artifact, uint32 renderer, uint32 mintedBlock, uint64 closeAt, uint128 data) token) view returns (string)',
|
|
81
82
|
])
|
|
82
83
|
|
package/utils/time.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { BLOCKS_PER_CACHE, BLOCKS_PER_HOUR, BLOCKS_PER_DAY } from '@visualizevalue/mint-utils/time'
|
|
2
|
-
import { blocksToSeconds, delay, nowInSeconds } from '@visualizevalue/mint-utils'
|
|
1
|
+
import { BLOCK_TIME, BLOCKS_PER_CACHE, BLOCKS_PER_HOUR, BLOCKS_PER_DAY } from '@visualizevalue/mint-utils/time'
|
|
2
|
+
import { blocksToSeconds, delay, nowInSeconds, secondsToBlocks } from '@visualizevalue/mint-utils'
|
|
3
3
|
|
|
4
4
|
export {
|
|
5
|
-
BLOCKS_PER_CACHE, BLOCKS_PER_HOUR, BLOCKS_PER_DAY,
|
|
6
|
-
blocksToSeconds, delay, nowInSeconds,
|
|
5
|
+
BLOCK_TIME, BLOCKS_PER_CACHE, BLOCKS_PER_HOUR, BLOCKS_PER_DAY,
|
|
6
|
+
blocksToSeconds, delay, nowInSeconds, secondsToBlocks,
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const now = ref(nowInSeconds())
|
package/utils/types.ts
CHANGED
|
@@ -44,10 +44,10 @@ export interface Token {
|
|
|
44
44
|
tokenId: bigint
|
|
45
45
|
name: string
|
|
46
46
|
description: string
|
|
47
|
-
image: string
|
|
48
|
-
animationUrl?: string
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
image: string
|
|
48
|
+
animationUrl?: string
|
|
49
|
+
closeAt: bigint
|
|
50
|
+
mintedBlock: bigint
|
|
51
51
|
mintsFetchedUntilBlock: bigint
|
|
52
52
|
mintsBackfilledUntilBlock: bigint
|
|
53
53
|
mints: MintEvent[]
|