1
+ import { fetchJson } from "@ethersproject/web"
2
+ import { Contract } from "ethers"
1
3
import { AddressOnNetwork } from "../../accounts"
2
4
import { getNFTCollections , getNFTs , getNFTsTransfers } from "../../lib/nfts"
3
5
import { getSimpleHashNFTs } from "../../lib/simple-hash"
@@ -9,7 +11,13 @@ import ChainService from "../chain"
9
11
import { ServiceCreatorFunction , ServiceLifecycleEvents } from "../types"
10
12
import { getOrCreateDB , NFTsDatabase , FreshCollectionsMap } from "./db"
11
13
import { getUNIXTimestamp , normalizeEVMAddress } from "../../lib/utils"
12
- import { MINUTE } from "../../constants"
14
+ import { MEZO_TESTNET , MINUTE } from "../../constants"
15
+ import { sameNetwork } from "../../networks"
16
+ import {
17
+ NFT_COLLECTION_ID ,
18
+ NFT_CONTRACT_ADDRESS ,
19
+ } from "../campaign/matsnet-nft"
20
+ import { isDisabled } from "../../features"
13
21
14
22
interface Events extends ServiceLifecycleEvents {
15
23
isReloadingNFTs : boolean
@@ -103,6 +111,7 @@ export default class NFTsService extends BaseService<Events> {
103
111
if ( accountsToFetch . length ) {
104
112
await this . fetchCollections ( accountsToFetch )
105
113
await this . fetchPOAPs ( accountsToFetch )
114
+ await this . fetchCampaignNFTs ( accountsToFetch )
106
115
}
107
116
}
108
117
@@ -118,6 +127,7 @@ export default class NFTsService extends BaseService<Events> {
118
127
await this . fetchCollections ( accountsToFetch ) // refetch only if there are some transfers
119
128
}
120
129
await this . fetchPOAPs ( accountsToFetch )
130
+ await this . fetchCampaignNFTs ( accountsToFetch )
121
131
}
122
132
123
133
async fetchCollections ( accounts : AddressOnNetwork [ ] ) : Promise < void > {
@@ -172,6 +182,59 @@ export default class NFTsService extends BaseService<Events> {
172
182
)
173
183
}
174
184
185
+ async fetchCampaignNFTs ( accounts : AddressOnNetwork [ ] ) : Promise < void > {
186
+ if ( isDisabled ( "SUPPORT_MEZO_NETWORK" ) ) {
187
+ return
188
+ }
189
+
190
+ const provider = this . chainService . providerForNetworkOrThrow ( MEZO_TESTNET )
191
+ const contract = new Contract (
192
+ NFT_CONTRACT_ADDRESS ,
193
+ [
194
+ "function balanceOf(address, uint256) view returns (uint256)" ,
195
+ "function uri(uint256) view returns (string)" ,
196
+ ] ,
197
+ provider ,
198
+ )
199
+
200
+ await Promise . allSettled (
201
+ accounts
202
+ . filter ( ( { network } ) => sameNetwork ( network , MEZO_TESTNET ) )
203
+ . map ( async ( account ) => {
204
+ const { address } = account
205
+
206
+ const hasTahoNFT =
207
+ ( await contract . callStatic . balanceOf ( address , 1 ) ) > 0n
208
+
209
+ const nfts : NFT [ ] = [ ]
210
+
211
+ if ( hasTahoNFT ) {
212
+ const metadataURI = await contract . callStatic . uri ( 1 )
213
+
214
+ const details = await fetchJson ( metadataURI )
215
+
216
+ nfts . push ( {
217
+ collectionID : NFT_COLLECTION_ID ,
218
+ id : `CAMPAIGN.${ contract . address } .${ address } ` ,
219
+ previewURL : details . image ,
220
+ thumbnailURL : details . image ,
221
+ name : details . name ,
222
+ description : details . description ,
223
+ tokenId : "1" ,
224
+ contract : contract . address ,
225
+ owner : address ,
226
+ isBadge : false ,
227
+ network : MEZO_TESTNET ,
228
+ attributes : [ ] ,
229
+ rarity : { } ,
230
+ } )
231
+
232
+ await this . updateSavedNFTs ( NFT_COLLECTION_ID , account , nfts , { } )
233
+ }
234
+ } ) ,
235
+ )
236
+ }
237
+
175
238
async fetchNFTsFromDatabase (
176
239
collectionID : string ,
177
240
account : AddressOnNetwork ,
@@ -224,7 +287,10 @@ export default class NFTsService extends BaseService<Events> {
224
287
225
288
let updatedCollection : NFTCollection | undefined
226
289
227
- if ( collectionID === POAP_COLLECTION_ID ) {
290
+ if (
291
+ collectionID === POAP_COLLECTION_ID ||
292
+ collectionID . startsWith ( "campaign::" )
293
+ ) {
228
294
// update number of poaps
229
295
updatedCollection = await this . db . updateCollectionData (
230
296
collectionID ,
0 commit comments