@visualizevalue/mint-app-base 0.1.59 → 0.1.61

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 CHANGED
@@ -16,7 +16,7 @@ NUXT_PUBLIC_CREATOR_ADDRESS=0xc8f8e2F59Dd95fF67c3d39109ecA2e2A017D4c8a
16
16
  # =========================
17
17
  # SERVICES
18
18
  # =========================
19
- NUXT_PUBLIC_BLOCK_EXPLORER=https://etherscan.io
19
+ NUXT_PUBLIC_BLOCK_EXPLORER=https://sepolia.etherscan.io
20
20
  NUXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=
21
21
  NUXT_PUBLIC_RPC1=
22
22
  NUXT_PUBLIC_RPC2=
@@ -25,5 +25,5 @@ NUXT_PUBLIC_RPC3=
25
25
  # =========================
26
26
  # ONCHAIN
27
27
  # =========================
28
- NUXT_PUBLIC_FACTORY_ADDRESS=0xfd0edC665A0566EF44f9BD7aB4E45DF7A7601a2b
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: '0xf6f1f8ea7bbc82a3b3da6fba1c24408e7a9a8fab',
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))
@@ -22,8 +22,6 @@ const { image, animationUrl, name, description } = useCreateMintData()
22
22
 
23
23
  <style scoped>
24
24
  .mint-preview {
25
- position: sticky;
26
- top: var(--spacer);
27
25
  height: min-content;
28
26
  place-content: start center;
29
27
  border-radius: var(--card-border-radius);
@@ -31,6 +29,11 @@ const { image, animationUrl, name, description } = useCreateMintData()
31
29
  grid-template-columns: 20% 1fr;
32
30
  gap: var(--spacer);
33
31
 
32
+ @media (--md) {
33
+ position: sticky;
34
+ top: var(--spacer);
35
+ }
36
+
34
37
  > * {
35
38
  grid-column: span 2;
36
39
  }
@@ -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 mintOpen = computed(() => currentBlock.value && props.token.untilBlock > currentBlock.value)
57
- const blocksRemaining = computed(() => props.token.untilBlock - (currentBlock.value || 0n))
58
- const secondsRemaining = computed(() => blocksToSeconds(blocksRemaining.value))
59
- const until = computed(() => nowInSeconds() + secondsRemaining.value)
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.untilBlock }}</p>
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 - mintedAtBlock" /></span>
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 mintedAtBlock = computed(() => token.untilBlock - MINT_BLOCKS)
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.untilBlock }}</p>
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(2_000)
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
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, untilBlock] = await Promise.all([
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 json = Buffer.from(data.substring(29), `base64`).toString()
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: metadata.name,
334
- description: metadata.description,
336
+ name,
337
+ description,
335
338
  image: metadata.image,
336
339
  animationUrl: metadata.animation_url,
337
- scriptUrl: metadata.script_url,
338
- untilBlock,
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 mintedAtBlock = token.untilBlock - MINT_BLOCKS
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 > token.untilBlock ? token.untilBlock : 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 > mintedAtBlock // Otherwise we'll go back as far as possible
391
+ : maxRangeBlock > token.mintedBlock // Otherwise we'll go back as far as possible
387
392
  ? maxRangeBlock // (to our max range)
388
- : mintedAtBlock // (or all the way to when the token minted)
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 <= mintedAtBlock) return
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 > mintedAtBlock ? toBlock - MAX_BLOCK_RANGE : mintedAtBlock
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: '0x9B47a8351a080ef055aB81E863CF67F3bdCA8365',
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.59",
3
+ "version": "0.1.61",
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.3"
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, uint192 tokenData)',
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() external pure returns (string memory)',
80
- 'function version() external pure returns (uint 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
- scriptUrl?: string,
50
- untilBlock: bigint
47
+ image: string
48
+ animationUrl?: string
49
+ closeAt: bigint
50
+ mintedBlock: bigint
51
51
  mintsFetchedUntilBlock: bigint
52
52
  mintsBackfilledUntilBlock: bigint
53
53
  mints: MintEvent[]