a manifold extension to port fully onchain an existing collection minted with offchain content
clgsms/scripts/redeem.js
JavaScript · 78 lines · 3 KBRAWDOWNLOAD
/**
* PHASE 2 — approve the extension and burn/redeem tokens you hold.
*
* FROM_ID=1 TO_ID=1 npx hardhat run scripts/redeem.js --network sepolia
* IDS=1,4,9 npx hardhat run scripts/redeem.js --network mainnet
*
* Env:
* CREATOR / EXTENSION default: deployments/<network>.json
* IDS comma-separated tokenIds (wins over FROM_ID/TO_ID)
* FROM_ID / TO_ID token range, default 1..100
* BATCH=0 send one burnRedeem per token instead of a batch
*
* Only tokens that are redeemable AND owned by the signer are attempted; the
* rest are reported and skipped, so this is safe to point at a whole range.
*/
import { addressFor, connect, creatorAt, decodeTokenURI, main, tokenRange } from "./_lib.js";
main(async () => {
const { ethers, net, signer } = await connect();
const creator = creatorAt(ethers, addressFor("creator", net), signer);
const extension = addressFor("extension", net);
const ext = await ethers.getContractAt("ColorgasmRedeemExtension", extension);
const wanted = process.env.IDS
? process.env.IDS.split(",").map((s) => Number(s.trim()))
: tokenRange();
// Which of those can actually be redeemed right now.
const ids = [];
for (const id of wanted) {
const [redeemable, owner] = await Promise.all([
ext.isRedeemable(id),
creator.ownerOf(id).catch(() => null),
]);
if (owner === null) console.log(`#${id}: does not exist (burned already?) — skipped`);
else if (owner !== signer.address) console.log(`#${id}: held by ${owner} — skipped`);
else if (!redeemable) console.log(`#${id}: not stored onchain yet — skipped`);
else ids.push(id);
}
if (ids.length === 0) {
console.log("\nnothing to redeem");
return;
}
console.log(`\nredeeming #${ids.join(", #")}\n`);
if (!(await creator.isApprovedForAll(signer.address, extension))) {
const tx = await creator.setApprovalForAll(extension, true);
console.log(`setApprovalForAll ${tx.hash}`);
await tx.wait();
}
const pairs = [];
if (process.env.BATCH === "0") {
for (const id of ids) {
const newId = await ext.burnRedeem.staticCall(id);
const tx = await ext.burnRedeem(id);
const receipt = await tx.wait();
console.log(` #${id} -> #${newId} ${receipt.gasUsed} gas ${tx.hash}`);
pairs.push([id, newId]);
}
} else {
const newIds = await ext.burnRedeemBatch.staticCall(ids);
const tx = await ext.burnRedeemBatch(ids);
const receipt = await tx.wait();
console.log(` batch of ${ids.length}: ${receipt.gasUsed} gas ${tx.hash}`);
ids.forEach((id, i) => pairs.push([id, newIds[i]]));
}
console.log("\nredeemed:");
for (const [id, newId] of pairs) {
const { json, imageBytes } = decodeTokenURI(await creator.tokenURI(newId));
console.log(
` #${id} -> #${newId} ${json.name} ${imageBytes.length} B image, fully onchain`,
);
}
console.log(`\nredeemedCount ${await ext.redeemedCount()}`);
});