Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
osipov-mit committed Dec 27, 2023
1 parent 2c151c3 commit 8a8b433
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 48 deletions.
20 changes: 18 additions & 2 deletions src/batchState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Store } from '@subsquid/typeorm-store';
import { Account, Nft, NftCollection, Transfer } from './model';
import { randomUUID } from 'crypto';
import { In } from 'typeorm';

import { Account, Nft, NftCollection, Transfer } from './model';
import { logger } from './logger';

export class BatchState {
Expand Down Expand Up @@ -32,20 +33,25 @@ export class BatchState {
async save() {
if (this.accounts.size > 0) {
await this.store.save(Array.from(this.accounts.values()));
logger.info('Accounts saved', { count: this.accounts.size });
}
if (this.collections.size > 0) {
await this.store.save(Array.from(this.collections.values()));
logger.info('Collections saved', { count: this.collections.size });
}
if (this.nfts.size > 0) {
await this.store.save(Array.from(this.nfts.values()));
logger.info('Nfts saved', { count: this.nfts.size });
}
if (this.transfers.size > 0) {
await this.store.save(Array.from(this.transfers.values()));
logger.info('Transfers saved', { count: this.transfers.size });
}
if (this.burntNfts.size > 0) {
const transfers = await this.store.findBy(Transfer, { nft: { id: In(Array.from(this.burntNfts.keys())) } });
await this.store.remove(transfers);
await this.store.remove(Array.from(this.burntNfts.values()));
logger.info('Nfts deleted', { count: this.burntNfts.size, transfersCount: transfers.length });
}
}

Expand Down Expand Up @@ -116,6 +122,7 @@ export class BatchState {
const id = `${collection.id}-${tokenId}`;

const owner = await this.getAccount(ownerAddress);

let nft = mint
? new Nft({
id,
Expand All @@ -131,9 +138,18 @@ export class BatchState {
})
: await this.getNft(id);

if (!nft) {
logger.error('NFT not found', { id: id, block: blockNumber.toString() });
return;
}

nft.attribUrl = attribUrl;

logger.info('Mint', { owner: ownerAddress, collection: collection.id, id });
logger.info(mint ? 'Mint' : 'Nft Changed', {
id,
owner: ownerAddress,
block: blockNumber.toString(),
});

this.nfts.set(`${collection.id}-${tokenId}`, nft);
}
Expand Down
103 changes: 59 additions & 44 deletions src/handlers/cb-nft.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,78 @@
import { ProgramMetadata } from '@gear-js/api';
import { BatchState } from '../batchState';
import { readFileSync } from 'fs';

import { getCollectionDescription, getCollectionName } from './helpers';
import { BatchState } from '../batchState';
import { MasterNftEvent } from '../types';
import { getDate } from '../utils';
import { getCollectionDescription, getCollectionName } from './helpers';
import { logger } from '../logger';

const meta = ProgramMetadata.from(readFileSync('./assets/cb-nft.meta.txt', 'utf8'));

export async function cbNftHandler(
state: BatchState,
id: string,
payload: string,
source: string,
blockNumber: bigint,
ts: Date,
linkIsFull = false,
) {
const data = meta.createType<MasterNftEvent>(meta.types.others.output, payload);
if (data.isMinted || data.isNftChanged) {
const action = data.isMinted ? data.asMinted : data.asNftChanged;
const tokenId = action.tokenId.toString();
const { media, owner, activities, link } = action.meta;
let collection = await state.getCollection(source);
if (!collection) {
const [collectionName, collectionDesc] = await Promise.all([
getCollectionName(meta, source),
getCollectionDescription(meta, source),
]);
collection = state.newCollection(source, collectionName, collectionDesc);
}

await state.mintNft(
tokenId,
collection,
owner.toHex(),
activities.map(([name, times, ts]) => {
const timesFormatted = name.toString() === 'NFT minted' ? ', ' : ` ${times.toString()} times, `;
const date = getDate(ts.toString());
const dateFormatted = name.toString() === 'NFT minted' ? `date: ${date}` : `last game date: ${date}`;
return `${name}${timesFormatted}${dateFormatted}`;
}),
collection.description,
collection.name + ' - ' + media.toString(),
linkIsFull ? link.toString() : `${link.toString()}/${tokenId}.png`,
blockNumber,
ts,
data.isMinted,
);
} else if (data.isTransferred) {
const { tokenId, owner, recipient } = data.asTransferred;
const collection = await state.getCollection(source);
await state.transferNft(tokenId.toString(), collection, owner.toHex(), recipient.toHex(), ts, blockNumber);
} else if (data.isBurnt) {
const { tokenId } = data.asBurnt;
await state.burnNft(tokenId.toString(), source);
} else if (data.isApproved) {
const { approvedAccount, tokenId } = data.asApproved;
await state.approveAccount(tokenId.toString(), source, approvedAccount.toHex());
} else if (data.isApprovalRevoked) {
const { tokenId } = data.asApprovalRevoked;
await state.revokeApprove(tokenId.toString(), source);
try {
if (data.isMinted || data.isNftChanged) {
const action = data.isMinted ? data.asMinted : data.asNftChanged;

const tokenId = action.tokenId.toString();

const { media, owner, activities, link } = action.meta;
let collection = await state.getCollection(source);
if (!collection) {
const [collectionName, collectionDesc] = await Promise.all([
getCollectionName(meta, source),
getCollectionDescription(meta, source),
]);
collection = state.newCollection(source, collectionName, collectionDesc);
}

await state.mintNft(
tokenId,
collection,
owner.toHex(),
activities.map(([name, times, ts]) => {
const timesFormatted = name.toString() === 'NFT minted' ? ', ' : ` ${times.toString()} times, `;
const date = getDate(ts.toString());
const dateFormatted = name.toString() === 'NFT minted' ? `date: ${date}` : `last game date: ${date}`;
return `${name}${timesFormatted}${dateFormatted}`;
}),
collection.description,
collection.name + ' - ' + tokenId,
linkIsFull ? link.toString() : `${link.toString()}/${media.toString()}.png`,
blockNumber,
ts,
data.isMinted,
);
} else if (data.isTransferred) {
const { tokenId, owner, recipient } = data.asTransferred;
const collection = await state.getCollection(source);
await state.transferNft(tokenId.toString(), collection, owner.toHex(), recipient.toHex(), ts, blockNumber);
} else if (data.isBurnt) {
const { tokenId } = data.asBurnt;
await state.burnNft(tokenId.toString(), source);
} else if (data.isApproved) {
const { approvedAccount, tokenId } = data.asApproved;
await state.approveAccount(tokenId.toString(), source, approvedAccount.toHex());
} else if (data.isApprovalRevoked) {
const { tokenId } = data.asApprovalRevoked;
await state.revokeApprove(tokenId.toString(), source);
}
} catch (err) {
logger.error('Error while processing CB NFT', {
err: err.message,
payload: data.toJSON(),
msgId: id,
bn: blockNumber.toString(),
});
}
}
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ processor.run(new TypeormDatabase(), async (ctx) => {
if (event.name !== 'Gear.UserMessageSent') continue;

const {
message: { source, payload, details },
message: { source, payload, details, id },
} = event.args as UserMessageSentArgs;

if (payload === '0x') continue;
if (details && details.code.__kind !== 'Success') continue;

if (programs.includes(source)) {
await cbNftHandler(state, payload, source, blockNumber, ts);
await cbNftHandler(state, id, payload, source, blockNumber, ts);
} else if (simpleNfts.includes(source)) {
await draftNftHandler(state, payload, source, blockNumber, ts);
}
Expand Down

0 comments on commit 8a8b433

Please sign in to comment.