feat: demonstrate state-preserving V2 upgrade
This commit is contained in:
@@ -18,12 +18,19 @@ const bankRequirements = [
|
||||
eventSignature("Upgraded", [parameter("implementation", "address", true)]),
|
||||
];
|
||||
const tokenRequirements = [functionSignature("balanceOf", [parameter("account", "address")], ["uint256"], "view")];
|
||||
const bankV2Requirements = [
|
||||
...bankRequirements,
|
||||
functionSignature("transferBalance", [parameter("recipient", "address"), parameter("amount", "uint256")], [], "nonpayable"),
|
||||
eventSignature("BalanceTransferred", [parameter("from", "address", true), parameter("to", "address", true), parameter("amount", "uint256", false)]),
|
||||
];
|
||||
|
||||
export function extractAbi(artifact, contractName) {
|
||||
if (!artifact || typeof artifact !== "object" || !Array.isArray(artifact.abi)) {
|
||||
throw new Error(`${contractName} artifact must contain an ABI`);
|
||||
}
|
||||
const requirements = contractName === "BankV1" ? bankRequirements : contractName === "MockUSDC" ? tokenRequirements : null;
|
||||
const requirements = contractName === "BankV1" ? bankRequirements
|
||||
: contractName === "BankV2" ? bankV2Requirements
|
||||
: contractName === "MockUSDC" ? tokenRequirements : null;
|
||||
if (!requirements) throw new Error(`unsupported contract artifact ${contractName}`);
|
||||
for (const requirement of requirements) {
|
||||
const entries = artifact.abi.filter((entry) => entry && entry.type === requirement.type && entry.name === requirement.name);
|
||||
@@ -53,21 +60,27 @@ function matchesParameters(actual, expected) {
|
||||
});
|
||||
}
|
||||
|
||||
export function renderContractsModule(bankV1Abi, mockUsdcAbi) {
|
||||
return `/* This file is generated by tools/sync-web-artifacts.mjs. Do not edit. */\n\nexport const bankV1Abi = ${JSON.stringify(bankV1Abi, null, 2)} as const;\n\nexport const mockUsdcAbi = ${JSON.stringify(mockUsdcAbi, null, 2)} as const;\n`;
|
||||
export function renderContractsModule(bankV1Abi, bankV2Abi, mockUsdcAbi) {
|
||||
return `/* This file is generated by tools/sync-web-artifacts.mjs. Do not edit. */\n\nexport const bankV1Abi = ${JSON.stringify(bankV1Abi, null, 2)} as const;\n\nexport const bankV2Abi = ${JSON.stringify(bankV2Abi, null, 2)} as const;\n\nexport const mockUsdcAbi = ${JSON.stringify(mockUsdcAbi, null, 2)} as const;\n`;
|
||||
}
|
||||
|
||||
export async function syncArtifacts({
|
||||
bankArtifactPath = resolve(repositoryRoot, "out/BankV1.sol/BankV1.json"),
|
||||
bankV2ArtifactPath = resolve(repositoryRoot, "out/BankV2.sol/BankV2.json"),
|
||||
tokenArtifactPath = resolve(repositoryRoot, "out/MockUSDC.sol/MockUSDC.json"),
|
||||
outputPath = resolve(repositoryRoot, "web/src/generated/contracts.ts"),
|
||||
check = false,
|
||||
} = {}) {
|
||||
const [bankArtifact, tokenArtifact] = await Promise.all([
|
||||
const [bankArtifact, bankV2Artifact, tokenArtifact] = await Promise.all([
|
||||
readArtifact(bankArtifactPath, "BankV1"),
|
||||
readArtifact(bankV2ArtifactPath, "BankV2"),
|
||||
readArtifact(tokenArtifactPath, "MockUSDC"),
|
||||
]);
|
||||
const contents = renderContractsModule(extractAbi(bankArtifact, "BankV1"), extractAbi(tokenArtifact, "MockUSDC"));
|
||||
const contents = renderContractsModule(
|
||||
extractAbi(bankArtifact, "BankV1"),
|
||||
extractAbi(bankV2Artifact, "BankV2"),
|
||||
extractAbi(tokenArtifact, "MockUSDC")
|
||||
);
|
||||
if (check) {
|
||||
let existing;
|
||||
try { existing = await readFile(outputPath, "utf8"); } catch { throw new Error("generated contracts module is stale or missing"); }
|
||||
|
||||
Reference in New Issue
Block a user