-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbatch-mint-with-assets-ids.ts
137 lines (119 loc) · 4.09 KB
/
batch-mint-with-assets-ids.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import fs from 'fs';
import hre from 'hardhat';
import invariant from 'tiny-invariant';
import { Address, decodeEventLog } from 'viem';
import { KanariaItems } from '../abis/KanariaItems.js';
import { getOrCreateNdjosnLogFile } from './utils/get-or-create-ndjosn-log-file.js';
import { jsonStringifyWithBigint } from './utils/json-stringify-with-bigint.js';
import { chunkArray } from './utils/utils.js';
export type BatchMintWithAssetsIdsInputData = {
contractAddress: Address;
assetIds: bigint[][];
to: Address;
};
type LogEntry = Record<
string,
{
inputData: BatchMintWithAssetsIdsInputData;
hash: Address;
tokenIds: bigint[];
}
>;
export const batchMintWithAssetsIds = async (
batchMintWithAssetsIdsInputDataArray: BatchMintWithAssetsIdsInputData[],
logFilePath: string,
) => {
const [walletClient] = await hre.viem.getWalletClients();
const publicClient = await hre.viem.getPublicClient();
// Get existing minted batches logs, or create the file if it doesn't exist
const alreadyMintedBatches =
await getOrCreateNdjosnLogFile<LogEntry>(logFilePath);
for (const batchMintWithAssetsIdsInputData of batchMintWithAssetsIdsInputDataArray) {
const { contractAddress, to, assetIds } = batchMintWithAssetsIdsInputData;
const assetIdsChunks = chunkArray(assetIds, 30);
console.log('Total chunks split', {
assetIdsChunksLength: assetIdsChunks.length,
});
for (const [
chunkIndex,
destinationTokenIdsChunk,
] of assetIdsChunks.entries()) {
console.log(`Processing chunk ${chunkIndex} of ${assetIdsChunks.length}`);
const uniqueLogIdentifier = `${contractAddress}-${assetIds[0][0].toString()}-${assetIds[
assetIds.length - 1
][0].toString()}-${to}-chunkIndex${chunkIndex}`;
// Check if this batch has already been minted
if (alreadyMintedBatches.find((batch) => !!batch[uniqueLogIdentifier])) {
console.warn(
`Log for this identifier already exists ${uniqueLogIdentifier}. Skipping`,
{
batchMintWithAssetsIdsInputData: {
contractAddress,
to,
assetIds: destinationTokenIdsChunk,
},
},
);
continue;
}
console.log('Simulating contract call', {
batchMintWithAssetsIdsInputData: {
contractAddress,
to,
assetIds: destinationTokenIdsChunk,
},
});
const { request } = await publicClient.simulateContract({
abi: KanariaItems,
address: contractAddress,
functionName: 'batchMintWithAssets',
args: [to, destinationTokenIdsChunk],
});
console.log('Sending transaction');
const hash = await walletClient.writeContract(request);
console.log('Waiting for transaction receipt for hash', hash);
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log('Transaction success', hash);
const events = receipt.logs.map((log) => {
try {
return decodeEventLog({
data: log.data,
topics: log.topics,
eventName: 'Transfer',
abi: KanariaItems,
strict: false,
});
} catch (e) {
return null;
}
});
const tokenIds = events
.filter((event) => event !== null)
.filter((event) => event?.eventName === 'Transfer')
.map((event) => {
if (event?.args?.tokenId) {
return event.args.tokenId;
}
console.error('Token ID is not present on event log', event);
throw new Error('Token ID is not present on event log');
});
invariant(tokenIds, 'Token IDs are not present on event log');
const logEntry: LogEntry = {
[uniqueLogIdentifier]: {
inputData: {
contractAddress,
to,
assetIds: destinationTokenIdsChunk,
},
hash,
tokenIds,
},
};
await fs.promises.appendFile(
logFilePath,
`${jsonStringifyWithBigint(logEntry)}\n`,
);
}
}
console.log('All done');
};