diff --git a/src/commands/diffSnaphots.ts b/src/commands/diffSnaphots.ts index 2a06b90..56e0d94 100644 --- a/src/commands/diffSnaphots.ts +++ b/src/commands/diffSnaphots.ts @@ -1,4 +1,5 @@ import { Command } from '@commander-js/extra-typings'; +import { adiDiffReports } from '../reports/adi-diff-reports'; import { diffReports } from '../reports/diff-reports'; import { readJsonString, readJsonFile } from '../utils/json'; import fs from 'fs'; @@ -23,6 +24,24 @@ export function addCommand(program: Command) { } }); + program + .command('adi-diff-snapshots') + .description('generate a aDI snapshot diff report') + .argument('') + .argument('') + .option('-o, --out ', 'output path') + .option('--stringMode', 'expects input to be a string, not paths') + .action(async (_from, _to, options) => { + const from = options.stringMode ? readJsonString(_from) : readJsonFile(_from); + const to = options.stringMode ? readJsonString(_to) : readJsonFile(_to); + const content = await adiDiffReports(from, to); + if (options.out) { + fs.writeFileSync(options.out, content); + } else { + console.log(content); + } + }); + program .command('diff-storage') .description('generate a storage diff') diff --git a/src/reports/__snapshots__/adi-report.spec.ts.snap b/src/reports/__snapshots__/adi-report.spec.ts.snap new file mode 100644 index 0000000..024c323 --- /dev/null +++ b/src/reports/__snapshots__/adi-report.spec.ts.snap @@ -0,0 +1,30 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`adi report > should generate a well formatted adi report 1`] = ` +"## Raw diff + +\`\`\`json +{ + "forwarderAdaptersByChain": { + "1": { + "destination_3": { + "from": "0xb13712De579E1f9943502FFCf72eab6ec348cF79", + "to": "0x1562F1b2487F892BBA8Ef325aF054Fd157510a71" + }, + "origin_3": { + "from": "0xb13712De579E1f9943502FFCf72eab6ec348cF79", + "to": "0x853649f897383f89d8441346Cf26a9ed02720B02" + } + } + }, + "receiverAdaptersByChain": { + "1": { + "receiver_3": { + "from": "0xb13712De579E1f9943502FFCf72eab6ec348cF79", + "to": "0x853649f897383f89d8441346Cf26a9ed02720B02" + } + } + } +} +\`\`\`" +`; diff --git a/src/reports/adi-diff-reports.ts b/src/reports/adi-diff-reports.ts new file mode 100644 index 0000000..f680a4e --- /dev/null +++ b/src/reports/adi-diff-reports.ts @@ -0,0 +1,15 @@ +import { ADISnapshot } from './snapshot-types'; +import { diff } from './diff'; + + +export async function adiDiffReports(pre: A, post: B) { + const chainId = pre.chainId; + const diffResult = diff(pre, post); + + // create report + let content = ''; + + + content += `## Raw diff\n\n\`\`\`json\n${JSON.stringify(diff(pre, post, true), null, 2)}\n\`\`\``; + return content; +} \ No newline at end of file diff --git a/src/reports/adi-report.spec.ts b/src/reports/adi-report.spec.ts new file mode 100644 index 0000000..869a161 --- /dev/null +++ b/src/reports/adi-report.spec.ts @@ -0,0 +1,17 @@ +import { describe, it, expect } from 'vitest'; +import { readJsonFile } from '../utils/json'; +import { adiDiffReports } from './adi-diff-reports'; + +describe('adi report', () => { + it( + 'should generate a well formatted adi report', + async () => { + const from = readJsonFile('/src/reports/mocks/preTestADI.json'); + const to = readJsonFile('/src/reports/mocks/postTestADI.json'); + const content = await adiDiffReports(from, to); + console.log(content); + expect(content).toMatchSnapshot(); + }, + { timeout: 30000 } + ); +}); diff --git a/src/reports/mocks/postTestADI.json b/src/reports/mocks/postTestADI.json new file mode 100644 index 0000000..3b91ade --- /dev/null +++ b/src/reports/mocks/postTestADI.json @@ -0,0 +1,29 @@ +{ + "chainId": 137, + "forwarderAdaptersByChain": { + "1": { + "destination_0": "0xDB8953194810b1942544fA528791278D458719D5", + "destination_1": "0x2a323be63e08E08536Fc3b5d8C6f24825e68895e", + "destination_2": "0x6Abb61beb5848B476d026C4934E8a6415e2E75a8", + "destination_3": "0x1562F1b2487F892BBA8Ef325aF054Fd157510a71", + "origin_0": "0x95Fa2c817169E26956AB8795c84a225b55d7db5B", + "origin_1": "0xDA4B6024aA06f7565BBcAaD9B8bE24C3c229AAb5", + "origin_2": "0x3c25b96fF62D21E90556869272a277eE2E229747", + "origin_3": "0x853649f897383f89d8441346Cf26a9ed02720B02" + } + }, + "receiverAdaptersByChain": { + "1": { + "receiver_0": "0x95Fa2c817169E26956AB8795c84a225b55d7db5B", + "receiver_1": "0xDA4B6024aA06f7565BBcAaD9B8bE24C3c229AAb5", + "receiver_2": "0x3c25b96fF62D21E90556869272a277eE2E229747", + "receiver_3": "0x853649f897383f89d8441346Cf26a9ed02720B02" + } + }, + "receiverConfigs": { + "1": { + "requiredConfirmations": 3, + "validityTimestamp": 0 + } + } +} \ No newline at end of file diff --git a/src/reports/mocks/preTestADI.json b/src/reports/mocks/preTestADI.json new file mode 100644 index 0000000..fbe4885 --- /dev/null +++ b/src/reports/mocks/preTestADI.json @@ -0,0 +1,29 @@ +{ + "chainId": 137, + "forwarderAdaptersByChain": { + "1": { + "destination_0": "0xDB8953194810b1942544fA528791278D458719D5", + "destination_1": "0x2a323be63e08E08536Fc3b5d8C6f24825e68895e", + "destination_2": "0x6Abb61beb5848B476d026C4934E8a6415e2E75a8", + "destination_3": "0xb13712De579E1f9943502FFCf72eab6ec348cF79", + "origin_0": "0x95Fa2c817169E26956AB8795c84a225b55d7db5B", + "origin_1": "0xDA4B6024aA06f7565BBcAaD9B8bE24C3c229AAb5", + "origin_2": "0x3c25b96fF62D21E90556869272a277eE2E229747", + "origin_3": "0xb13712De579E1f9943502FFCf72eab6ec348cF79" + } + }, + "receiverAdaptersByChain": { + "1": { + "receiver_0": "0x95Fa2c817169E26956AB8795c84a225b55d7db5B", + "receiver_1": "0xDA4B6024aA06f7565BBcAaD9B8bE24C3c229AAb5", + "receiver_2": "0x3c25b96fF62D21E90556869272a277eE2E229747", + "receiver_3": "0xb13712De579E1f9943502FFCf72eab6ec348cF79" + } + }, + "receiverConfigs": { + "1": { + "requiredConfirmations": 3, + "validityTimestamp": 0 + } + } +} \ No newline at end of file diff --git a/src/reports/snapshot-types.ts b/src/reports/snapshot-types.ts index 09b1c4f..97c1071 100644 --- a/src/reports/snapshot-types.ts +++ b/src/reports/snapshot-types.ts @@ -84,6 +84,10 @@ export const CHAIN_ID = { AVALANCHE: 43114, METIS: 1088, BASE: 8453, + SCROLL: 534352, + BNB: 56, + GNOSIS: 100, + CELO: 42220, } as const; const zodChainId = z.nativeEnum(CHAIN_ID); @@ -98,4 +102,19 @@ export const aaveV3SnapshotSchema = z.object({ chainId: zodChainId, }); + +export const aDIReceiverConfigSchema = z.object({ + requiredConfirmations: z.number(), + validityTimestamp: z.number() +}); +export const aDIAdapterSchema = z.record(z.string(), z.string()); + +export const aDISnapshotSchema = z.object({ + receiverConfigs: z.record(zodChainId, aDIReceiverConfigSchema), + forwarderAdaptersByChain: z.record(zodChainId, aDIAdapterSchema), + receiverAdaptersByChain: z.record(zodChainId, aDIAdapterSchema), + chainId: zodChainId, +}); + export type AaveV3Snapshot = z.infer; +export type ADISnapshot = z.infer;