forked from DA0-DA0/dao-dao-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnft.ts
113 lines (104 loc) · 3 KB
/
nft.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// If name is only a number, prefix with collection name. Fallback to token ID
import {
GenericToken,
NftCardInfo,
StargazeNft,
StargazeNftMediaType,
} from '@dao-dao/types'
import { STARGAZE_URL_BASE } from './constants'
// if name does not exist.
export const getNftName = (
collectionName: string,
tokenId: string,
tokenName?: string
) =>
!tokenName || /^[0-9]+$/.test(tokenName.trim())
? `${collectionName} ${(tokenName || tokenId).trim()}`.trim()
: tokenName
// Uploads an NFT to NFT Storage and returns the metadata.
export const uploadNft = async (
name: string,
description: string,
image?: File,
extra?: string
): Promise<{
cid: string
metadataUrl: string
imageUrl: string | undefined
}> => {
const form = new FormData()
form.append('name', name)
form.append('description', description)
if (image) {
form.append('image', image)
}
if (extra) {
form.append('extra', extra)
}
// Next.js API route.
const response = await fetch('/api/uploadNft', {
method: 'POST',
body: form,
})
if (response.ok) {
const data = await response.json()
return data
} else {
// Vercel limits file size to 4.5MB and responds with 413 if exceeded. Add
// some buffer to make room for the other fields.
if (response.status === 413) {
throw new Error('File too large. Max 4MB.')
}
const { error } = await response
.json()
.catch(() => ({ error: 'Unknown error' }))
throw new Error(error)
}
}
export const getNftKey = (
chainId: string,
collectionAddress: string,
tokenId: string
): string =>
[chainId, collectionAddress, tokenId]
// Ensure this produces an empty string if the variables are empty.
.filter(Boolean)
.join(':')
export const nftCardInfoFromStargazeIndexerNft = (
chainId: string,
token: StargazeNft,
offerToken: GenericToken | null = null,
timestamp: Date = new Date()
): NftCardInfo => ({
key: getNftKey(
chainId,
token.collection.contractAddress || '',
token.tokenId || ''
),
chainId,
collectionAddress: token.collection.contractAddress || '',
collectionName: token.collection.name || 'Unknown Collection',
tokenId: token.tokenId || '',
externalLink: {
href: `${STARGAZE_URL_BASE}/media/${token.collection.contractAddress}/${token.tokenId}`,
name: 'Stargaze',
},
imageUrl:
// The Stargaze API resizes animated images (gifs) into `video/mp4`
// mimetype, which cannot display in an `img` tag. If this is a gif, use the
// original media URL instead of the resized one.
(token.media?.type !== StargazeNftMediaType.AnimatedImage &&
token.media?.visualAssets?.lg?.url) ||
token.media?.url ||
undefined,
name: token.name || token.tokenId || 'Unknown NFT',
description: token.description || undefined,
highestOffer: offerToken
? {
offerToken,
amountUsd: token.highestOffer?.offerPrice?.amountUsd,
amount: Number(token.highestOffer?.offerPrice?.amount),
}
: undefined,
fetchedTimestamp: timestamp,
})