From d094f8e545f289bd9ac4ec29e4d774588ee54b99 Mon Sep 17 00:00:00 2001 From: amateima <89395931+amateima@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:42:41 +0300 Subject: [PATCH 1/9] feat: add oft transfers table (#390) Co-authored-by: Melisa Guevara --- packages/indexer-database/src/main.ts | 1 + .../migrations/1760347378412-OftTransfer.ts | 61 ++ .../migrations/1760464624377-OftTransfer.ts | 27 + .../service/OFTIndexerDataHandler.ts | 3 + .../service/OFTIndexerManager.ts | 1 + .../tests/oft-transfer-aggregator/README.md | 235 +++++ .../oft-transfer-aggregator/index.test.ts | 833 ++++++++++++++++++ pnpm-lock.yaml | 386 ++++---- 8 files changed, 1377 insertions(+), 170 deletions(-) create mode 100644 packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts create mode 100644 packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts create mode 100644 packages/indexer/src/tests/oft-transfer-aggregator/README.md create mode 100644 packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts diff --git a/packages/indexer-database/src/main.ts b/packages/indexer-database/src/main.ts index 3c90d936..6b9960b9 100644 --- a/packages/indexer-database/src/main.ts +++ b/packages/indexer-database/src/main.ts @@ -72,6 +72,7 @@ export const createDataSource = (config: DatabaseConfig): DataSource => { // OFT entities.OFTSent, entities.OFTReceived, + entities.OftTransfer, ], migrationsTableName: "_migrations", migrations: ["migrations/*.ts"], diff --git a/packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts b/packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts new file mode 100644 index 00000000..fa33b77b --- /dev/null +++ b/packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts @@ -0,0 +1,61 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class OftTransfer1760347378412 implements MigrationInterface { + name = "OftTransfer1760347378412"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TYPE "public"."oft_transfer_status_enum" AS ENUM( + 'unfilled', + 'filled' + ) + `); + await queryRunner.query(` + CREATE TABLE "oft_transfer" ( + "id" SERIAL NOT NULL, + "guid" character varying NOT NULL, + "originChainId" bigint NOT NULL, + "destinationChainId" bigint NOT NULL, + "originTokenAddress" character varying, + "destinationTokenAddress" character varying, + "originTokenAmount" numeric, + "destinationTokenAmount" numeric, + "originTxnRef" character varying, + "destinationTxnRef" character varying, + "oftSentEventId" integer, + "oftReceivedEventId" integer, + "status" "public"."oft_transfer_status_enum" NOT NULL DEFAULT 'unfilled', + "bridgeFeeUsd" numeric, + "originGasFee" numeric, + "originGasFeeUsd" numeric, + "originGasTokenPriceUsd" numeric, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "REL_a55d2ab4103b4a13e824848b7d" UNIQUE ("oftSentEventId"), + CONSTRAINT "REL_85a1fa5348947197b31809477c" UNIQUE ("oftReceivedEventId"), + CONSTRAINT "PK_c986f173fc2315410daf73cfdde" PRIMARY KEY ("id") + ) + `); + await queryRunner.query(` + ALTER TABLE "oft_transfer" + ADD CONSTRAINT "FK_a55d2ab4103b4a13e824848b7d4" + FOREIGN KEY ("oftSentEventId") REFERENCES "evm"."oft_sent"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + await queryRunner.query(` + ALTER TABLE "oft_transfer" + ADD CONSTRAINT "FK_85a1fa5348947197b31809477c1" + FOREIGN KEY ("oftReceivedEventId") REFERENCES "evm"."oft_received"("id") ON DELETE NO ACTION ON UPDATE NO ACTION + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "oft_transfer" DROP CONSTRAINT "FK_85a1fa5348947197b31809477c1"`, + ); + await queryRunner.query( + `ALTER TABLE "oft_transfer" DROP CONSTRAINT "FK_a55d2ab4103b4a13e824848b7d4"`, + ); + await queryRunner.query(`DROP TABLE "oft_transfer"`); + await queryRunner.query(`DROP TYPE "public"."oft_transfer_status_enum"`); + } +} diff --git a/packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts b/packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts new file mode 100644 index 00000000..b4cbb282 --- /dev/null +++ b/packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts @@ -0,0 +1,27 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class OftTransfer1760464624377 implements MigrationInterface { + name = "OftTransfer1760464624377"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "oft_transfer" ADD CONSTRAINT "UQ_85fc3827b7381fa02ef4e01f008" UNIQUE ("guid")`, + ); + await queryRunner.query( + `CREATE INDEX "IX_oft_transfer_status" ON "oft_transfer" ("status") `, + ); + await queryRunner.query( + `CREATE INDEX "IX_oft_transfer_origin_txn_ref" ON "oft_transfer" ("originTxnRef") `, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `DROP INDEX "public"."IX_oft_transfer_origin_txn_ref"`, + ); + await queryRunner.query(`DROP INDEX "public"."IX_oft_transfer_status"`); + await queryRunner.query( + `ALTER TABLE "oft_transfer" DROP CONSTRAINT "UQ_85fc3827b7381fa02ef4e01f008"`, + ); + } +} diff --git a/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts b/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts index 72ddc31a..18fcda60 100644 --- a/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts +++ b/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts @@ -28,14 +28,17 @@ const SWAP_API_CALLDATA_MARKER = "73c0de"; export class OFTIndexerDataHandler implements IndexerDataHandler { private isInitialized: boolean; + private oftTransferAggregator: OftTransferAggregator; constructor( private logger: Logger, private chainId: number, private provider: across.providers.RetryProvider, private oftRepository: OftRepository, + private postgres: DataSource, ) { this.isInitialized = false; + this.oftTransferAggregator = new OftTransferAggregator(postgres); } private initialize() {} diff --git a/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts b/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts index 17ebb6e1..e5c060b7 100644 --- a/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts +++ b/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts @@ -65,6 +65,7 @@ export class OFTIndexerManager { Number(chainId), provider, this.oftRepository, + this.postgres, ); const indexer = new EvmIndexer( { diff --git a/packages/indexer/src/tests/oft-transfer-aggregator/README.md b/packages/indexer/src/tests/oft-transfer-aggregator/README.md new file mode 100644 index 00000000..be8070b6 --- /dev/null +++ b/packages/indexer/src/tests/oft-transfer-aggregator/README.md @@ -0,0 +1,235 @@ +# OftTransferAggregator End-to-End Test Plan + +## Overview + +This document outlines the test plan for the `OftTransferAggregator` class, which is responsible for aggregating OFT (Omnichain Fungible Token) events into unified OFT transfers. + +## Test Cases + +### 1. New OFTSent Event Processing + +#### 1.1 Single OFTSent Event → New OFT Transfer Created + +- **Given**: An empty database +- **When**: A new OFTSent event is added +- **Then**: + - A new OftTransfer row is created + - `guid` matches the sent event's GUID + - `oftSentEventId` is set to the sent event's ID + - `status` is `"unfilled"` + +#### 1.2 Multiple OFTSent Events with Different GUIDs + +- **Given**: An empty database +- **When**: Multiple OFTSent events with different GUIDs are added +- **Then**: + - Each event creates a separate OftTransfer row (3 transfers for 3 events) + - All rows have `status` = `"unfilled"` + - All rows have `oftSentEventId` set + +#### 1.3 OFTSent Event with Existing GUID (Different Event ID) + +- **Given**: An existing OftTransfer with a specific GUID linked to OFTSent event A +- **When**: A new OFTSent event B with the same GUID but different event ID is added +- **Then**: + - Only one OftTransfer row exists (no duplicates) + - `guid` remains the same + - `oftSentEventId` is updated to event B's ID + +#### 1.4 OFTSent Event with Existing GUID (Same Event ID) + +- **Given**: An existing OftTransfer linked to OFTSent event A +- **When**: The same OFTSent event A is processed again +- **Then**: + - No update occurs (no-op) + - Database remains unchanged + +--- + +### 2. New OFTReceived Event Processing + +#### 2.1 Single OFTReceived Event → New OFT Transfer Created + +- **Given**: An empty database +- **When**: A new OFTReceived event is added +- **Then**: + - A new OftTransfer row is created + - `guid` matches the received event's GUID + - `oftReceivedEventId` is set to the received event's ID + - `status` is `"filled"` + +#### 2.2 Multiple OFTReceived Events with Different GUIDs + +- **Given**: An empty database +- **When**: Multiple OFTReceived events with different GUIDs are added +- **Then**: + - Each event creates a separate OftTransfer row (3 transfers for 3 events) + - All rows have `status` = `"filled"` + - All rows have `oftReceivedEventId` set + +#### 2.3 OFTReceived Event with Existing GUID (Different Event ID) + +- **Given**: An existing OftTransfer with a specific GUID linked to OFTReceived event A +- **When**: A new OFTReceived event B with the same GUID but different event ID is added +- **Then**: + - Only one OftTransfer row exists (no duplicates) + - `guid` remains the same + - `oftReceivedEventId` is updated to event B's ID + +#### 2.4 OFTReceived Event with Existing GUID (Same Event ID) + +- **Given**: An existing OftTransfer linked to OFTReceived event A +- **When**: The same OFTReceived event A is processed again +- **Then**: + - No update occurs (no-op) + - Database remains unchanged + +--- + +### 3. Matching Sent and Received Events + +#### 3.1 OFTSent First, Then OFTReceived (Complete Transfer) + +- **Given**: An OftTransfer exists with only OFTSent event (status = `"unfilled"`) +- **When**: An OFTReceived event with the same GUID is added +- **Then**: + - Only one OftTransfer row exists (no duplicates) + - `guid` matches both events + - Both `oftSentEventId` and `oftReceivedEventId` are set + - `status` is updated to `"filled"` + +#### 3.2 OFTReceived First, Then OFTSent (Complete Transfer) + +- **Given**: An OftTransfer exists with only OFTReceived event (status = `"filled"`) +- **When**: An OFTSent event with the same GUID is added +- **Then**: + - Only one OftTransfer row exists (no duplicates) + - `guid` matches both events + - Both `oftSentEventId` and `oftReceivedEventId` are set + - `status` remains `"filled"` + +#### 3.3 Both Events Processed Simultaneously + +- **Given**: An empty database +- **When**: Both OFTSent and OFTReceived events with the same GUID are added in the same call +- **Then**: + - Only one OftTransfer row exists (no duplicates) + - `guid` matches both events + - Both `oftSentEventId` and `oftReceivedEventId` are set + - `status` is `"filled"` + +--- + +### 4. Deleted/Re-Organized OFTSent Events + +#### 4.1 Deleted OFTSent Event (Transfer Has No OFTReceived) + +- **Given**: An OftTransfer with only OFTSent event (no received event) +- **When**: The OFTSent event is marked as deleted (deletedAt set) and processed +- **Then**: + - The entire OftTransfer row is deleted + - No transfers remain in database + +#### 4.2 Deleted OFTSent Event (Transfer Has OFTReceived) + +- **Given**: An OftTransfer with both OFTSent and OFTReceived events (status = `"filled"`) +- **When**: The OFTSent event is marked as deleted (deletedAt set) and processed +- **Then**: + - The OftTransfer row is updated (not deleted) + - Only one transfer remains + - `guid` remains the same + - `oftSentEventId` is set to null + - `oftReceivedEventId` remains set to the received event's ID + - `originTxnRef` is set to null + - `status` remains `"filled"` + +#### 4.3 Multiple Deleted OFTSent Events + +- **Given**: Multiple OftTransfers with only OFTSent events (3 transfers) +- **When**: Multiple OFTSent events are marked as deleted and processed +- **Then**: + - All transfers are deleted + - No transfers remain in database + +--- + +### 5. Deleted/Re-Organized OFTReceived Events + +#### 5.1 Deleted OFTReceived Event (Transfer Has No OFTSent) + +- **Given**: An OftTransfer with only OFTReceived event (no sent event) +- **When**: The OFTReceived event is marked as deleted (deletedAt set) and processed +- **Then**: + - The entire OftTransfer row is deleted + - No transfers remain in database + +#### 5.2 Deleted OFTReceived Event (Transfer Has OFTSent) + +- **Given**: An OftTransfer with both OFTSent and OFTReceived events (status = `"filled"`) +- **When**: The OFTReceived event is marked as deleted (deletedAt set) and processed +- **Then**: + - The OftTransfer row is updated (not deleted) + - Only one transfer remains + - `guid` remains the same + - `oftSentEventId` remains set to the sent event's ID + - `oftReceivedEventId` is set to null + - `destinationTxnRef` is set to null + - `status` is updated to `"unfilled"` + +#### 5.3 Multiple Deleted OFTReceived Events + +- **Given**: Multiple OftTransfers with only OFTReceived events (3 transfers) +- **When**: Multiple OFTReceived events are marked as deleted and processed +- **Then**: + - All transfers are deleted + - No transfers remain in database + +--- + +### 6. Complex Re-Organization Scenarios + +#### 6.1 Sequential Re-Org: Delete Then Re-Add + +- **Given**: A complete OftTransfer (both sent and received events) +- **When**: + 1. OFTSent event is marked as deleted and processed + 2. A new OFTSent event with the same GUID is added +- **Then**: + - Only one OftTransfer row exists throughout + - After re-add: `oftSentEventId` is set to the new event's ID + - Both `oftSentEventId` and `oftReceivedEventId` are set + - `status` is `"filled"` + +#### 6.2 Both Events Deleted Sequentially + +- **Given**: A complete OftTransfer (both sent and received events) +- **When**: + 1. OFTSent event is marked as deleted and processed + 2. OFTReceived event is marked as deleted and processed +- **Then**: + - After first deletion: One transfer exists (with only received event) + - After second deletion: Transfer is completely deleted + - No transfers remain in database + +#### 6.3 Both Events Deleted Simultaneously + +- **Given**: A complete OftTransfer (both sent and received events) +- **When**: Both OFTSent and OFTReceived events are marked as deleted and processed in the same call +- **Then**: + - The OftTransfer row is deleted + - No transfers remain in database + +--- + +### 7. Edge Cases and Error Handling + +#### 7.1 Empty Input Arrays + +- **Given**: Database in any state +- **When**: `processDatabaseEvents()` is called with all empty arrays +- **Then**: + - No errors occur + - Database state remains unchanged + - Method completes successfully + +--- diff --git a/packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts b/packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts new file mode 100644 index 00000000..f9a914b3 --- /dev/null +++ b/packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts @@ -0,0 +1,833 @@ +import { expect } from "chai"; +import { CHAIN_IDs } from "@across-protocol/constants"; +import { + createDataSource, + DataSource, + entities, + fixtures, +} from "@repo/indexer-database"; +import { parsePostgresConfig } from "../../parseEnv"; +import { OftTransferAggregator } from "../../data-indexing/service/OftTransferAggregator"; +import { getOftChainConfiguration } from "../../data-indexing/adapter/oft/service"; + +describe("OftTransferAggregator", () => { + // DataSource + let dataSource: DataSource; + + // Fixtures + let oftSentFixture: fixtures.OftSentFixture; + let oftReceivedFixture: fixtures.OftReceivedFixture; + let oftTransferFixture: fixtures.OftTransferFixture; + + // Aggregator + let oftTransferAggregator: OftTransferAggregator; + + // Default OFTReceived configuration + const defaultOftReceivedConfig = { + token: getOftChainConfiguration(CHAIN_IDs.MAINNET).tokens[0]!.address, + chainId: CHAIN_IDs.MAINNET.toString(), + srcEid: getOftChainConfiguration(CHAIN_IDs.POLYGON).endpointId, + }; + + before(async () => { + // Connect to database + const databaseConfig = parsePostgresConfig(process.env); + dataSource = await createDataSource(databaseConfig).initialize(); + + // Instantiate fixtures + oftSentFixture = new fixtures.OftSentFixture(dataSource); + oftReceivedFixture = new fixtures.OftReceivedFixture(dataSource); + oftTransferFixture = new fixtures.OftTransferFixture(dataSource); + + // Instantiate aggregator + oftTransferAggregator = new OftTransferAggregator(dataSource); + }); + + beforeEach(async () => { + await oftTransferFixture.deleteAllOftTransfers(); + await oftSentFixture.deleteAllOftSentEvents(); + await oftReceivedFixture.deleteAllOftReceivedEvents(); + }); + + afterEach(async () => { + await oftTransferFixture.deleteAllOftTransfers(); + await oftSentFixture.deleteAllOftSentEvents(); + await oftReceivedFixture.deleteAllOftReceivedEvents(); + }); + + after(async () => {}); + + // Test 1.1: Single OFTSent Event → New OFT Transfer Created + // Given an empty database, when new OFTSent event is added, + // then a new OftTransfer row should be created with the sent event's data + it("1.1. should create new OFT transfer when new OFTSent event is added", async () => { + const [oftSentEvent] = await oftSentFixture.insertOftSentEvents(); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(oftSentEvent!.guid); + expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + expect(oftTransfers[0]!.status).to.equal("unfilled"); + }); + + // Test 1.2: Multiple OFTSent Events with Different GUIDs + // When multiple OFTSent events with different GUIDs are processed, + // then each should create a separate OftTransfer row + it("1.2. should create separate OFT transfers when multiple OFTSent events with different GUIDs are added", async () => { + const oftSentEvents = await oftSentFixture.insertOftSentEvents([ + {}, + {}, + {}, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + oftSentEvents, + [], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(3); + oftTransfers.forEach((transfer) => { + expect(transfer.status).to.equal("unfilled"); + expect(transfer.oftSentEventId).to.not.be.null; + }); + }); + + // Test 1.3: OFTSent Event with Existing GUID (Different Event ID) + // When a new OFTSent event with same GUID but different event ID is added, + // then the existing OftTransfer should be updated + it("1.3. should update existing OFT transfer when OFTSent event with same GUID but different event ID is added", async () => { + const sharedGuid = "0x123abc"; + const [firstEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [firstEvent!], + [], + 1, + ); + + const [secondEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [secondEvent!], + [], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftSentEventId).to.equal(secondEvent!.id); + }); + + // Test 1.4: OFTSent Event with Existing GUID (Same Event ID) + // When the same OFTSent event is processed again, + // then no update should occur (no-op) + it("1.4. should not update OFT transfer when same OFTSent event is processed again", async () => { + const [oftSentEvent] = await oftSentFixture.insertOftSentEvents(); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [], + 1, + ); + let transfersAfter = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(transfersAfter[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [], + 1, + ); + transfersAfter = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(transfersAfter[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + }); + + // Test 2.1: Single OFTReceived Event → New OFT Transfer Created + // When a new OFTReceived event is added, + // then a new OftTransfer row should be created with status Filled + it("2.1. should create new OftTransfer when new OFTReceived event is added", async () => { + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [{ ...defaultOftReceivedConfig }], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [oftReceivedEvent!], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(oftReceivedEvent!.guid); + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); + expect(oftTransfers[0]!.status).to.equal("filled"); + }); + + // Test 2.2: Multiple OFTReceived Events with Different GUIDs + // When multiple OFTReceived events with different GUIDs are processed, + // then each should create a separate OftTransfer row with status Filled + it("2.2. should create separate OftTransfers when multiple OFTReceived events with different GUIDs are added", async () => { + const oftReceivedEvents = await oftReceivedFixture.insertOftReceivedEvents([ + { ...defaultOftReceivedConfig }, + { ...defaultOftReceivedConfig }, + { ...defaultOftReceivedConfig }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + oftReceivedEvents, + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(3); + oftTransfers.forEach((transfer) => { + expect(transfer.status).to.equal("filled"); + expect(transfer.oftReceivedEventId).to.not.be.null; + }); + }); + + // Test 2.3: OFTReceived Event with Existing GUID (Different Event ID) + // When a new OFTReceived event with same GUID but different event ID is added, + // then the existing OftTransfer should be updated + it("2.3. should update existing OFT transfer when OFTReceived event with same GUID but different event ID is added", async () => { + const sharedGuid = "0xabc123"; + const [firstEvent] = await oftReceivedFixture.insertOftReceivedEvents([ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [firstEvent!], + 1, + ); + + const [secondEvent] = await oftReceivedFixture.insertOftReceivedEvents([ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [secondEvent!], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(secondEvent!.id); + }); + + // Test 2.4: OFTReceived Event with Existing GUID (Same Event ID) + // When the same OFTReceived event is processed again, + // then no update should occur (no-op) + it("2.4. should not update OFT transfer when same OFTReceived event is processed again", async () => { + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [{ ...defaultOftReceivedConfig }], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [oftReceivedEvent!], + 1, + ); + let transfersAfter = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(transfersAfter[0]!.oftReceivedEventId).to.equal( + oftReceivedEvent!.id, + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [oftReceivedEvent!], + 1, + ); + transfersAfter = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(transfersAfter[0]!.oftReceivedEventId).to.equal( + oftReceivedEvent!.id, + ); + }); + + // Test 3.1: OFTSent First, Then OFTReceived (Complete Transfer) + // When OFTReceived event matches existing OFTSent event, + // then the OftTransfer should be updated with received data and status changed to Filled + it("3.1. should update OFT transfer to Filled when OFTReceived event matches existing OFTSent event", async () => { + const sharedGuid = "0xmatching123"; + const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [], + 1, + ); + + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [oftReceivedEvent!], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); + expect(oftTransfers[0]!.status).to.equal("filled"); + }); + + // Test 3.2: OFTReceived First, Then OFTSent (Complete Transfer) + // When OFTSent event matches existing OFTReceived event, + // then the OftTransfer should be updated with sent data and status remains Filled + it("3.2. should update OFT transfer with sent data when OFTSent event matches existing OFTReceived event", async () => { + const sharedGuid = "0xmatching456"; + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [oftReceivedEvent!], + 1, + ); + + const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); + expect(oftTransfers[0]!.status).to.equal("filled"); + }); + + // Test 3.3: Both Events Processed Simultaneously + // When both OFTSent and OFTReceived events with same GUID are processed together, + // then a single complete OftTransfer should be created with status Filled + it("3.3. should create single complete OFT transfer when both OFTSent and OFTReceived events are processed simultaneously", async () => { + const sharedGuid = "0xsimultaneous"; + const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [oftReceivedEvent!], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); + expect(oftTransfers[0]!.status).to.equal("filled"); + }); + + // Test 4.1: Deleted OFTSent Event (Transfer Has No OFTReceived) + // When an OFTSent event is deleted and transfer has no OFTReceived event, + // then the entire OftTransfer row should be deleted + it("4.1. should delete OFT transfer when OFTSent event is deleted and transfer has no OFTReceived event", async () => { + let [oftSentEvent] = await oftSentFixture.insertOftSentEvents(); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [], + 1, + ); + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + oftSentEvent!.deletedAt = new Date(); + oftSentEvent = await dataSource + .getRepository(entities.OFTSent) + .save(oftSentEvent!); + + await oftTransferAggregator.processDatabaseEvents( + [oftSentEvent!], + [], + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(0); + }); + + // Test 4.2: Deleted OFTSent Event (Transfer Has OFTReceived) + // When an OFTSent event is deleted but transfer has OFTReceived event, + // then the OftTransfer should be updated with sent fields nulled + it("4.2. should update OFT transfer when OFTSent event is deleted and transfer has OFTReceived event", async () => { + const sharedGuid = "0xdeleted123"; + let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [oftReceivedEvent!], + 1, + ); + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.status).to.equal("filled"); + + oftSentEvent!.deletedAt = new Date(); + oftSentEvent = await dataSource + .getRepository(entities.OFTSent) + .save(oftSentEvent!); + await oftTransferAggregator.processDatabaseEvents( + [oftSentEvent!], + [], + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftSentEventId).to.be.null; + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); + expect(oftTransfers[0]!.originTxnRef).to.be.null; + expect(oftTransfers[0]!.status).to.equal("filled"); + }); + + // Test 4.3: Multiple Deleted OFTSent Events + // When multiple OFTSent events are deleted, + // then each transfer should be processed correctly + it("4.3. should process multiple deleted OFTSent events correctly", async () => { + let oftSentEvents = await oftSentFixture.insertOftSentEvents([{}, {}, {}]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + oftSentEvents, + [], + 1, + ); + + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(3); + + oftSentEvents = await Promise.all( + oftSentEvents.map(async (event) => { + event!.deletedAt = new Date(); + return await dataSource.getRepository(entities.OFTSent).save(event!); + }), + ); + + await oftTransferAggregator.processDatabaseEvents( + oftSentEvents, + [], + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(0); + }); + + // Test 5.1: Deleted OFTReceived Event (Transfer Has No OFTSent) + // When an OFTReceived event is deleted and transfer has no OFTSent event, + // then the entire OftTransfer row should be deleted + it("5.1. should delete OFT transfer when OFTReceived event is deleted and transfer has no OFTSent event", async () => { + let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ + { ...defaultOftReceivedConfig }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + [oftReceivedEvent!], + 1, + ); + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + + oftReceivedEvent!.deletedAt = new Date(); + oftReceivedEvent = await dataSource + .getRepository(entities.OFTReceived) + .save(oftReceivedEvent!); + await oftTransferAggregator.processDatabaseEvents( + [], + [oftReceivedEvent!], + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(0); + }); + + // Test 5.2: Deleted OFTReceived Event (Transfer Has OFTSent) + // When an OFTReceived event is deleted but transfer has OFTSent event, + // then the OftTransfer should be updated with received fields nulled and status changed to Unfilled + it("5.2. should update OFT transfer when OFTReceived event is deleted and transfer has OFTSent event", async () => { + const sharedGuid = "0xdeleted456"; + const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [oftReceivedEvent!], + 1, + ); + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.status).to.equal("filled"); + + oftReceivedEvent!.deletedAt = new Date(); + oftReceivedEvent = await dataSource + .getRepository(entities.OFTReceived) + .save(oftReceivedEvent!); + await oftTransferAggregator.processDatabaseEvents( + [], + [oftReceivedEvent!], + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.guid).to.equal(sharedGuid); + expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); + expect(oftTransfers[0]!.oftReceivedEventId).to.be.null; + expect(oftTransfers[0]!.destinationTxnRef).to.be.null; + expect(oftTransfers[0]!.status).to.equal("unfilled"); + }); + + // Test 5.3: Multiple Deleted OFTReceived Events + // When multiple OFTReceived events are deleted, + // then each transfer should be processed correctly + it("5.3. should process multiple deleted OFTReceived events correctly", async () => { + let oftReceivedEvents = await oftReceivedFixture.insertOftReceivedEvents([ + { ...defaultOftReceivedConfig }, + { ...defaultOftReceivedConfig }, + { ...defaultOftReceivedConfig }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [], + oftReceivedEvents, + 1, + ); + + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(3); + + oftReceivedEvents = await Promise.all( + oftReceivedEvents.map(async (event) => { + event!.deletedAt = new Date(); + return await dataSource + .getRepository(entities.OFTReceived) + .save(event!); + }), + ); + + await oftTransferAggregator.processDatabaseEvents( + [], + oftReceivedEvents, + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(0); + }); + + // Test 6.1: Sequential Re-Org: Delete Then Re-Add + // When an OFTSent event is deleted then re-added with same GUID, + // then the transfer should be updated accordingly through both operations + it("6.1. should handle sequential re-org when OFTSent event is deleted then re-added", async () => { + const sharedGuid = "0xreorg123"; + let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( + [ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ], + ); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [oftReceivedEvent!], + 1, + ); + + oftSentEvent!.deletedAt = new Date(); + oftSentEvent = await dataSource + .getRepository(entities.OFTSent) + .save(oftSentEvent!); + await oftTransferAggregator.processDatabaseEvents( + [oftSentEvent!], + [], + [], + [], + 1, + ); + + const [newOftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [newOftSentEvent!], + [], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + expect(oftTransfers[0]!.oftSentEventId).to.equal(newOftSentEvent!.id); + expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); + expect(oftTransfers[0]!.status).to.equal("filled"); + }); + + // Test 6.2: Both Events Deleted Sequentially + // When both OFTSent and OFTReceived events are deleted sequentially, + // then the transfer should be completely deleted + it("6.2. should delete transfer when both OFTSent and OFTReceived events are deleted sequentially", async () => { + const sharedGuid = "0xbothdeleted"; + let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [oftReceivedEvent!], + 1, + ); + + oftSentEvent!.deletedAt = new Date(); + oftSentEvent = await dataSource + .getRepository(entities.OFTSent) + .save(oftSentEvent!); + await oftTransferAggregator.processDatabaseEvents( + [oftSentEvent!], + [], + [], + [], + 1, + ); + + let oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(1); + + oftReceivedEvent!.deletedAt = new Date(); + oftReceivedEvent = await dataSource + .getRepository(entities.OFTReceived) + .save(oftReceivedEvent!); + await oftTransferAggregator.processDatabaseEvents( + [], + [oftReceivedEvent!], + [], + [], + 1, + ); + + oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); + expect(oftTransfers).to.have.length(0); + }); + + // Test 6.3: Both Events Deleted Simultaneously + // When both OFTSent and OFTReceived events are deleted in parallel, + // then the transfer should be completely deleted + it("6.3. should delete transfer when both OFTSent and OFTReceived events are deleted simultaneously", async () => { + const sharedGuid = "0xsimuldelete"; + let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ + { guid: sharedGuid }, + ]); + let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ + { + ...defaultOftReceivedConfig, + guid: sharedGuid, + }, + ]); + await oftTransferAggregator.processDatabaseEvents( + [], + [], + [oftSentEvent!], + [oftReceivedEvent!], + 1, + ); + + oftSentEvent!.deletedAt = new Date(); + oftSentEvent = await dataSource + .getRepository(entities.OFTSent) + .save(oftSentEvent!); + oftReceivedEvent!.deletedAt = new Date(); + oftReceivedEvent = await dataSource + .getRepository(entities.OFTReceived) + .save(oftReceivedEvent!); + + await oftTransferAggregator.processDatabaseEvents( + [oftSentEvent!], + [oftReceivedEvent!], + [], + [], + 1, + ); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(0); + }); + + // Test 7.1: Empty Input Arrays + // When processDatabaseEvents is called with all empty arrays, + // then no errors should occur and database should remain unchanged + it("7.1. should handle empty input arrays without errors", async () => { + await oftTransferAggregator.processDatabaseEvents([], [], [], [], 1); + + const oftTransfers = await dataSource + .getRepository(entities.OftTransfer) + .find(); + expect(oftTransfers).to.have.length(0); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ccaace47..85a904f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -252,8 +252,8 @@ importers: packages/indexer-api: dependencies: '@across-protocol/sdk': - specifier: ^4.3.75 - version: 4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + specifier: ^4.3.67 + version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@repo/error-handling': specifier: workspace:* version: link:../error-handling @@ -349,8 +349,8 @@ importers: packages/indexer-database: dependencies: '@across-protocol/sdk': - specifier: ^4.3.75 - version: 4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + specifier: ^4.3.67 + version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -9042,64 +9042,70 @@ snapshots: - typechain - utf-8-validate - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@openzeppelin/contracts': 4.1.0 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - bufferutil - - debug - - encoding - ethers - - hardhat - - supports-color - - ts-generator - - typechain - utf-8-validate - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@openzeppelin/contracts': 4.1.0 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@across-protocol/contracts@4.1.11(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: + '@across-protocol/constants': 3.1.83 + '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) + '@defi-wonderland/smock': 2.4.0(@ethersproject/abi@5.8.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@openzeppelin/contracts': 4.1.0 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@openzeppelin/contracts': 4.9.6 + '@openzeppelin/contracts-upgradeable': 4.9.6 + '@openzeppelin/foundry-upgrades': 0.4.0(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1) + '@safe-global/protocol-kit': 6.1.1(bufferutil@4.0.8)(typescript@5.5.4)(utf-8-validate@5.0.10) + '@scroll-tech/contracts': 0.1.0 + '@solana-developers/helpers': 2.8.1(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) + '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) + '@types/yargs': 17.0.33 + '@uma/common': 2.37.3(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) + '@uma/contracts-node': 0.4.26 + '@uma/core': 2.61.0(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) + axios: 1.12.2 + bs58: 6.0.0 + buffer-layout: 1.2.2 + prettier-plugin-rust: 0.1.9 + yargs: 17.7.2 + zksync-web3: 0.14.4(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) transitivePeerDependencies: - '@babel/core' - '@codechecks/client' + - '@ethersproject/abi' - '@ethersproject/hardware-wallets' + - '@nomiclabs/hardhat-ethers' + - '@openzeppelin/defender-deploy-client-cli' + - '@openzeppelin/upgrades-core' - bufferutil + - c-kzg - debug - encoding - ethers + - fastestsmallesttextencoderdecoder - hardhat - supports-color - ts-generator - typechain + - typescript - utf-8-validate + - ws + - zod - '@across-protocol/contracts@4.1.11(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@across-protocol/contracts@4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/constants': 3.1.83 '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) @@ -9114,16 +9120,16 @@ snapshots: '@safe-global/protocol-kit': 6.1.1(bufferutil@4.0.8)(typescript@5.5.4)(utf-8-validate@5.0.10) '@scroll-tech/contracts': 0.1.0 '@solana-developers/helpers': 2.8.1(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana-program/token': 0.5.1(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana/kit': 2.1.0(typescript@5.5.4) '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/yargs': 17.0.33 - '@uma/common': 2.37.3(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@uma/contracts-node': 0.4.26 - '@uma/core': 2.61.0(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) - axios: 1.12.2 + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + axios: 1.8.2 bs58: 6.0.0 buffer-layout: 1.2.2 prettier-plugin-rust: 0.1.9 @@ -9150,11 +9156,10 @@ snapshots: - typescript - utf-8-validate - ws - - zod - '@across-protocol/contracts@4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/contracts@4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: - '@across-protocol/constants': 3.1.83 + '@across-protocol/constants': 3.1.79 '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@defi-wonderland/smock': 2.4.0(@ethersproject/abi@5.8.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) @@ -9164,16 +9169,15 @@ snapshots: '@openzeppelin/contracts': 4.9.6 '@openzeppelin/contracts-upgradeable': 4.9.6 '@openzeppelin/foundry-upgrades': 0.4.0(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1) - '@safe-global/protocol-kit': 6.1.1(bufferutil@4.0.8)(typescript@5.5.4)(utf-8-validate@5.0.10) '@scroll-tech/contracts': 0.1.0 '@solana-developers/helpers': 2.8.1(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.5.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))) + '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/yargs': 17.0.33 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@uma/contracts-node': 0.4.26 '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) axios: 1.12.2 @@ -9259,18 +9263,18 @@ snapshots: - ws - zod - '@across-protocol/sdk@4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/sdk@4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - '@across-protocol/constants': 3.1.83 - '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/constants': 3.1.79 + '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 '@pinata/sdk': 2.1.0 - '@solana-program/system': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/system': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))) + '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(typescript@5.5.4)) + '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/mocha': 10.0.7 '@types/node': 24.3.1 @@ -9313,18 +9317,18 @@ snapshots: - ws - zod - '@across-protocol/sdk@4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/sdk@4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - '@across-protocol/constants': 3.1.83 - '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/constants': 3.1.79 + '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 '@pinata/sdk': 2.1.0 - '@solana-program/system': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/system': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(typescript@5.5.4))(@solana/sysvars@2.1.0(typescript@5.5.4)) + '@solana/kit': 2.1.0(typescript@5.5.4) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/mocha': 10.0.7 '@types/node': 24.3.1 @@ -11900,19 +11904,53 @@ snapshots: dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/address-lookup-table@0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + + '@solana-program/address-lookup-table@0.7.0(@solana/kit@2.1.0(typescript@5.5.4))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana-program/system@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/system@0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + + '@solana-program/system@0.7.0(@solana/kit@2.1.0(typescript@5.5.4))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana-program/token-2022@0.4.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana-program/token-2022@0.4.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(typescript@5.5.4))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + + '@solana-program/token-2022@0.4.1(@solana/kit@2.1.0(typescript@5.5.4))(@solana/sysvars@2.1.0(typescript@5.5.4))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana-program/token@0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/token@0.5.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + + '@solana-program/token@0.5.1(@solana/kit@2.1.0(typescript@5.5.4))': + dependencies: + '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana/accounts@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) @@ -12091,6 +12129,56 @@ snapshots: - fastestsmallesttextencoderdecoder - ws + '@solana/kit@2.1.0(typescript@5.5.4)': + dependencies: + '@solana/accounts': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/codecs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/errors': 2.1.0(typescript@5.5.4) + '@solana/functional': 2.1.0(typescript@5.5.4) + '@solana/instructions': 2.1.0(typescript@5.5.4) + '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/programs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc-parsed-types': 2.1.0(typescript@5.5.4) + '@solana/rpc-spec-types': 2.1.0(typescript@5.5.4) + '@solana/rpc-subscriptions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/signers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transaction-confirmation': 2.1.0(typescript@5.5.4) + '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + typescript: 5.5.4 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/codecs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/errors': 2.1.0(typescript@5.5.4) + '@solana/functional': 2.1.0(typescript@5.5.4) + '@solana/instructions': 2.1.0(typescript@5.5.4) + '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/programs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc-parsed-types': 2.1.0(typescript@5.5.4) + '@solana/rpc-spec-types': 2.1.0(typescript@5.5.4) + '@solana/rpc-subscriptions': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/signers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transaction-confirmation': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + typescript: 5.5.4 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.5.4) @@ -12169,6 +12257,15 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder + '@solana/rpc-subscriptions-channel-websocket@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.1.0(typescript@5.5.4) + '@solana/functional': 2.1.0(typescript@5.5.4) + '@solana/rpc-subscriptions-spec': 2.1.0(typescript@5.5.4) + '@solana/subscribable': 2.1.0(typescript@5.5.4) + typescript: 5.5.4 + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/rpc-subscriptions-channel-websocket@2.1.0(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.1.0(typescript@5.5.4) @@ -12204,6 +12301,24 @@ snapshots: - fastestsmallesttextencoderdecoder - ws + '@solana/rpc-subscriptions@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.1.0(typescript@5.5.4) + '@solana/fast-stable-stringify': 2.1.0(typescript@5.5.4) + '@solana/functional': 2.1.0(typescript@5.5.4) + '@solana/promises': 2.1.0(typescript@5.5.4) + '@solana/rpc-spec-types': 2.1.0(typescript@5.5.4) + '@solana/rpc-subscriptions-api': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc-subscriptions-channel-websocket': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 2.1.0(typescript@5.5.4) + '@solana/rpc-transformers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/subscribable': 2.1.0(typescript@5.5.4) + typescript: 5.5.4 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + '@solana/rpc-transformers@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/errors': 2.1.0(typescript@5.5.4) @@ -12324,6 +12439,40 @@ snapshots: - fastestsmallesttextencoderdecoder - ws + '@solana/transaction-confirmation@2.1.0(typescript@5.5.4)': + dependencies: + '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/codecs-strings': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/errors': 2.1.0(typescript@5.5.4) + '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/promises': 2.1.0(typescript@5.5.4) + '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc-subscriptions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + typescript: 5.5.4 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/transaction-confirmation@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/codecs-strings': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/errors': 2.1.0(typescript@5.5.4) + '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/promises': 2.1.0(typescript@5.5.4) + '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/rpc-subscriptions': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) + typescript: 5.5.4 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + '@solana/transaction-messages@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) @@ -13076,7 +13225,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13127,7 +13276,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13176,57 +13325,6 @@ snapshots: - typechain - utf-8-validate - '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@ethersproject/address': 5.8.0 - '@ethersproject/bignumber': 5.8.0 - '@ethersproject/bytes': 5.8.0 - '@ethersproject/constants': 5.8.0 - '@google-cloud/kms': 3.8.0(encoding@0.1.13) - '@google-cloud/storage': 6.12.0(encoding@0.1.13) - '@nomicfoundation/hardhat-verify': 1.1.1(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) - '@nomiclabs/hardhat-web3': 2.0.1(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@truffle/contract': 4.6.17(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@truffle/hdwallet-provider': 1.5.1-alpha.1(@babel/core@7.25.2)(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@types/ethereum-protocol': 1.0.5 - '@uniswap/v3-core': 1.0.1 - abi-decoder: https://codeload.github.com/UMAprotocol/abi-decoder/tar.gz/1f18b7037985bf9b8960a6dc39dc52579ef274bb - async-retry: 1.3.3 - axios: 1.12.2 - bignumber.js: 8.1.1 - chalk-pipe: 3.0.0 - decimal.js: 10.5.0 - dotenv: 9.0.2 - eth-crypto: 2.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - hardhat-deploy: 0.9.1(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - hardhat-gas-reporter: 1.0.10(bufferutil@4.0.8)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - hardhat-typechain: 0.3.5(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4)) - lodash.uniqby: 4.7.0 - minimist: 1.2.8 - moment: 2.30.1 - node-fetch: 2.7.0(encoding@0.1.13) - node-metamask: https://codeload.github.com/UMAprotocol/node-metamask/tar.gz/36b33cb82558bafcd3ab0dcfbd35b26c2c0a2584(bufferutil@4.0.8)(utf-8-validate@5.0.10) - require-context: 1.1.0 - solidity-coverage: 0.7.22(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - truffle-deploy-registry: 0.5.1 - web3: 1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - winston: 3.13.1 - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - '@uma/contracts-node@0.4.26': {} '@uma/core@2.61.0(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10)': @@ -13255,65 +13353,13 @@ snapshots: - typechain - utf-8-validate - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@maticnetwork/fx-portal': 1.0.5 - '@openzeppelin/contracts': 4.9.6 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@uniswap/lib': 4.0.1-alpha - '@uniswap/v2-core': 1.0.0 - '@uniswap/v2-periphery': 1.1.0-beta.0 - '@uniswap/v3-core': 1.0.1 - '@uniswap/v3-periphery': 1.4.4 - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@maticnetwork/fx-portal': 1.0.5 - '@openzeppelin/contracts': 4.9.6 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@uniswap/lib': 4.0.1-alpha - '@uniswap/v2-core': 1.0.0 - '@uniswap/v2-periphery': 1.1.0-beta.0 - '@uniswap/v3-core': 1.0.1 - '@uniswap/v3-periphery': 1.4.4 - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@maticnetwork/fx-portal': 1.0.5 '@openzeppelin/contracts': 4.9.6 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@uniswap/lib': 4.0.1-alpha '@uniswap/v2-core': 1.0.0 '@uniswap/v2-periphery': 1.1.0-beta.0 From 16321145796ad1bca93d9dd4adf6a1feb21cc980 Mon Sep 17 00:00:00 2001 From: Melisa Guevara Date: Thu, 23 Oct 2025 12:33:07 +0200 Subject: [PATCH 2/9] feat: index solana cctp burn transactions (#396) --- pnpm-lock.yaml | 374 ++++++++++++++++++++++--------------------------- 1 file changed, 164 insertions(+), 210 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85a904f6..b9350b1c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -350,7 +350,7 @@ importers: dependencies: '@across-protocol/sdk': specifier: ^4.3.67 - version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -9042,70 +9042,64 @@ snapshots: - typechain - utf-8-validate - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@openzeppelin/contracts': 4.1.0 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' - bufferutil + - debug + - encoding - ethers + - hardhat + - supports-color + - ts-generator + - typechain - utf-8-validate - '@across-protocol/contracts@4.1.11(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/constants': 3.1.83 - '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@defi-wonderland/smock': 2.4.0(@ethersproject/abi@5.8.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@ethersproject/abstract-provider': 5.7.0 - '@ethersproject/abstract-signer': 5.7.0 - '@ethersproject/bignumber': 5.7.0 - '@openzeppelin/contracts': 4.9.6 - '@openzeppelin/contracts-upgradeable': 4.9.6 - '@openzeppelin/foundry-upgrades': 0.4.0(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1) - '@safe-global/protocol-kit': 6.1.1(bufferutil@4.0.8)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@scroll-tech/contracts': 0.1.0 - '@solana-developers/helpers': 2.8.1(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@types/yargs': 17.0.33 - '@uma/common': 2.37.3(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) - '@uma/contracts-node': 0.4.26 - '@uma/core': 2.61.0(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) - axios: 1.12.2 - bs58: 6.0.0 - buffer-layout: 1.2.2 - prettier-plugin-rust: 0.1.9 - yargs: 17.7.2 - zksync-web3: 0.14.4(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@openzeppelin/contracts': 4.1.0 + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@openzeppelin/contracts': 4.1.0 + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) transitivePeerDependencies: - '@babel/core' - '@codechecks/client' - - '@ethersproject/abi' - '@ethersproject/hardware-wallets' - - '@nomiclabs/hardhat-ethers' - - '@openzeppelin/defender-deploy-client-cli' - - '@openzeppelin/upgrades-core' - bufferutil - - c-kzg - debug - encoding - ethers - - fastestsmallesttextencoderdecoder - hardhat - supports-color - ts-generator - typechain - - typescript - utf-8-validate - - ws - - zod - '@across-protocol/contracts@4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/contracts@4.1.11(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@across-protocol/constants': 3.1.83 '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) @@ -9122,14 +9116,14 @@ snapshots: '@solana-developers/helpers': 2.8.1(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) '@solana-program/token': 0.5.1(@solana/kit@2.1.0(typescript@5.5.4)) - '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/yargs': 17.0.33 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uma/common': 2.37.3(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) '@uma/contracts-node': 0.4.26 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - axios: 1.8.2 + '@uma/core': 2.61.0(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10) + axios: 1.12.2 bs58: 6.0.0 buffer-layout: 1.2.2 prettier-plugin-rust: 0.1.9 @@ -9156,10 +9150,11 @@ snapshots: - typescript - utf-8-validate - ws + - zod - '@across-protocol/contracts@4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@across-protocol/contracts@4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/constants': 3.1.79 + '@across-protocol/constants': 3.1.83 '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@defi-wonderland/smock': 2.4.0(@ethersproject/abi@5.8.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) @@ -9169,15 +9164,16 @@ snapshots: '@openzeppelin/contracts': 4.9.6 '@openzeppelin/contracts-upgradeable': 4.9.6 '@openzeppelin/foundry-upgrades': 0.4.0(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1) + '@safe-global/protocol-kit': 6.1.1(bufferutil@4.0.8)(typescript@5.5.4)(utf-8-validate@5.0.10) '@scroll-tech/contracts': 0.1.0 '@solana-developers/helpers': 2.8.1(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) - '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token': 0.5.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/address-lookup-table': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana-program/token': 0.5.1(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/spl-token': 0.4.13(@solana/web3.js@1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/yargs': 17.0.33 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@uma/contracts-node': 0.4.26 '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) axios: 1.12.2 @@ -9218,8 +9214,8 @@ snapshots: '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 '@pinata/sdk': 2.1.0 - '@solana-program/system': 0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)) + '@solana-program/system': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(typescript@5.5.4))(@solana/sysvars@2.1.0(typescript@5.5.4)) '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/mocha': 10.0.7 @@ -9263,18 +9259,18 @@ snapshots: - ws - zod - '@across-protocol/sdk@4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@across-protocol/sdk@4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@across-protocol/constants': 3.1.79 - '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 '@pinata/sdk': 2.1.0 - '@solana-program/system': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(typescript@5.5.4)) - '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana-program/system': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) + '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(typescript@5.5.4))(@solana/sysvars@2.1.0(typescript@5.5.4)) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/mocha': 10.0.7 '@types/node': 24.3.1 @@ -9321,14 +9317,14 @@ snapshots: dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@across-protocol/constants': 3.1.79 - '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 '@pinata/sdk': 2.1.0 '@solana-program/system': 0.7.0(@solana/kit@2.1.0(typescript@5.5.4)) '@solana-program/token-2022': 0.4.1(@solana/kit@2.1.0(typescript@5.5.4))(@solana/sysvars@2.1.0(typescript@5.5.4)) - '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.2(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@types/mocha': 10.0.7 '@types/node': 24.3.1 @@ -11900,56 +11896,22 @@ snapshots: - typescript - utf-8-validate - '@solana-program/address-lookup-table@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - - '@solana-program/address-lookup-table@0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana-program/address-lookup-table@0.7.0(@solana/kit@2.1.0(typescript@5.5.4))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4) - - '@solana-program/system@0.7.0(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana-program/system@0.7.0(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana-program/system@0.7.0(@solana/kit@2.1.0(typescript@5.5.4))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4) - - '@solana-program/token-2022@0.4.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - - '@solana-program/token-2022@0.4.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(typescript@5.5.4))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) '@solana-program/token-2022@0.4.1(@solana/kit@2.1.0(typescript@5.5.4))(@solana/sysvars@2.1.0(typescript@5.5.4))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - - '@solana-program/token@0.5.1(@solana/kit@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - - '@solana-program/token@0.5.1(@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)))': - dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) '@solana-program/token@0.5.1(@solana/kit@2.1.0(typescript@5.5.4))': dependencies: - '@solana/kit': 2.1.0(typescript@5.5.4) + '@solana/kit': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/accounts@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: @@ -12129,56 +12091,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/kit@2.1.0(typescript@5.5.4)': - dependencies: - '@solana/accounts': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/codecs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/errors': 2.1.0(typescript@5.5.4) - '@solana/functional': 2.1.0(typescript@5.5.4) - '@solana/instructions': 2.1.0(typescript@5.5.4) - '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/programs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc-parsed-types': 2.1.0(typescript@5.5.4) - '@solana/rpc-spec-types': 2.1.0(typescript@5.5.4) - '@solana/rpc-subscriptions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/signers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transaction-confirmation': 2.1.0(typescript@5.5.4) - '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - - '@solana/kit@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': - dependencies: - '@solana/accounts': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/codecs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/errors': 2.1.0(typescript@5.5.4) - '@solana/functional': 2.1.0(typescript@5.5.4) - '@solana/instructions': 2.1.0(typescript@5.5.4) - '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/programs': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc-parsed-types': 2.1.0(typescript@5.5.4) - '@solana/rpc-spec-types': 2.1.0(typescript@5.5.4) - '@solana/rpc-subscriptions': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/signers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/sysvars': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transaction-confirmation': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/codecs-core': 2.0.0-rc.1(typescript@5.5.4) @@ -12257,15 +12169,6 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/rpc-subscriptions-channel-websocket@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.1.0(typescript@5.5.4) - '@solana/functional': 2.1.0(typescript@5.5.4) - '@solana/rpc-subscriptions-spec': 2.1.0(typescript@5.5.4) - '@solana/subscribable': 2.1.0(typescript@5.5.4) - typescript: 5.5.4 - ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/rpc-subscriptions-channel-websocket@2.1.0(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@solana/errors': 2.1.0(typescript@5.5.4) @@ -12301,24 +12204,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/rpc-subscriptions@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': - dependencies: - '@solana/errors': 2.1.0(typescript@5.5.4) - '@solana/fast-stable-stringify': 2.1.0(typescript@5.5.4) - '@solana/functional': 2.1.0(typescript@5.5.4) - '@solana/promises': 2.1.0(typescript@5.5.4) - '@solana/rpc-spec-types': 2.1.0(typescript@5.5.4) - '@solana/rpc-subscriptions-api': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc-subscriptions-channel-websocket': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/rpc-subscriptions-spec': 2.1.0(typescript@5.5.4) - '@solana/rpc-transformers': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/subscribable': 2.1.0(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/rpc-transformers@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/errors': 2.1.0(typescript@5.5.4) @@ -12439,40 +12324,6 @@ snapshots: - fastestsmallesttextencoderdecoder - ws - '@solana/transaction-confirmation@2.1.0(typescript@5.5.4)': - dependencies: - '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/codecs-strings': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/errors': 2.1.0(typescript@5.5.4) - '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/promises': 2.1.0(typescript@5.5.4) - '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc-subscriptions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - - '@solana/transaction-confirmation@2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))': - dependencies: - '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/codecs-strings': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/errors': 2.1.0(typescript@5.5.4) - '@solana/keys': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/promises': 2.1.0(typescript@5.5.4) - '@solana/rpc': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/rpc-subscriptions': 2.1.0(typescript@5.5.4)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/rpc-types': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transaction-messages': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - '@solana/transactions': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) - typescript: 5.5.4 - transitivePeerDependencies: - - fastestsmallesttextencoderdecoder - - ws - '@solana/transaction-messages@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4)': dependencies: '@solana/addresses': 2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4) @@ -13225,7 +13076,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13276,7 +13127,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13325,6 +13176,57 @@ snapshots: - typechain - utf-8-validate + '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@google-cloud/kms': 3.8.0(encoding@0.1.13) + '@google-cloud/storage': 6.12.0(encoding@0.1.13) + '@nomicfoundation/hardhat-verify': 1.1.1(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)) + '@nomiclabs/hardhat-web3': 2.0.1(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(web3@1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@truffle/contract': 4.6.17(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@truffle/hdwallet-provider': 1.5.1-alpha.1(@babel/core@7.25.2)(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@types/ethereum-protocol': 1.0.5 + '@uniswap/v3-core': 1.0.1 + abi-decoder: https://codeload.github.com/UMAprotocol/abi-decoder/tar.gz/1f18b7037985bf9b8960a6dc39dc52579ef274bb + async-retry: 1.3.3 + axios: 1.8.2 + bignumber.js: 8.1.1 + chalk-pipe: 3.0.0 + decimal.js: 10.5.0 + dotenv: 9.0.2 + eth-crypto: 2.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat-deploy: 0.9.1(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + hardhat-gas-reporter: 1.0.10(bufferutil@4.0.8)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + hardhat-typechain: 0.3.5(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4)) + lodash.uniqby: 4.7.0 + minimist: 1.2.8 + moment: 2.30.1 + node-fetch: 2.7.0(encoding@0.1.13) + node-metamask: https://codeload.github.com/UMAprotocol/node-metamask/tar.gz/36b33cb82558bafcd3ab0dcfbd35b26c2c0a2584(bufferutil@4.0.8)(utf-8-validate@5.0.10) + require-context: 1.1.0 + solidity-coverage: 0.7.22(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + truffle-deploy-registry: 0.5.1 + web3: 1.10.4(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + winston: 3.13.1 + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + '@uma/contracts-node@0.4.26': {} '@uma/core@2.61.0(@babel/core@7.25.2)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(utf-8-validate@5.0.10)': @@ -13353,7 +13255,33 @@ snapshots: - typechain - utf-8-validate - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@maticnetwork/fx-portal': 1.0.5 + '@openzeppelin/contracts': 4.9.6 + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uniswap/lib': 4.0.1-alpha + '@uniswap/v2-core': 1.0.0 + '@uniswap/v2-periphery': 1.1.0-beta.0 + '@uniswap/v3-core': 1.0.1 + '@uniswap/v3-periphery': 1.4.4 + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + + '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -13379,6 +13307,32 @@ snapshots: - typechain - utf-8-validate + '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@maticnetwork/fx-portal': 1.0.5 + '@openzeppelin/contracts': 4.9.6 + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uniswap/lib': 4.0.1-alpha + '@uniswap/v2-core': 1.0.0 + '@uniswap/v2-periphery': 1.1.0-beta.0 + '@uniswap/v3-core': 1.0.1 + '@uniswap/v3-periphery': 1.4.4 + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + '@uma/logger@1.3.1(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@google-cloud/logging-winston': 4.2.4(encoding@0.1.13)(winston@3.13.1) From 0bb9b2672143aa2a8106130318a35d585fc859af Mon Sep 17 00:00:00 2001 From: amateima Date: Thu, 16 Oct 2025 16:07:06 +0300 Subject: [PATCH 3/9] feat: send cctp burn transactions to pubsub --- .../src/entities/CctpFinalizerJob.ts | 39 ++++ .../src/entities/evm/DepositForBurn.ts | 5 + .../indexer-database/src/entities/index.ts | 2 + packages/indexer-database/src/main.ts | 1 + .../1760541259411-CctpFinalizerJob.ts | 28 +++ packages/indexer/README.md | 3 + packages/indexer/package.json | 1 + .../service/CctpFinalizerService.ts | 204 ++++++++++++++++++ packages/indexer/src/main.ts | 11 + packages/indexer/src/parseEnv.ts | 8 + packages/indexer/src/pubsub/service.ts | 34 +++ pnpm-lock.yaml | 14 +- 12 files changed, 343 insertions(+), 7 deletions(-) create mode 100644 packages/indexer-database/src/entities/CctpFinalizerJob.ts create mode 100644 packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts create mode 100644 packages/indexer/src/data-indexing/service/CctpFinalizerService.ts create mode 100644 packages/indexer/src/pubsub/service.ts diff --git a/packages/indexer-database/src/entities/CctpFinalizerJob.ts b/packages/indexer-database/src/entities/CctpFinalizerJob.ts new file mode 100644 index 00000000..7abfe401 --- /dev/null +++ b/packages/indexer-database/src/entities/CctpFinalizerJob.ts @@ -0,0 +1,39 @@ +import { + Column, + CreateDateColumn, + Entity, + JoinColumn, + OneToOne, + PrimaryGeneratedColumn, + Unique, + UpdateDateColumn, +} from "typeorm"; +import { DepositForBurn } from "./evm/DepositForBurn"; + +/** + * Table to store the burn events sent to be finalized by the + * finalizer bot. Each row points to a burn event that has + * been sent successfully to the finalizer bot. + */ +@Entity() +@Unique("UK_cctpFinalizerJob_burnEventId", ["burnEventId"]) +export class CctpFinalizerJob { + @PrimaryGeneratedColumn() + id: number; + + @Column() + attestation: string; + + @Column() + burnEventId: number; + + @OneToOne(() => DepositForBurn, (burnEvent) => burnEvent.id) + @JoinColumn({ name: "burnEventId" }) + burnEvent: DepositForBurn; + + @CreateDateColumn() + createdAt: Date; + + @UpdateDateColumn() + updatedAt: Date; +} diff --git a/packages/indexer-database/src/entities/evm/DepositForBurn.ts b/packages/indexer-database/src/entities/evm/DepositForBurn.ts index 77a17457..3122bc38 100644 --- a/packages/indexer-database/src/entities/evm/DepositForBurn.ts +++ b/packages/indexer-database/src/entities/evm/DepositForBurn.ts @@ -4,9 +4,11 @@ import { DeleteDateColumn, Entity, Index, + OneToOne, PrimaryGeneratedColumn, Unique, } from "typeorm"; +import { CctpFinalizerJob } from "../CctpFinalizerJob"; @Entity({ schema: "evm" }) @Unique("UK_depositForBurn_chain_block_txn_log", [ @@ -77,4 +79,7 @@ export class DepositForBurn { @DeleteDateColumn({ nullable: true }) deletedAt?: Date; + + @OneToOne(() => CctpFinalizerJob, (finalizerJob) => finalizerJob.burnEvent) + finalizerJob: CctpFinalizerJob; } diff --git a/packages/indexer-database/src/entities/index.ts b/packages/indexer-database/src/entities/index.ts index eaa585dc..cf83d16e 100644 --- a/packages/indexer-database/src/entities/index.ts +++ b/packages/indexer-database/src/entities/index.ts @@ -37,6 +37,8 @@ export * from "./evm/MintAndWithdraw"; export * from "./evm/MessageReceived"; export * from "./evm/SponsoredDepositForBurn"; +export * from "./CctpFinalizerJob"; + // OFT export * from "./evm/OftSent"; export * from "./evm/OftReceived"; diff --git a/packages/indexer-database/src/main.ts b/packages/indexer-database/src/main.ts index 6b9960b9..29958b4e 100644 --- a/packages/indexer-database/src/main.ts +++ b/packages/indexer-database/src/main.ts @@ -69,6 +69,7 @@ export const createDataSource = (config: DatabaseConfig): DataSource => { entities.MessageReceived, entities.MintAndWithdraw, entities.SponsoredDepositForBurn, + entities.CctpFinalizerJob, // OFT entities.OFTSent, entities.OFTReceived, diff --git a/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts b/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts new file mode 100644 index 00000000..284e36a7 --- /dev/null +++ b/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts @@ -0,0 +1,28 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CctpFinalizerJob1760541259411 implements MigrationInterface { + name = "CctpFinalizerJob1760541259411"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TABLE "cctp_finalizer_job" ( + "id" SERIAL NOT NULL, + "attestation" character varying NOT NULL, + "burnEventId" integer NOT NULL, + "createdAt" TIMESTAMP NOT NULL DEFAULT now(), + "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), + CONSTRAINT "REL_955f0780d44fb1b785425d7b56" UNIQUE ("burnEventId"), + CONSTRAINT "PK_f6a74f608a35916f58fbb1da6ba" PRIMARY KEY ("id") + )`); + await queryRunner.query( + `ALTER TABLE "cctp_finalizer_job" ADD CONSTRAINT "FK_955f0780d44fb1b785425d7b567" FOREIGN KEY ("burnEventId") REFERENCES "evm"."deposit_for_burn"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "cctp_finalizer_job" DROP CONSTRAINT "FK_955f0780d44fb1b785425d7b567"`, + ); + await queryRunner.query(`DROP TABLE "cctp_finalizer_job"`); + } +} diff --git a/packages/indexer/README.md b/packages/indexer/README.md index b39904be..33dafc1b 100644 --- a/packages/indexer/README.md +++ b/packages/indexer/README.md @@ -53,6 +53,9 @@ ENABLE_BUNDLE_INCLUDED_EVENTS_SERVICE=true ENABLE_BUNDLE_BUILDER=true ENABLE_PRICE_WORKER=false ENABLE_CCTP_INDEXER=false +ENABLE_CCTP_FINALIZER=false + +CCTP_FINALIZER_PUBSUB_TOPIC= COINGECKO_API_KEY= BUNDLE_EVENTS_SERVICE_START_BLOCK_NUMBER= diff --git a/packages/indexer/package.json b/packages/indexer/package.json index dbe5303f..5a333c95 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -30,6 +30,7 @@ "@types/express": "^4.17.21", "@types/lodash": "^4.17.7", "@types/luxon": "^3.4.2", + "axios": "^1.12.2", "bullmq": "^5.12.12", "ethers": "^5.8.0", "express": "^4.19.2", diff --git a/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts b/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts new file mode 100644 index 00000000..c828b00b --- /dev/null +++ b/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts @@ -0,0 +1,204 @@ +import winston, { Logger } from "winston"; +import axios from "axios"; + +import { RepeatableTask } from "../../generics"; +import { DataSource } from "@repo/indexer-database"; +import { + CctpFinalizerJob, + DepositForBurn, +} from "../../../../indexer-database/dist/src/entities"; +import { CHAIN_IDs } from "@across-protocol/constants"; +import { PubSubService } from "../../pubsub/service"; +import { Config } from "../../parseEnv"; + +export const CCTP_FINALIZER_DELAY_SECONDS = 10; + +export class CctpFinalizerServiceManager { + private service: RepeatableTask; + private pubSubService: PubSubService; + + constructor( + private logger: Logger, + private config: Config, + private postgres: DataSource, + ) {} + + public async start() { + try { + if (!this.config.enableCctpFinalizer) { + this.logger.warn({ + at: "Indexer#CctpFinalizerServiceManager#start", + message: "CCTP finalizer is disabled", + }); + return; + } + + this.pubSubService = new PubSubService(this.config); + this.service = new CctpFinalizerService( + this.logger, + this.postgres, + this.pubSubService, + ); + await this.service.start(CCTP_FINALIZER_DELAY_SECONDS); + } catch (error) { + this.logger.error({ + at: "Indexer#CctpFinalizerServiceManager#start", + message: "Error starting CCTP finalizer", + error, + errorJson: JSON.stringify(error), + }); + throw error; + } + } + + public async stopGracefully() { + this.service?.stop(); + } +} + +/** + * @description This service is designed to run on an interval basis similar to a cron job. + * It publishes CCTP burn events info to the pubsub topic so that the finalization bot can + * finalize the burn events indexed by the indexer. This service doesn't deal with + * submitting the finalization transaction onchain, it just publishes the messages + * to the the pubsub topic. + */ +class CctpFinalizerService extends RepeatableTask { + constructor( + logger: winston.Logger, + private readonly postgres: DataSource, + private readonly pubSubService: PubSubService, + ) { + super(logger, "cctp-finalizer-service"); + } + + protected async taskLogic(): Promise { + try { + //#region devnote + // Steps: + // 1. Get the burn events from the database that were not published to the pubsub topic yet. + // 2. Publish the burn events info to the pubsub topic. As an optimization, publish only + // the burn events for which the attestation is available. + // 3. Create a new CctpFinalizJob row in the database for each burn event that was published + // to the pubsub topic, so that they are picked up again. + //#endregion + const qb = this.postgres + .createQueryBuilder(DepositForBurn, "burnEvent") + .leftJoinAndSelect("burnEvent.finalizerJob", "job") + .where("job.id IS NULL") + // Filter out the burn events that have been deleted due to re-orgs. + .andWhere("burnEvent.deletedAt IS NULL"); + const burnEvents = await qb.getMany(); + + for (const burnEvent of burnEvents) { + await this.publishBurnEvent(burnEvent); + } + } catch (error) { + this.logger.error({ + at: "CctpFinalizerService#taskLogic", + message: "Error in CctpFinalizerService", + notificationPath: "across-indexer-error", + errorJson: JSON.stringify(error), + error, + }); + } + } + + protected initialize(): Promise { + // Empty because there's no need to initialize dependencies for now. + return Promise.resolve(); + } + + private async publishBurnEvent(burnEvent: DepositForBurn) { + try { + const { chainId, transactionHash, minFinalityThreshold, blockTimestamp } = + burnEvent; + // Skip the event if the attestation time has not passed yet. Attestation times are + // taken from here: https://developers.circle.com/cctp/required-block-confirmations + const attestationTimeSeconds = getAttestationTime( + Number(chainId), + minFinalityThreshold, + ); + const elapsedSeconds = + new Date().getTime() / 1000 - blockTimestamp.getTime() / 1000; + + if (elapsedSeconds < attestationTimeSeconds * 1000) { + this.logger.debug({ + at: "CctpFinalizerService#publishBurnEvent", + message: + "Skipping burn event because the attestation time has not passed yet", + chainId, + transactionHash, + minFinalityThreshold, + blockTimestamp, + attestationTimeSeconds, + elapsedSeconds, + }); + return; + } + this.logger.debug({ + at: "CctpFinalizerService#publishBurnEvent", + message: "Publishing burn event to pubsub", + chainId, + transactionHash, + minFinalityThreshold, + blockTimestamp, + attestationTimeSeconds, + elapsedSeconds, + }); + await this.pubSubService.publishCctpFinalizerMessage( + transactionHash, + Number(chainId), + ); + + await this.postgres + .createQueryBuilder(CctpFinalizerJob, "j") + .insert() + .values({ + attestation: "", + burnEventId: burnEvent.id, + }) + .orUpdate(["attestation"], ["burnEventId"]) + .execute(); + } catch (error) { + this.logger.error({ + at: "CctpFinalizerService#publishBurnEvent", + message: "Error in CctpFinalizerService", + notificationPath: "across-indexer-error", + errorJson: JSON.stringify(error), + error, + }); + } + } +} + +const ATTESTATION_TIMES = { + [CHAIN_IDs.MAINNET]: { standard: 13 * 60, fast: 20 }, + [CHAIN_IDs.ARBITRUM]: { standard: 13 * 60, fast: 8 }, + [CHAIN_IDs.BASE]: { standard: 13 * 60, fast: 8 }, + [CHAIN_IDs.BSC]: { standard: 2, fast: 8 }, + [CHAIN_IDs.HYPEREVM]: { standard: 5, fast: 8 }, + [CHAIN_IDs.INK]: { standard: 30 * 60, fast: 8 }, + [CHAIN_IDs.LINEA]: { standard: 6 * 60 * 60, fast: 8 }, + [CHAIN_IDs.OPTIMISM]: { standard: 13 * 60, fast: 8 }, + [CHAIN_IDs.POLYGON]: { standard: 8, fast: 8 }, + [CHAIN_IDs.SOLANA]: { standard: 25, fast: 8 }, + [CHAIN_IDs.UNICHAIN]: { standard: 13 * 60, fast: 8 }, + [CHAIN_IDs.WORLD_CHAIN]: { standard: 13 * 60, fast: 8 }, +}; + +function getAttestationTime(chainId: number, finalityThreshold: number) { + let finalityKey: keyof (typeof ATTESTATION_TIMES)[typeof chainId]; + if (finalityThreshold <= 1000) { + finalityKey = "fast"; + } else { + finalityKey = "standard"; + } + const attestationTime = ATTESTATION_TIMES[chainId]?.[finalityKey]; + if (!attestationTime) { + throw new Error( + `CCTP attestation time not defined for chainId: ${chainId}`, + ); + } + return attestationTime; +} diff --git a/packages/indexer/src/main.ts b/packages/indexer/src/main.ts index 644dea73..2d8b506f 100644 --- a/packages/indexer/src/main.ts +++ b/packages/indexer/src/main.ts @@ -32,6 +32,7 @@ import { CCTPIndexerManager } from "./data-indexing/service/CCTPIndexerManager"; import { OFTIndexerManager } from "./data-indexing/service/OFTIndexerManager"; import { CCTPRepository } from "./database/CctpRepository"; import { OftRepository } from "./database/OftRepository"; +import { CctpFinalizerServiceManager } from "./data-indexing/service/CctpFinalizerService"; async function initializeRedis( config: parseEnv.RedisConfig, @@ -144,6 +145,11 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { retryProvidersFactory, indexerQueuesService, ); + const cctpFinalizerServiceManager = new CctpFinalizerServiceManager( + logger, + config, + postgres, + ); // Set up message workers const integratorIdWorker = new IntegratorIdWorker( @@ -183,6 +189,7 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { oftIndexerManager.stopGracefully(); bundleServicesManager.stop(); hotfixServicesManager.stop(); + cctpFinalizerServiceManager.stopGracefully(); } else { integratorIdWorker.close(); swapWorker.close(); @@ -206,12 +213,14 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { cctpIndexerManagerResult, oftIndexerManagerResult, hotfixServicesManagerResults, + cctpFinalizerServiceManagerResults, ] = await Promise.allSettled([ bundleServicesManager.start(), acrossIndexerManager.start(), cctpIndexerManager.start(), oftIndexerManager.start(), hotfixServicesManager.start(), + cctpFinalizerServiceManager.start(), ]); logger.info({ at: "Indexer#Main", @@ -227,6 +236,8 @@ export async function Main(config: parseEnv.Config, logger: winston.Logger) { cctpIndexerManagerResult.status === "fulfilled", oftIndexerManagerRunSuccess: oftIndexerManagerResult.status === "fulfilled", + cctpFinalizerServiceManagerRunSuccess: + cctpFinalizerServiceManagerResults.status === "fulfilled", }, }); await integratorIdWorker.close(); diff --git a/packages/indexer/src/parseEnv.ts b/packages/indexer/src/parseEnv.ts index a4e069e0..8f41ecab 100644 --- a/packages/indexer/src/parseEnv.ts +++ b/packages/indexer/src/parseEnv.ts @@ -20,6 +20,8 @@ export type Config = { enableHotfixServices: boolean; enableBundleBuilder: boolean; enableCctpIndexer: boolean; + enableCctpFinalizer: boolean; + finalizerPubSubTopic: string; enableOftIndexer: boolean; webhookConfig: WebhooksConfig; maxBlockRangeSize?: number; @@ -221,6 +223,10 @@ export function envToConfig(env: Env): Config { const enableOftIndexer = env.ENABLE_OFT_INDEXER ? env.ENABLE_OFT_INDEXER === "true" : false; + const enableCctpFinalizer = env.ENABLE_CCTP_FINALIZER + ? env.ENABLE_CCTP_FINALIZER === "true" + : false; + const finalizerPubSubTopic = env.CCTP_FINALIZER_PUBSUB_TOPIC ?? ""; const enableBundleIncludedEventsService = env.ENABLE_BUNDLE_INCLUDED_EVENTS_SERVICE ? env.ENABLE_BUNDLE_INCLUDED_EVENTS_SERVICE === "true" @@ -279,6 +285,8 @@ export function envToConfig(env: Env): Config { enableBundleBuilder, enableCctpIndexer, enableOftIndexer, + enableCctpFinalizer, + finalizerPubSubTopic, webhookConfig, maxBlockRangeSize, coingeckoApiKey, diff --git a/packages/indexer/src/pubsub/service.ts b/packages/indexer/src/pubsub/service.ts new file mode 100644 index 00000000..7dfb8d9c --- /dev/null +++ b/packages/indexer/src/pubsub/service.ts @@ -0,0 +1,34 @@ +import axios from "axios"; +import { Config } from "../parseEnv"; + +/** + * Helper class to publish messages to a GCP pubsub topic. + */ +export class PubSubService { + constructor(private readonly config: Config) {} + + async publishCctpFinalizerMessage( + burnTransactionHash: string, + sourceChainId: number, + ) { + // the published payload is a base64 encoded JSON string. The JSON is + // validated by the Avro schema defined in GCP + const payload = Buffer.from( + JSON.stringify({ + burnTransactionHash: burnTransactionHash, + sourceChainId, + }), + ).toString("base64"); + const body = { messages: [{ data: payload }] }; + const response = await axios.post(this.config.finalizerPubSubTopic, body, { + headers: { + "Content-Type": "application/json", + // TODO: this authorization method is temporary for local testing. + // It must be replaced with a proper authentication method. + Authorization: `Bearer `, + }, + }); + + return response.data; + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b9350b1c..9d6478e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,6 +172,9 @@ importers: '@types/luxon': specifier: ^3.4.2 version: 3.4.2 + axios: + specifier: ^1.12.2 + version: 1.12.2 bullmq: specifier: ^5.12.12 version: 5.12.14 @@ -351,9 +354,6 @@ importers: '@across-protocol/sdk': specifier: ^4.3.67 version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - ethers: - specifier: ^5.8.0 - version: 5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) pg: specifier: ^8.4.0 version: 8.12.0 @@ -9152,7 +9152,7 @@ snapshots: - ws - zod - '@across-protocol/contracts@4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/contracts@4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/constants': 3.1.83 '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) @@ -9263,7 +9263,7 @@ snapshots: dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@across-protocol/constants': 3.1.79 - '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 @@ -9317,7 +9317,7 @@ snapshots: dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@across-protocol/constants': 3.1.79 - '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 @@ -13194,7 +13194,7 @@ snapshots: '@uniswap/v3-core': 1.0.1 abi-decoder: https://codeload.github.com/UMAprotocol/abi-decoder/tar.gz/1f18b7037985bf9b8960a6dc39dc52579ef274bb async-retry: 1.3.3 - axios: 1.8.2 + axios: 1.12.2 bignumber.js: 8.1.1 chalk-pipe: 3.0.0 decimal.js: 10.5.0 From c0a23456c23d8963c21474d8d9a78b1850303cc2 Mon Sep 17 00:00:00 2001 From: amateima Date: Tue, 21 Oct 2025 19:44:56 +0300 Subject: [PATCH 4/9] Integrate pubsub lib --- .../src/entities/CctpFinalizerJob.ts | 3 + .../1760541259411-CctpFinalizerJob.ts | 1 + packages/indexer/package.json | 1 + .../data-indexing/adapter/cctp-v2/service.ts | 39 ++ .../service/CCTPIndexerManager.ts | 3 +- .../service/CctpFinalizerService.ts | 53 ++- packages/indexer/src/parseEnv.ts | 9 +- packages/indexer/src/pubsub/service.ts | 37 +- pnpm-lock.yaml | 397 +++++++++++++----- 9 files changed, 420 insertions(+), 123 deletions(-) diff --git a/packages/indexer-database/src/entities/CctpFinalizerJob.ts b/packages/indexer-database/src/entities/CctpFinalizerJob.ts index 7abfe401..96d618ee 100644 --- a/packages/indexer-database/src/entities/CctpFinalizerJob.ts +++ b/packages/indexer-database/src/entities/CctpFinalizerJob.ts @@ -24,6 +24,9 @@ export class CctpFinalizerJob { @Column() attestation: string; + @Column() + message: string; + @Column() burnEventId: number; diff --git a/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts b/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts index 284e36a7..79086c7b 100644 --- a/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts +++ b/packages/indexer-database/src/migrations/1760541259411-CctpFinalizerJob.ts @@ -8,6 +8,7 @@ export class CctpFinalizerJob1760541259411 implements MigrationInterface { CREATE TABLE "cctp_finalizer_job" ( "id" SERIAL NOT NULL, "attestation" character varying NOT NULL, + "message" character varying NOT NULL, "burnEventId" integer NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), diff --git a/packages/indexer/package.json b/packages/indexer/package.json index 5a333c95..3a74fd42 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -24,6 +24,7 @@ "@across-protocol/constants": "^3.1.82", "@across-protocol/contracts": "^4.1.11", "@across-protocol/sdk": "^4.3.75", + "@google-cloud/pubsub": "^5.2.0", "@repo/error-handling": "workspace:*", "@repo/webhooks": "workspace:*", "@solana/kit": "^2.1.0", diff --git a/packages/indexer/src/data-indexing/adapter/cctp-v2/service.ts b/packages/indexer/src/data-indexing/adapter/cctp-v2/service.ts index cefca7a1..a1ace226 100644 --- a/packages/indexer/src/data-indexing/adapter/cctp-v2/service.ts +++ b/packages/indexer/src/data-indexing/adapter/cctp-v2/service.ts @@ -1,8 +1,10 @@ import { ethers } from "ethers"; +import axios from "axios"; import { CCTP_NO_DOMAIN, CHAIN_IDs, PRODUCTION_NETWORKS, + PUBLIC_NETWORKS, TEST_NETWORKS, } from "@across-protocol/constants"; import * as across from "@across-protocol/sdk"; @@ -81,6 +83,19 @@ export function decodeMessage(messageBytesArray: Uint8Array) { }; } +/** + * @notice Returns the CCTP domain for a given chain ID. Throws if the chain ID is not a CCTP domain. + * @param chainId + * @returns CCTP Domain ID + */ +export function getCctpDomainForChainId(chainId: number): number { + const cctpDomain = PUBLIC_NETWORKS[chainId]?.cctpDomain; + if (!across.utils.isDefined(cctpDomain) || cctpDomain === CCTP_NO_DOMAIN) { + throw new Error(`No CCTP domain found for chainId: ${chainId}`); + } + return cctpDomain; +} + export function getCctpDestinationChainFromDomain( domain: number, productionNetworks: boolean = true, @@ -111,3 +126,27 @@ export function getCctpDestinationChainFromDomain( } return parseInt(chainId); } + +export type CCTPV2APIGetAttestationResponse = { + messages: CCTPV2APIAttestation[]; +}; + +export type CCTPV2APIAttestation = { + eventNonce: string; + status: string; + attestation: string; + message: string; +}; + +export async function fetchAttestationsForTxn( + sourceDomainId: number, + transactionHash: string, + isMainnet: boolean, +): Promise { + const httpResponse = await axios.get( + `https://iris-api${ + isMainnet ? "" : "-sandbox" + }.circle.com/v2/messages/${sourceDomainId}?transactionHash=${transactionHash}`, + ); + return httpResponse.data; +} diff --git a/packages/indexer/src/data-indexing/service/CCTPIndexerManager.ts b/packages/indexer/src/data-indexing/service/CCTPIndexerManager.ts index 48186355..0c34b893 100644 --- a/packages/indexer/src/data-indexing/service/CCTPIndexerManager.ts +++ b/packages/indexer/src/data-indexing/service/CCTPIndexerManager.ts @@ -74,7 +74,8 @@ export class CCTPIndexerManager { ); const indexer = new EvmIndexer( { - indexingDelaySeconds: getIndexingDelaySeconds(chainId, this.config), + indexingDelaySeconds: + getIndexingDelaySeconds(chainId, this.config) * 2, finalisedBlockBufferDistance: getFinalisedBlockBufferDistance(chainId), maxBlockRangeSize: MAX_BLOCK_RANGE_SIZE, diff --git a/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts b/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts index c828b00b..0dc1e86b 100644 --- a/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts +++ b/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts @@ -2,7 +2,7 @@ import winston, { Logger } from "winston"; import axios from "axios"; import { RepeatableTask } from "../../generics"; -import { DataSource } from "@repo/indexer-database"; +import { DataSource, entities } from "@repo/indexer-database"; import { CctpFinalizerJob, DepositForBurn, @@ -10,6 +10,11 @@ import { import { CHAIN_IDs } from "@across-protocol/constants"; import { PubSubService } from "../../pubsub/service"; import { Config } from "../../parseEnv"; +import { + fetchAttestationsForTxn, + getCctpDestinationChainFromDomain, + getCctpDomainForChainId, +} from "../adapter/cctp-v2/service"; export const CCTP_FINALIZER_DELAY_SECONDS = 10; @@ -136,6 +141,43 @@ class CctpFinalizerService extends RepeatableTask { }); return; } + const attestations = await fetchAttestationsForTxn( + getCctpDomainForChainId(Number(burnEvent.chainId)), + transactionHash, + true, + ); + if (attestations.messages.length === 0) { + this.logger.debug({ + at: "CctpFinalizerService#publishBurnEvent", + message: "No attestations found for burn event", + chainId, + transactionHash, + burnEvent, + }); + return; + } + const { attestation, eventNonce, message, status } = + attestations.messages[0]!; + if (status !== "complete") { + this.logger.debug({ + at: "CctpFinalizerService#publishBurnEvent", + message: "Attestation is not complete", + chainId, + transactionHash, + burnEvent, + attestations, + }); + return; + } + + await this.postgres + .createQueryBuilder(entities.MessageSent, "ms") + .update() + .set({ + nonce: eventNonce, + }) + .where("id = :id", { id: burnEvent.id }) + .execute(); this.logger.debug({ at: "CctpFinalizerService#publishBurnEvent", message: "Publishing burn event to pubsub", @@ -146,16 +188,23 @@ class CctpFinalizerService extends RepeatableTask { attestationTimeSeconds, elapsedSeconds, }); + const destinationChainId = getCctpDestinationChainFromDomain( + burnEvent.destinationDomain, + ); await this.pubSubService.publishCctpFinalizerMessage( transactionHash, Number(chainId), + message, + attestation, + destinationChainId, ); await this.postgres .createQueryBuilder(CctpFinalizerJob, "j") .insert() .values({ - attestation: "", + attestation, + message, burnEventId: burnEvent.id, }) .orUpdate(["attestation"], ["burnEventId"]) diff --git a/packages/indexer/src/parseEnv.ts b/packages/indexer/src/parseEnv.ts index 8f41ecab..6803465e 100644 --- a/packages/indexer/src/parseEnv.ts +++ b/packages/indexer/src/parseEnv.ts @@ -21,7 +21,8 @@ export type Config = { enableBundleBuilder: boolean; enableCctpIndexer: boolean; enableCctpFinalizer: boolean; - finalizerPubSubTopic: string; + pubSubCctpFinalizerTopic: string; + pubSubGcpProjectId: string; enableOftIndexer: boolean; webhookConfig: WebhooksConfig; maxBlockRangeSize?: number; @@ -226,7 +227,8 @@ export function envToConfig(env: Env): Config { const enableCctpFinalizer = env.ENABLE_CCTP_FINALIZER ? env.ENABLE_CCTP_FINALIZER === "true" : false; - const finalizerPubSubTopic = env.CCTP_FINALIZER_PUBSUB_TOPIC ?? ""; + const pubSubCctpFinalizerTopic = env.PUBSUB_CCTP_FINALIZER_TOPIC ?? ""; + const pubSubGcpProjectId = env.PUBSUB_GCP_PROJECT_ID ?? ""; const enableBundleIncludedEventsService = env.ENABLE_BUNDLE_INCLUDED_EVENTS_SERVICE ? env.ENABLE_BUNDLE_INCLUDED_EVENTS_SERVICE === "true" @@ -286,7 +288,8 @@ export function envToConfig(env: Env): Config { enableCctpIndexer, enableOftIndexer, enableCctpFinalizer, - finalizerPubSubTopic, + pubSubCctpFinalizerTopic, + pubSubGcpProjectId, webhookConfig, maxBlockRangeSize, coingeckoApiKey, diff --git a/packages/indexer/src/pubsub/service.ts b/packages/indexer/src/pubsub/service.ts index 7dfb8d9c..91f0b172 100644 --- a/packages/indexer/src/pubsub/service.ts +++ b/packages/indexer/src/pubsub/service.ts @@ -1,34 +1,43 @@ -import axios from "axios"; +import { PubSub, Topic } from "@google-cloud/pubsub"; import { Config } from "../parseEnv"; /** * Helper class to publish messages to a GCP pubsub topic. */ export class PubSubService { - constructor(private readonly config: Config) {} + private readonly pubSub: PubSub; + private cctpFinalizerTopic: Topic; + + constructor(private readonly config: Config) { + this.pubSub = new PubSub({ + projectId: this.config.pubSubGcpProjectId, + }); + } async publishCctpFinalizerMessage( burnTransactionHash: string, sourceChainId: number, + message: string, + attestation: string, + destinationChainId: number, ) { + if (!this.cctpFinalizerTopic) { + const topic = await this.pubSub.topic( + this.config.pubSubCctpFinalizerTopic, + ); + this.cctpFinalizerTopic = topic; + } // the published payload is a base64 encoded JSON string. The JSON is // validated by the Avro schema defined in GCP const payload = Buffer.from( JSON.stringify({ burnTransactionHash: burnTransactionHash, sourceChainId, + message, + attestation, + destinationChainId, }), - ).toString("base64"); - const body = { messages: [{ data: payload }] }; - const response = await axios.post(this.config.finalizerPubSubTopic, body, { - headers: { - "Content-Type": "application/json", - // TODO: this authorization method is temporary for local testing. - // It must be replaced with a proper authentication method. - Authorization: `Bearer `, - }, - }); - - return response.data; + ); + await this.cctpFinalizerTopic.publishMessage({ data: payload }); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d6478e1..94e21490 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1275,6 +1275,14 @@ packages: resolution: {integrity: sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==} engines: {node: '>=10'} + '@google-cloud/paginator@6.0.0': + resolution: {integrity: sha512-g5nmMnzC+94kBxOKkLGpK1ikvolTFCC3s2qtE4F+1EuArcJ7HHC23RDQVt3Ra3CqpUYZ+oXNKZ8n5Cn5yug8DA==} + engines: {node: '>=18'} + + '@google-cloud/precise-date@5.0.0': + resolution: {integrity: sha512-9h0Gvw92EvPdE8AK8AgZPbMnH5ftDyPtKm7/KUfcJVaPEPjwGDsJd1QV0H8esBDV4II41R/2lDWH1epBqIoKUw==} + engines: {node: '>=18'} + '@google-cloud/projectify@2.1.1': resolution: {integrity: sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==} engines: {node: '>=10'} @@ -1283,6 +1291,10 @@ packages: resolution: {integrity: sha512-HRkZsNmjScY6Li8/kb70wjGlDDyLkVk3KvoEo9uIoxSjYLJasGiCch9+PqRVDOCGUFvEIqyogl+BeqILL4OJHA==} engines: {node: '>=12.0.0'} + '@google-cloud/projectify@5.0.0': + resolution: {integrity: sha512-XXQLaIcLrOAMWvRrzz+mlUGtN6vlVNja3XQbMqRi/V7XJTAVwib3VcKd7oRwyZPkp7rBVlHGcaqdyGRrcnkhlA==} + engines: {node: '>=18'} + '@google-cloud/promisify@2.0.4': resolution: {integrity: sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==} engines: {node: '>=10'} @@ -1291,6 +1303,14 @@ packages: resolution: {integrity: sha512-z1CjRjtQyBOYL+5Qr9DdYIfrdLBe746jRTYfaYU6MeXkqp7UfYs/jX16lFFVzZ7PGEJvqZNqYUEtb1mvDww4pA==} engines: {node: '>=12'} + '@google-cloud/promisify@5.0.0': + resolution: {integrity: sha512-N8qS6dlORGHwk7WjGXKOSsLjIjNINCPicsOX6gyyLiYk7mq3MtII96NZ9N2ahwA2vnkLmZODOIH9rlNniYWvCQ==} + engines: {node: '>=18'} + + '@google-cloud/pubsub@5.2.0': + resolution: {integrity: sha512-YNSRBo85mgPQ9QuuzAHjmLwngIwmy2RjAUAoPl2mOL2+bCM0cAVZswPb8ylcsWJP7PgDJlck+ybv0MwJ9AM0sg==} + engines: {node: '>=18'} + '@google-cloud/storage@6.12.0': resolution: {integrity: sha512-78nNAY7iiZ4O/BouWMWTD/oSF2YtYgYB3GZirn0To6eBOugjXVoK+GXgUXOl+HlqbAOyHxAVXOlsj3snfbQ1dw==} engines: {node: '>=12'} @@ -1299,6 +1319,10 @@ packages: resolution: {integrity: sha512-TLZwbR9WYx/wNhJv6PcbKEuHZpArUG1WtaPLwjxRJeTVNDV2gOsDVDihbezCyyOcHxU3kXCewB5y2BA1pP0mIg==} engines: {node: '>=10'} + '@grpc/grpc-js@1.14.0': + resolution: {integrity: sha512-N8Jx6PaYzcTRNzirReJCtADVoq4z7+1KQ4E70jTg/koQiMoUSN1kbNjPOqpPbhMFhfU1/l7ixspPl8dNY+FoUg==} + engines: {node: '>=12.10.0'} + '@grpc/grpc-js@1.6.12': resolution: {integrity: sha512-JmvQ03OTSpVd9JTlj/K3IWHSz4Gk/JMLUTtW7Zb0KvO1LcOYGATh5cNuRYzCAeDR3O8wq+q8FZe97eO9MBrkUw==} engines: {node: ^8.13.0 || >=10.10.0} @@ -1317,6 +1341,11 @@ packages: engines: {node: '>=6'} hasBin: true + '@grpc/proto-loader@0.8.0': + resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==} + engines: {node: '>=6'} + hasBin: true + '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -1376,6 +1405,9 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jsdoc/salty@0.2.9': resolution: {integrity: sha512-yYxMVH7Dqw6nO0d5NIV8OQWnitU8k6vXH8NtgqAfIa/IUqRMxRv/NUJJ08VEKbAakwxlgBl5PJdrU0dMPStsnw==} engines: {node: '>=v12.0.0'} @@ -1615,6 +1647,24 @@ packages: '@opencensus/propagation-stackdriver@0.1.0': resolution: {integrity: sha512-YLklu8jnnYKaJ8gUFz3rM0FVdsWXEJAMLzeeU4JRac6LI34raENy4kvRezZtNEFS5KthaJUsYg04sPc/Ag0w4w==} + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/core@1.30.1': + resolution: {integrity: sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.28.0': + resolution: {integrity: sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==} + engines: {node: '>=14'} + + '@opentelemetry/semantic-conventions@1.34.0': + resolution: {integrity: sha512-aKcOkyrorBGlajjRdVoJWHTxfxO1vCNHLJVlSDaRHDIdjU+pX8IYQPvPDkYiujKLbRnWU+1TBwEt0QRgSm4SGA==} + engines: {node: '>=14'} + '@openzeppelin/contracts-upgradeable@4.9.6': resolution: {integrity: sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA==} @@ -3799,6 +3849,10 @@ packages: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} engines: {node: '>= 0.4'} @@ -4696,6 +4750,10 @@ packages: fecha@4.2.3: resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + fetch-ponyfill@4.1.0: resolution: {integrity: sha512-knK9sGskIg2T7OnYLdZ2hZXn0CtDrAIBxYQLpmEf0BqfdWnwmM1weccUl5+4EdA44tzNSFAuxITPbXtPehUB3g==} @@ -4800,6 +4858,10 @@ packages: resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} engines: {node: '>= 6'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + formidable@3.5.1: resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} @@ -4884,6 +4946,10 @@ packages: resolution: {integrity: sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==} engines: {node: '>=12'} + gaxios@7.1.2: + resolution: {integrity: sha512-/Szrn8nr+2TsQT1Gp8iIe/BEytJmbyfrbFh419DfGQSkEgNEhbPi7JRJuughjkTzPWgU9gBQf5AVu3DbHt0OXA==} + engines: {node: '>=18'} + gcp-metadata@4.3.1: resolution: {integrity: sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==} engines: {node: '>=10'} @@ -4892,6 +4958,10 @@ packages: resolution: {integrity: sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==} engines: {node: '>=12'} + gcp-metadata@8.1.1: + resolution: {integrity: sha512-dTCcAe9fRQf06ELwel6lWWFrEbstwjUBYEhr5VRGoC+iPDZQucHppCowaIp8b8v92tU1G4X4H3b/Y6zXZxkMsQ==} + engines: {node: '>=18'} + generic-pool@3.9.0: resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==} engines: {node: '>= 4'} @@ -5026,6 +5096,10 @@ packages: resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + google-auth-library@10.4.1: + resolution: {integrity: sha512-VlvZ+QDWng3aPh++0BSQlSJyjn4qgLLTmqylAR3as0dr6YwPkZpHcZAngAFr68TDVCUSQVRTkV73K/D3m7vEIg==} + engines: {node: '>=18'} + google-auth-library@7.14.1: resolution: {integrity: sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==} engines: {node: '>=10'} @@ -5044,6 +5118,14 @@ packages: engines: {node: '>=12'} hasBin: true + google-gax@5.0.4: + resolution: {integrity: sha512-HmQ6zIYBs2EikTk+kjeHmtHprNTEpsnVaKONw9cwZZwUNCkUb+D5RYrJpCxyjdvIDvJp3wLbVReolJLRZRms1g==} + engines: {node: '>=18'} + + google-logging-utils@1.1.1: + resolution: {integrity: sha512-rcX58I7nqpu4mbKztFeOAObbomBbHU2oIb/d3tJfF3dizGSApqtSwYJigGCooHdnMyQBIw8BrWyK96w3YXgr6A==} + engines: {node: '>=14'} + google-p12-pem@3.1.4: resolution: {integrity: sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==} engines: {node: '>=10'} @@ -5089,6 +5171,10 @@ packages: resolution: {integrity: sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==} engines: {node: '>=12.0.0'} + gtoken@8.0.0: + resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==} + engines: {node: '>=18'} + handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} @@ -5199,6 +5285,10 @@ packages: header-case@1.0.1: resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} + heap-js@2.7.1: + resolution: {integrity: sha512-EQfezRg0NCZGNlhlDR3Evrw1FVL2G3LhU7EgPoxufQKruNBSYA8MiRPHeWbU+36o+Fhel0wMwM+sLEiBAlNLJA==} + engines: {node: '>=10.0.0'} + hex2dec@1.1.2: resolution: {integrity: sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==} @@ -6331,6 +6421,11 @@ packages: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} @@ -6346,6 +6441,10 @@ packages: encoding: optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -6626,6 +6725,10 @@ packages: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} + p-defer@3.0.0: + resolution: {integrity: sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==} + engines: {node: '>=8'} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -6980,6 +7083,10 @@ packages: resolution: {integrity: sha512-AwAuY4g9nxx0u52DnSMkqqgyLHaW/XaPLtaAo3y/ZCfeaQB/g4YDH4kb8Wc/mWzWvu0YjOznVnfn373MVZZrgw==} engines: {node: '>=12.0.0'} + proto3-json-serializer@3.0.3: + resolution: {integrity: sha512-iUi7jGLuECChuoUwtvf6eXBDcFXTHAt5GM6ckvtD3RqD+j2wW0GW6WndPOu9IWeUk7n933lzrskcNMHJy2tFSw==} + engines: {node: '>=18'} + protobufjs-cli@1.1.1: resolution: {integrity: sha512-VPWMgIcRNyQwWUv8OLPyGQ/0lQY/QTQAVN5fh+XzfDwsVw1FZ2L3DM/bcBf8WPiRz2tNpaov9lPZfNcmNo6LXA==} engines: {node: '>=12.0.0'} @@ -7003,6 +7110,10 @@ packages: resolution: {integrity: sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==} engines: {node: '>=12.0.0'} + protobufjs@7.5.4: + resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + engines: {node: '>=12.0.0'} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -7291,6 +7402,10 @@ packages: resolution: {integrity: sha512-wfI3pk7EE80lCIXprqh7ym48IHYdwmAAzESdbU8Q9l7pnRCk9LEhpbOTNKjz6FARLm/Bl5m+4F0ABxOkYUujSQ==} engines: {node: '>=12'} + retry-request@8.0.2: + resolution: {integrity: sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==} + engines: {node: '>=18'} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -7841,6 +7956,10 @@ packages: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} + teeny-request@10.1.0: + resolution: {integrity: sha512-3ZnLvgWF29jikg1sAQ1g0o+lr5JX6sVgYvfUJazn7ZjJroDBUTWp44/+cFVX0bULjv4vci+rBD+oGVAkWqhUbw==} + engines: {node: '>=18'} + teeny-request@7.2.0: resolution: {integrity: sha512-SyY0pek1zWsi0LRVAALem+avzMLc33MKW/JLLakdP4s9+D7+jHcy5x6P+h94g2QNZsAqQNfX5lsbd3WSeJXrrw==} engines: {node: '>=10'} @@ -8338,6 +8457,10 @@ packages: typescript: optional: true + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + web3-bzz@1.10.0: resolution: {integrity: sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA==} engines: {node: '>=8.0.0'} @@ -9042,61 +9165,14 @@ snapshots: - typechain - utf-8-validate - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@openzeppelin/contracts': 4.1.0 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@openzeppelin/contracts': 4.1.0 - '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@openzeppelin/contracts': 4.1.0 '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - bufferutil - - debug - - encoding - ethers - - hardhat - - supports-color - - ts-generator - - typechain - utf-8-validate '@across-protocol/contracts@4.1.11(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': @@ -10854,14 +10930,44 @@ snapshots: arrify: 2.0.1 extend: 3.0.2 + '@google-cloud/paginator@6.0.0': + dependencies: + extend: 3.0.2 + + '@google-cloud/precise-date@5.0.0': {} + '@google-cloud/projectify@2.1.1': {} '@google-cloud/projectify@3.0.0': {} + '@google-cloud/projectify@5.0.0': {} + '@google-cloud/promisify@2.0.4': {} '@google-cloud/promisify@3.0.1': {} + '@google-cloud/promisify@5.0.0': {} + + '@google-cloud/pubsub@5.2.0': + dependencies: + '@google-cloud/paginator': 6.0.0 + '@google-cloud/precise-date': 5.0.0 + '@google-cloud/projectify': 5.0.0 + '@google-cloud/promisify': 5.0.0 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.34.0 + arrify: 2.0.1 + extend: 3.0.2 + google-auth-library: 10.4.1 + google-gax: 5.0.4 + heap-js: 2.7.1 + is-stream-ended: 0.1.4 + lodash.snakecase: 4.1.1 + p-defer: 3.0.0 + transitivePeerDependencies: + - supports-color + '@google-cloud/storage@6.12.0(encoding@0.1.13)': dependencies: '@google-cloud/paginator': 3.0.7 @@ -10908,6 +11014,11 @@ snapshots: - encoding - supports-color + '@grpc/grpc-js@1.14.0': + dependencies: + '@grpc/proto-loader': 0.8.0 + '@js-sdsl/ordered-map': 4.4.2 + '@grpc/grpc-js@1.6.12': dependencies: '@grpc/proto-loader': 0.7.13 @@ -10933,6 +11044,13 @@ snapshots: protobufjs: 7.3.2 yargs: 17.7.2 + '@grpc/proto-loader@0.8.0': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.2.3 + protobufjs: 7.5.4 + yargs: 17.7.2 + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -10997,6 +11115,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@js-sdsl/ordered-map@4.4.2': {} + '@jsdoc/salty@0.2.9': dependencies: lodash: 4.17.21 @@ -11292,6 +11412,17 @@ snapshots: hex2dec: 1.1.2 uuid: 8.3.2 + '@opentelemetry/api@1.9.0': {} + + '@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.28.0 + + '@opentelemetry/semantic-conventions@1.28.0': {} + + '@opentelemetry/semantic-conventions@1.34.0': {} + '@openzeppelin/contracts-upgradeable@4.9.6': {} '@openzeppelin/contracts@3.4.2-solc-0.7': {} @@ -13076,7 +13207,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13127,7 +13258,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13178,7 +13309,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13255,58 +13386,6 @@ snapshots: - typechain - utf-8-validate - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@maticnetwork/fx-portal': 1.0.5 - '@openzeppelin/contracts': 4.9.6 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@uniswap/lib': 4.0.1-alpha - '@uniswap/v2-core': 1.0.0 - '@uniswap/v2-periphery': 1.1.0-beta.0 - '@uniswap/v3-core': 1.0.1 - '@uniswap/v3-periphery': 1.4.4 - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': - dependencies: - '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@maticnetwork/fx-portal': 1.0.5 - '@openzeppelin/contracts': 4.9.6 - '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) - '@uniswap/lib': 4.0.1-alpha - '@uniswap/v2-core': 1.0.0 - '@uniswap/v2-periphery': 1.1.0-beta.0 - '@uniswap/v3-core': 1.0.1 - '@uniswap/v3-periphery': 1.4.4 - transitivePeerDependencies: - - '@babel/core' - - '@codechecks/client' - - '@ethersproject/hardware-wallets' - - bufferutil - - debug - - encoding - - ethers - - hardhat - - supports-color - - ts-generator - - typechain - - utf-8-validate - '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -14592,6 +14671,8 @@ snapshots: dependencies: assert-plus: 1.0.0 + data-uri-to-buffer@4.0.1: {} + data-view-buffer@1.0.1: dependencies: call-bind: 1.0.7 @@ -15912,6 +15993,11 @@ snapshots: fecha@4.2.3: {} + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + fetch-ponyfill@4.1.0: dependencies: node-fetch: 1.7.3 @@ -16046,6 +16132,10 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + formidable@3.5.1: dependencies: dezalgo: 1.0.4 @@ -16158,6 +16248,14 @@ snapshots: - encoding - supports-color + gaxios@7.1.2: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + node-fetch: 3.3.2 + transitivePeerDependencies: + - supports-color + gcp-metadata@4.3.1(encoding@0.1.13): dependencies: gaxios: 4.3.3(encoding@0.1.13) @@ -16174,6 +16272,14 @@ snapshots: - encoding - supports-color + gcp-metadata@8.1.1: + dependencies: + gaxios: 7.1.2 + google-logging-utils: 1.1.1 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + generic-pool@3.9.0: {} gensync@1.0.0-beta.2: {} @@ -16346,6 +16452,18 @@ snapshots: merge2: 1.4.1 slash: 4.0.0 + google-auth-library@10.4.1: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.2 + gcp-metadata: 8.1.1 + google-logging-utils: 1.1.1 + gtoken: 8.0.0 + jws: 4.0.0 + transitivePeerDependencies: + - supports-color + google-auth-library@7.14.1(encoding@0.1.13): dependencies: arrify: 2.0.1 @@ -16416,6 +16534,23 @@ snapshots: - encoding - supports-color + google-gax@5.0.4: + dependencies: + '@grpc/grpc-js': 1.14.0 + '@grpc/proto-loader': 0.8.0 + duplexify: 4.1.3 + google-auth-library: 10.4.1 + google-logging-utils: 1.1.1 + node-fetch: 3.3.2 + object-hash: 3.0.0 + proto3-json-serializer: 3.0.3 + protobufjs: 7.5.4 + retry-request: 8.0.2 + transitivePeerDependencies: + - supports-color + + google-logging-utils@1.1.1: {} + google-p12-pem@3.1.4: dependencies: node-forge: 1.3.1 @@ -16498,6 +16633,13 @@ snapshots: - encoding - supports-color + gtoken@8.0.0: + dependencies: + gaxios: 7.1.2 + jws: 4.0.0 + transitivePeerDependencies: + - supports-color + handlebars@4.7.8: dependencies: minimist: 1.2.8 @@ -16779,6 +16921,8 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 + heap-js@2.7.1: {} + hex2dec@1.1.2: {} hexoid@1.0.0: {} @@ -17956,6 +18100,8 @@ snapshots: dependencies: minimatch: 3.1.2 + node-domexception@1.0.0: {} + node-emoji@1.11.0: dependencies: lodash: 4.17.21 @@ -17971,6 +18117,12 @@ snapshots: optionalDependencies: encoding: 0.1.13 + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} node-gyp-build-optional-packages@5.2.2: @@ -18232,6 +18384,8 @@ snapshots: p-cancelable@3.0.0: {} + p-defer@3.0.0: {} + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -18582,6 +18736,10 @@ snapshots: dependencies: protobufjs: 7.3.2 + proto3-json-serializer@3.0.3: + dependencies: + protobufjs: 7.5.4 + protobufjs-cli@1.1.1(protobufjs@7.2.4): dependencies: chalk: 4.1.2 @@ -18658,6 +18816,21 @@ snapshots: '@types/node': 16.18.104 long: 5.2.3 + protobufjs@7.5.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 16.18.104 + long: 5.2.3 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -19024,6 +19197,13 @@ snapshots: transitivePeerDependencies: - supports-color + retry-request@8.0.2: + dependencies: + extend: 3.0.2 + teeny-request: 10.1.0 + transitivePeerDependencies: + - supports-color + retry@0.12.0: {} retry@0.13.1: {} @@ -19752,6 +19932,15 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 + teeny-request@10.1.0: + dependencies: + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + node-fetch: 3.3.2 + stream-events: 1.0.5 + transitivePeerDependencies: + - supports-color + teeny-request@7.2.0(encoding@0.1.13): dependencies: http-proxy-agent: 5.0.0 @@ -20239,6 +20428,8 @@ snapshots: - utf-8-validate - zod + web-streams-polyfill@3.3.3: {} + web3-bzz@1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: '@types/node': 12.20.55 From 45cbd2750e68e5506d2fd939c2791bb37dbe7c3b Mon Sep 17 00:00:00 2001 From: amateima Date: Thu, 23 Oct 2025 19:49:12 +0300 Subject: [PATCH 5/9] Fix --- pnpm-lock.yaml | 124 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 11 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 94e21490..e538df9a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -354,6 +354,9 @@ importers: '@across-protocol/sdk': specifier: ^4.3.67 version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + ethers: + specifier: ^5.8.0 + version: 5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) pg: specifier: ^8.4.0 version: 8.12.0 @@ -9165,14 +9168,61 @@ snapshots: - typechain - utf-8-validate - '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@openzeppelin/contracts': 4.1.0 + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@openzeppelin/contracts': 4.1.0 + '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + + '@across-protocol/contracts@0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@eth-optimism/contracts': 0.5.40(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@openzeppelin/contracts': 4.1.0 '@uma/core': 2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' - bufferutil + - debug + - encoding - ethers + - hardhat + - supports-color + - ts-generator + - typechain - utf-8-validate '@across-protocol/contracts@4.1.11(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))': @@ -9228,7 +9278,7 @@ snapshots: - ws - zod - '@across-protocol/contracts@4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/contracts@4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/constants': 3.1.83 '@coral-xyz/anchor': 0.31.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) @@ -9339,7 +9389,7 @@ snapshots: dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@across-protocol/constants': 3.1.79 - '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 @@ -9393,7 +9443,7 @@ snapshots: dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@across-protocol/constants': 3.1.79 - '@across-protocol/contracts': 4.1.9(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) + '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/bignumber': 5.8.0 @@ -13207,7 +13257,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13258,7 +13308,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13309,7 +13359,7 @@ snapshots: '@uma/common@2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: - '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@across-protocol/contracts': 0.1.4(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) '@ethersproject/address': 5.8.0 '@ethersproject/bignumber': 5.8.0 '@ethersproject/bytes': 5.8.0 @@ -13386,6 +13436,58 @@ snapshots: - typechain - utf-8-validate + '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@maticnetwork/fx-portal': 1.0.5 + '@openzeppelin/contracts': 4.9.6 + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uniswap/lib': 4.0.1-alpha + '@uniswap/v2-core': 1.0.0 + '@uniswap/v2-periphery': 1.1.0-beta.0 + '@uniswap/v3-core': 1.0.1 + '@uniswap/v3-periphery': 1.4.4 + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + + '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + dependencies: + '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@gnosis.pm/zodiac': 3.2.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@maticnetwork/fx-portal': 1.0.5 + '@openzeppelin/contracts': 4.9.6 + '@uma/common': 2.37.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@uniswap/lib': 4.0.1-alpha + '@uniswap/v2-core': 1.0.0 + '@uniswap/v2-periphery': 1.1.0-beta.0 + '@uniswap/v3-core': 1.0.1 + '@uniswap/v3-periphery': 1.4.4 + transitivePeerDependencies: + - '@babel/core' + - '@codechecks/client' + - '@ethersproject/hardware-wallets' + - bufferutil + - debug + - encoding + - ethers + - hardhat + - supports-color + - ts-generator + - typechain + - utf-8-validate + '@uma/core@2.61.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': dependencies: '@gnosis.pm/safe-contracts': 1.3.0(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) @@ -13466,7 +13568,7 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.5.4) eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)) eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) @@ -15228,7 +15330,7 @@ snapshots: eslint: 8.57.0 eslint-plugin-turbo: 2.0.11(eslint@8.57.0) - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)): dependencies: eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) @@ -15245,7 +15347,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 @@ -15257,7 +15359,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: From a89f06fa67d0530dea5ab62faccadbe68f8bfb8e Mon Sep 17 00:00:00 2001 From: amateima Date: Fri, 24 Oct 2025 11:40:13 +0300 Subject: [PATCH 6/9] Fix --- packages/indexer/src/pubsub/service.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/indexer/src/pubsub/service.ts b/packages/indexer/src/pubsub/service.ts index 91f0b172..18ba09ed 100644 --- a/packages/indexer/src/pubsub/service.ts +++ b/packages/indexer/src/pubsub/service.ts @@ -22,9 +22,7 @@ export class PubSubService { destinationChainId: number, ) { if (!this.cctpFinalizerTopic) { - const topic = await this.pubSub.topic( - this.config.pubSubCctpFinalizerTopic, - ); + const topic = this.pubSub.topic(this.config.pubSubCctpFinalizerTopic); this.cctpFinalizerTopic = topic; } // the published payload is a base64 encoded JSON string. The JSON is From c121f7c85a8754ff85d1e2bf1ec62ba7ef735d15 Mon Sep 17 00:00:00 2001 From: amateima <89395931+amateima@users.noreply.github.com> Date: Thu, 30 Oct 2025 11:10:34 +0200 Subject: [PATCH 7/9] Update packages/indexer/src/data-indexing/service/CctpFinalizerService.ts Co-authored-by: Melisa Guevara --- .../indexer/src/data-indexing/service/CctpFinalizerService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts b/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts index 0dc1e86b..e2a6cb50 100644 --- a/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts +++ b/packages/indexer/src/data-indexing/service/CctpFinalizerService.ts @@ -84,7 +84,7 @@ class CctpFinalizerService extends RepeatableTask { // 1. Get the burn events from the database that were not published to the pubsub topic yet. // 2. Publish the burn events info to the pubsub topic. As an optimization, publish only // the burn events for which the attestation is available. - // 3. Create a new CctpFinalizJob row in the database for each burn event that was published + // 3. Create a new CctpFinalizerJob row in the database for each burn event that was published // to the pubsub topic, so that they are picked up again. //#endregion const qb = this.postgres From 0aaf2fdb1d3fb98070b767a410bc19807e51aa84 Mon Sep 17 00:00:00 2001 From: amateima Date: Thu, 30 Oct 2025 11:13:01 +0200 Subject: [PATCH 8/9] Fix --- packages/indexer/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/indexer/README.md b/packages/indexer/README.md index 33dafc1b..2ff1d44f 100644 --- a/packages/indexer/README.md +++ b/packages/indexer/README.md @@ -55,7 +55,8 @@ ENABLE_PRICE_WORKER=false ENABLE_CCTP_INDEXER=false ENABLE_CCTP_FINALIZER=false -CCTP_FINALIZER_PUBSUB_TOPIC= +PUBSUB_CCTP_FINALIZER_TOPIC= +PUBSUB_GCP_PROJECT_ID= COINGECKO_API_KEY= BUNDLE_EVENTS_SERVICE_START_BLOCK_NUMBER= From ffca0ddff0a569510e8f1284ede22322da43308f Mon Sep 17 00:00:00 2001 From: amateima Date: Wed, 5 Nov 2025 16:30:58 +0100 Subject: [PATCH 9/9] Remove oft transfers aggregator --- packages/indexer-database/src/main.ts | 1 - .../migrations/1760347378412-OftTransfer.ts | 61 -- .../migrations/1760464624377-OftTransfer.ts | 27 - .../service/OFTIndexerDataHandler.ts | 3 - .../service/OFTIndexerManager.ts | 1 - .../tests/oft-transfer-aggregator/README.md | 235 ----- .../oft-transfer-aggregator/index.test.ts | 833 ------------------ pnpm-lock.yaml | 21 +- 8 files changed, 12 insertions(+), 1170 deletions(-) delete mode 100644 packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts delete mode 100644 packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts delete mode 100644 packages/indexer/src/tests/oft-transfer-aggregator/README.md delete mode 100644 packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts diff --git a/packages/indexer-database/src/main.ts b/packages/indexer-database/src/main.ts index 29958b4e..2285c397 100644 --- a/packages/indexer-database/src/main.ts +++ b/packages/indexer-database/src/main.ts @@ -73,7 +73,6 @@ export const createDataSource = (config: DatabaseConfig): DataSource => { // OFT entities.OFTSent, entities.OFTReceived, - entities.OftTransfer, ], migrationsTableName: "_migrations", migrations: ["migrations/*.ts"], diff --git a/packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts b/packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts deleted file mode 100644 index fa33b77b..00000000 --- a/packages/indexer-database/src/migrations/1760347378412-OftTransfer.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class OftTransfer1760347378412 implements MigrationInterface { - name = "OftTransfer1760347378412"; - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(` - CREATE TYPE "public"."oft_transfer_status_enum" AS ENUM( - 'unfilled', - 'filled' - ) - `); - await queryRunner.query(` - CREATE TABLE "oft_transfer" ( - "id" SERIAL NOT NULL, - "guid" character varying NOT NULL, - "originChainId" bigint NOT NULL, - "destinationChainId" bigint NOT NULL, - "originTokenAddress" character varying, - "destinationTokenAddress" character varying, - "originTokenAmount" numeric, - "destinationTokenAmount" numeric, - "originTxnRef" character varying, - "destinationTxnRef" character varying, - "oftSentEventId" integer, - "oftReceivedEventId" integer, - "status" "public"."oft_transfer_status_enum" NOT NULL DEFAULT 'unfilled', - "bridgeFeeUsd" numeric, - "originGasFee" numeric, - "originGasFeeUsd" numeric, - "originGasTokenPriceUsd" numeric, - "createdAt" TIMESTAMP NOT NULL DEFAULT now(), - "updatedAt" TIMESTAMP NOT NULL DEFAULT now(), - CONSTRAINT "REL_a55d2ab4103b4a13e824848b7d" UNIQUE ("oftSentEventId"), - CONSTRAINT "REL_85a1fa5348947197b31809477c" UNIQUE ("oftReceivedEventId"), - CONSTRAINT "PK_c986f173fc2315410daf73cfdde" PRIMARY KEY ("id") - ) - `); - await queryRunner.query(` - ALTER TABLE "oft_transfer" - ADD CONSTRAINT "FK_a55d2ab4103b4a13e824848b7d4" - FOREIGN KEY ("oftSentEventId") REFERENCES "evm"."oft_sent"("id") ON DELETE NO ACTION ON UPDATE NO ACTION - `); - await queryRunner.query(` - ALTER TABLE "oft_transfer" - ADD CONSTRAINT "FK_85a1fa5348947197b31809477c1" - FOREIGN KEY ("oftReceivedEventId") REFERENCES "evm"."oft_received"("id") ON DELETE NO ACTION ON UPDATE NO ACTION - `); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "oft_transfer" DROP CONSTRAINT "FK_85a1fa5348947197b31809477c1"`, - ); - await queryRunner.query( - `ALTER TABLE "oft_transfer" DROP CONSTRAINT "FK_a55d2ab4103b4a13e824848b7d4"`, - ); - await queryRunner.query(`DROP TABLE "oft_transfer"`); - await queryRunner.query(`DROP TYPE "public"."oft_transfer_status_enum"`); - } -} diff --git a/packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts b/packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts deleted file mode 100644 index b4cbb282..00000000 --- a/packages/indexer-database/src/migrations/1760464624377-OftTransfer.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class OftTransfer1760464624377 implements MigrationInterface { - name = "OftTransfer1760464624377"; - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "oft_transfer" ADD CONSTRAINT "UQ_85fc3827b7381fa02ef4e01f008" UNIQUE ("guid")`, - ); - await queryRunner.query( - `CREATE INDEX "IX_oft_transfer_status" ON "oft_transfer" ("status") `, - ); - await queryRunner.query( - `CREATE INDEX "IX_oft_transfer_origin_txn_ref" ON "oft_transfer" ("originTxnRef") `, - ); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `DROP INDEX "public"."IX_oft_transfer_origin_txn_ref"`, - ); - await queryRunner.query(`DROP INDEX "public"."IX_oft_transfer_status"`); - await queryRunner.query( - `ALTER TABLE "oft_transfer" DROP CONSTRAINT "UQ_85fc3827b7381fa02ef4e01f008"`, - ); - } -} diff --git a/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts b/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts index 18fcda60..72ddc31a 100644 --- a/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts +++ b/packages/indexer/src/data-indexing/service/OFTIndexerDataHandler.ts @@ -28,17 +28,14 @@ const SWAP_API_CALLDATA_MARKER = "73c0de"; export class OFTIndexerDataHandler implements IndexerDataHandler { private isInitialized: boolean; - private oftTransferAggregator: OftTransferAggregator; constructor( private logger: Logger, private chainId: number, private provider: across.providers.RetryProvider, private oftRepository: OftRepository, - private postgres: DataSource, ) { this.isInitialized = false; - this.oftTransferAggregator = new OftTransferAggregator(postgres); } private initialize() {} diff --git a/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts b/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts index e5c060b7..17ebb6e1 100644 --- a/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts +++ b/packages/indexer/src/data-indexing/service/OFTIndexerManager.ts @@ -65,7 +65,6 @@ export class OFTIndexerManager { Number(chainId), provider, this.oftRepository, - this.postgres, ); const indexer = new EvmIndexer( { diff --git a/packages/indexer/src/tests/oft-transfer-aggregator/README.md b/packages/indexer/src/tests/oft-transfer-aggregator/README.md deleted file mode 100644 index be8070b6..00000000 --- a/packages/indexer/src/tests/oft-transfer-aggregator/README.md +++ /dev/null @@ -1,235 +0,0 @@ -# OftTransferAggregator End-to-End Test Plan - -## Overview - -This document outlines the test plan for the `OftTransferAggregator` class, which is responsible for aggregating OFT (Omnichain Fungible Token) events into unified OFT transfers. - -## Test Cases - -### 1. New OFTSent Event Processing - -#### 1.1 Single OFTSent Event → New OFT Transfer Created - -- **Given**: An empty database -- **When**: A new OFTSent event is added -- **Then**: - - A new OftTransfer row is created - - `guid` matches the sent event's GUID - - `oftSentEventId` is set to the sent event's ID - - `status` is `"unfilled"` - -#### 1.2 Multiple OFTSent Events with Different GUIDs - -- **Given**: An empty database -- **When**: Multiple OFTSent events with different GUIDs are added -- **Then**: - - Each event creates a separate OftTransfer row (3 transfers for 3 events) - - All rows have `status` = `"unfilled"` - - All rows have `oftSentEventId` set - -#### 1.3 OFTSent Event with Existing GUID (Different Event ID) - -- **Given**: An existing OftTransfer with a specific GUID linked to OFTSent event A -- **When**: A new OFTSent event B with the same GUID but different event ID is added -- **Then**: - - Only one OftTransfer row exists (no duplicates) - - `guid` remains the same - - `oftSentEventId` is updated to event B's ID - -#### 1.4 OFTSent Event with Existing GUID (Same Event ID) - -- **Given**: An existing OftTransfer linked to OFTSent event A -- **When**: The same OFTSent event A is processed again -- **Then**: - - No update occurs (no-op) - - Database remains unchanged - ---- - -### 2. New OFTReceived Event Processing - -#### 2.1 Single OFTReceived Event → New OFT Transfer Created - -- **Given**: An empty database -- **When**: A new OFTReceived event is added -- **Then**: - - A new OftTransfer row is created - - `guid` matches the received event's GUID - - `oftReceivedEventId` is set to the received event's ID - - `status` is `"filled"` - -#### 2.2 Multiple OFTReceived Events with Different GUIDs - -- **Given**: An empty database -- **When**: Multiple OFTReceived events with different GUIDs are added -- **Then**: - - Each event creates a separate OftTransfer row (3 transfers for 3 events) - - All rows have `status` = `"filled"` - - All rows have `oftReceivedEventId` set - -#### 2.3 OFTReceived Event with Existing GUID (Different Event ID) - -- **Given**: An existing OftTransfer with a specific GUID linked to OFTReceived event A -- **When**: A new OFTReceived event B with the same GUID but different event ID is added -- **Then**: - - Only one OftTransfer row exists (no duplicates) - - `guid` remains the same - - `oftReceivedEventId` is updated to event B's ID - -#### 2.4 OFTReceived Event with Existing GUID (Same Event ID) - -- **Given**: An existing OftTransfer linked to OFTReceived event A -- **When**: The same OFTReceived event A is processed again -- **Then**: - - No update occurs (no-op) - - Database remains unchanged - ---- - -### 3. Matching Sent and Received Events - -#### 3.1 OFTSent First, Then OFTReceived (Complete Transfer) - -- **Given**: An OftTransfer exists with only OFTSent event (status = `"unfilled"`) -- **When**: An OFTReceived event with the same GUID is added -- **Then**: - - Only one OftTransfer row exists (no duplicates) - - `guid` matches both events - - Both `oftSentEventId` and `oftReceivedEventId` are set - - `status` is updated to `"filled"` - -#### 3.2 OFTReceived First, Then OFTSent (Complete Transfer) - -- **Given**: An OftTransfer exists with only OFTReceived event (status = `"filled"`) -- **When**: An OFTSent event with the same GUID is added -- **Then**: - - Only one OftTransfer row exists (no duplicates) - - `guid` matches both events - - Both `oftSentEventId` and `oftReceivedEventId` are set - - `status` remains `"filled"` - -#### 3.3 Both Events Processed Simultaneously - -- **Given**: An empty database -- **When**: Both OFTSent and OFTReceived events with the same GUID are added in the same call -- **Then**: - - Only one OftTransfer row exists (no duplicates) - - `guid` matches both events - - Both `oftSentEventId` and `oftReceivedEventId` are set - - `status` is `"filled"` - ---- - -### 4. Deleted/Re-Organized OFTSent Events - -#### 4.1 Deleted OFTSent Event (Transfer Has No OFTReceived) - -- **Given**: An OftTransfer with only OFTSent event (no received event) -- **When**: The OFTSent event is marked as deleted (deletedAt set) and processed -- **Then**: - - The entire OftTransfer row is deleted - - No transfers remain in database - -#### 4.2 Deleted OFTSent Event (Transfer Has OFTReceived) - -- **Given**: An OftTransfer with both OFTSent and OFTReceived events (status = `"filled"`) -- **When**: The OFTSent event is marked as deleted (deletedAt set) and processed -- **Then**: - - The OftTransfer row is updated (not deleted) - - Only one transfer remains - - `guid` remains the same - - `oftSentEventId` is set to null - - `oftReceivedEventId` remains set to the received event's ID - - `originTxnRef` is set to null - - `status` remains `"filled"` - -#### 4.3 Multiple Deleted OFTSent Events - -- **Given**: Multiple OftTransfers with only OFTSent events (3 transfers) -- **When**: Multiple OFTSent events are marked as deleted and processed -- **Then**: - - All transfers are deleted - - No transfers remain in database - ---- - -### 5. Deleted/Re-Organized OFTReceived Events - -#### 5.1 Deleted OFTReceived Event (Transfer Has No OFTSent) - -- **Given**: An OftTransfer with only OFTReceived event (no sent event) -- **When**: The OFTReceived event is marked as deleted (deletedAt set) and processed -- **Then**: - - The entire OftTransfer row is deleted - - No transfers remain in database - -#### 5.2 Deleted OFTReceived Event (Transfer Has OFTSent) - -- **Given**: An OftTransfer with both OFTSent and OFTReceived events (status = `"filled"`) -- **When**: The OFTReceived event is marked as deleted (deletedAt set) and processed -- **Then**: - - The OftTransfer row is updated (not deleted) - - Only one transfer remains - - `guid` remains the same - - `oftSentEventId` remains set to the sent event's ID - - `oftReceivedEventId` is set to null - - `destinationTxnRef` is set to null - - `status` is updated to `"unfilled"` - -#### 5.3 Multiple Deleted OFTReceived Events - -- **Given**: Multiple OftTransfers with only OFTReceived events (3 transfers) -- **When**: Multiple OFTReceived events are marked as deleted and processed -- **Then**: - - All transfers are deleted - - No transfers remain in database - ---- - -### 6. Complex Re-Organization Scenarios - -#### 6.1 Sequential Re-Org: Delete Then Re-Add - -- **Given**: A complete OftTransfer (both sent and received events) -- **When**: - 1. OFTSent event is marked as deleted and processed - 2. A new OFTSent event with the same GUID is added -- **Then**: - - Only one OftTransfer row exists throughout - - After re-add: `oftSentEventId` is set to the new event's ID - - Both `oftSentEventId` and `oftReceivedEventId` are set - - `status` is `"filled"` - -#### 6.2 Both Events Deleted Sequentially - -- **Given**: A complete OftTransfer (both sent and received events) -- **When**: - 1. OFTSent event is marked as deleted and processed - 2. OFTReceived event is marked as deleted and processed -- **Then**: - - After first deletion: One transfer exists (with only received event) - - After second deletion: Transfer is completely deleted - - No transfers remain in database - -#### 6.3 Both Events Deleted Simultaneously - -- **Given**: A complete OftTransfer (both sent and received events) -- **When**: Both OFTSent and OFTReceived events are marked as deleted and processed in the same call -- **Then**: - - The OftTransfer row is deleted - - No transfers remain in database - ---- - -### 7. Edge Cases and Error Handling - -#### 7.1 Empty Input Arrays - -- **Given**: Database in any state -- **When**: `processDatabaseEvents()` is called with all empty arrays -- **Then**: - - No errors occur - - Database state remains unchanged - - Method completes successfully - ---- diff --git a/packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts b/packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts deleted file mode 100644 index f9a914b3..00000000 --- a/packages/indexer/src/tests/oft-transfer-aggregator/index.test.ts +++ /dev/null @@ -1,833 +0,0 @@ -import { expect } from "chai"; -import { CHAIN_IDs } from "@across-protocol/constants"; -import { - createDataSource, - DataSource, - entities, - fixtures, -} from "@repo/indexer-database"; -import { parsePostgresConfig } from "../../parseEnv"; -import { OftTransferAggregator } from "../../data-indexing/service/OftTransferAggregator"; -import { getOftChainConfiguration } from "../../data-indexing/adapter/oft/service"; - -describe("OftTransferAggregator", () => { - // DataSource - let dataSource: DataSource; - - // Fixtures - let oftSentFixture: fixtures.OftSentFixture; - let oftReceivedFixture: fixtures.OftReceivedFixture; - let oftTransferFixture: fixtures.OftTransferFixture; - - // Aggregator - let oftTransferAggregator: OftTransferAggregator; - - // Default OFTReceived configuration - const defaultOftReceivedConfig = { - token: getOftChainConfiguration(CHAIN_IDs.MAINNET).tokens[0]!.address, - chainId: CHAIN_IDs.MAINNET.toString(), - srcEid: getOftChainConfiguration(CHAIN_IDs.POLYGON).endpointId, - }; - - before(async () => { - // Connect to database - const databaseConfig = parsePostgresConfig(process.env); - dataSource = await createDataSource(databaseConfig).initialize(); - - // Instantiate fixtures - oftSentFixture = new fixtures.OftSentFixture(dataSource); - oftReceivedFixture = new fixtures.OftReceivedFixture(dataSource); - oftTransferFixture = new fixtures.OftTransferFixture(dataSource); - - // Instantiate aggregator - oftTransferAggregator = new OftTransferAggregator(dataSource); - }); - - beforeEach(async () => { - await oftTransferFixture.deleteAllOftTransfers(); - await oftSentFixture.deleteAllOftSentEvents(); - await oftReceivedFixture.deleteAllOftReceivedEvents(); - }); - - afterEach(async () => { - await oftTransferFixture.deleteAllOftTransfers(); - await oftSentFixture.deleteAllOftSentEvents(); - await oftReceivedFixture.deleteAllOftReceivedEvents(); - }); - - after(async () => {}); - - // Test 1.1: Single OFTSent Event → New OFT Transfer Created - // Given an empty database, when new OFTSent event is added, - // then a new OftTransfer row should be created with the sent event's data - it("1.1. should create new OFT transfer when new OFTSent event is added", async () => { - const [oftSentEvent] = await oftSentFixture.insertOftSentEvents(); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(oftSentEvent!.guid); - expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - expect(oftTransfers[0]!.status).to.equal("unfilled"); - }); - - // Test 1.2: Multiple OFTSent Events with Different GUIDs - // When multiple OFTSent events with different GUIDs are processed, - // then each should create a separate OftTransfer row - it("1.2. should create separate OFT transfers when multiple OFTSent events with different GUIDs are added", async () => { - const oftSentEvents = await oftSentFixture.insertOftSentEvents([ - {}, - {}, - {}, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - oftSentEvents, - [], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(3); - oftTransfers.forEach((transfer) => { - expect(transfer.status).to.equal("unfilled"); - expect(transfer.oftSentEventId).to.not.be.null; - }); - }); - - // Test 1.3: OFTSent Event with Existing GUID (Different Event ID) - // When a new OFTSent event with same GUID but different event ID is added, - // then the existing OftTransfer should be updated - it("1.3. should update existing OFT transfer when OFTSent event with same GUID but different event ID is added", async () => { - const sharedGuid = "0x123abc"; - const [firstEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [firstEvent!], - [], - 1, - ); - - const [secondEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [secondEvent!], - [], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftSentEventId).to.equal(secondEvent!.id); - }); - - // Test 1.4: OFTSent Event with Existing GUID (Same Event ID) - // When the same OFTSent event is processed again, - // then no update should occur (no-op) - it("1.4. should not update OFT transfer when same OFTSent event is processed again", async () => { - const [oftSentEvent] = await oftSentFixture.insertOftSentEvents(); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [], - 1, - ); - let transfersAfter = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(transfersAfter[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [], - 1, - ); - transfersAfter = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(transfersAfter[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - }); - - // Test 2.1: Single OFTReceived Event → New OFT Transfer Created - // When a new OFTReceived event is added, - // then a new OftTransfer row should be created with status Filled - it("2.1. should create new OftTransfer when new OFTReceived event is added", async () => { - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [{ ...defaultOftReceivedConfig }], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [oftReceivedEvent!], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(oftReceivedEvent!.guid); - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); - expect(oftTransfers[0]!.status).to.equal("filled"); - }); - - // Test 2.2: Multiple OFTReceived Events with Different GUIDs - // When multiple OFTReceived events with different GUIDs are processed, - // then each should create a separate OftTransfer row with status Filled - it("2.2. should create separate OftTransfers when multiple OFTReceived events with different GUIDs are added", async () => { - const oftReceivedEvents = await oftReceivedFixture.insertOftReceivedEvents([ - { ...defaultOftReceivedConfig }, - { ...defaultOftReceivedConfig }, - { ...defaultOftReceivedConfig }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - oftReceivedEvents, - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(3); - oftTransfers.forEach((transfer) => { - expect(transfer.status).to.equal("filled"); - expect(transfer.oftReceivedEventId).to.not.be.null; - }); - }); - - // Test 2.3: OFTReceived Event with Existing GUID (Different Event ID) - // When a new OFTReceived event with same GUID but different event ID is added, - // then the existing OftTransfer should be updated - it("2.3. should update existing OFT transfer when OFTReceived event with same GUID but different event ID is added", async () => { - const sharedGuid = "0xabc123"; - const [firstEvent] = await oftReceivedFixture.insertOftReceivedEvents([ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [firstEvent!], - 1, - ); - - const [secondEvent] = await oftReceivedFixture.insertOftReceivedEvents([ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [secondEvent!], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(secondEvent!.id); - }); - - // Test 2.4: OFTReceived Event with Existing GUID (Same Event ID) - // When the same OFTReceived event is processed again, - // then no update should occur (no-op) - it("2.4. should not update OFT transfer when same OFTReceived event is processed again", async () => { - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [{ ...defaultOftReceivedConfig }], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [oftReceivedEvent!], - 1, - ); - let transfersAfter = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(transfersAfter[0]!.oftReceivedEventId).to.equal( - oftReceivedEvent!.id, - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [oftReceivedEvent!], - 1, - ); - transfersAfter = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(transfersAfter[0]!.oftReceivedEventId).to.equal( - oftReceivedEvent!.id, - ); - }); - - // Test 3.1: OFTSent First, Then OFTReceived (Complete Transfer) - // When OFTReceived event matches existing OFTSent event, - // then the OftTransfer should be updated with received data and status changed to Filled - it("3.1. should update OFT transfer to Filled when OFTReceived event matches existing OFTSent event", async () => { - const sharedGuid = "0xmatching123"; - const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [], - 1, - ); - - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [oftReceivedEvent!], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); - expect(oftTransfers[0]!.status).to.equal("filled"); - }); - - // Test 3.2: OFTReceived First, Then OFTSent (Complete Transfer) - // When OFTSent event matches existing OFTReceived event, - // then the OftTransfer should be updated with sent data and status remains Filled - it("3.2. should update OFT transfer with sent data when OFTSent event matches existing OFTReceived event", async () => { - const sharedGuid = "0xmatching456"; - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [oftReceivedEvent!], - 1, - ); - - const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); - expect(oftTransfers[0]!.status).to.equal("filled"); - }); - - // Test 3.3: Both Events Processed Simultaneously - // When both OFTSent and OFTReceived events with same GUID are processed together, - // then a single complete OftTransfer should be created with status Filled - it("3.3. should create single complete OFT transfer when both OFTSent and OFTReceived events are processed simultaneously", async () => { - const sharedGuid = "0xsimultaneous"; - const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [oftReceivedEvent!], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); - expect(oftTransfers[0]!.status).to.equal("filled"); - }); - - // Test 4.1: Deleted OFTSent Event (Transfer Has No OFTReceived) - // When an OFTSent event is deleted and transfer has no OFTReceived event, - // then the entire OftTransfer row should be deleted - it("4.1. should delete OFT transfer when OFTSent event is deleted and transfer has no OFTReceived event", async () => { - let [oftSentEvent] = await oftSentFixture.insertOftSentEvents(); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [], - 1, - ); - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - oftSentEvent!.deletedAt = new Date(); - oftSentEvent = await dataSource - .getRepository(entities.OFTSent) - .save(oftSentEvent!); - - await oftTransferAggregator.processDatabaseEvents( - [oftSentEvent!], - [], - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(0); - }); - - // Test 4.2: Deleted OFTSent Event (Transfer Has OFTReceived) - // When an OFTSent event is deleted but transfer has OFTReceived event, - // then the OftTransfer should be updated with sent fields nulled - it("4.2. should update OFT transfer when OFTSent event is deleted and transfer has OFTReceived event", async () => { - const sharedGuid = "0xdeleted123"; - let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [oftReceivedEvent!], - 1, - ); - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.status).to.equal("filled"); - - oftSentEvent!.deletedAt = new Date(); - oftSentEvent = await dataSource - .getRepository(entities.OFTSent) - .save(oftSentEvent!); - await oftTransferAggregator.processDatabaseEvents( - [oftSentEvent!], - [], - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftSentEventId).to.be.null; - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); - expect(oftTransfers[0]!.originTxnRef).to.be.null; - expect(oftTransfers[0]!.status).to.equal("filled"); - }); - - // Test 4.3: Multiple Deleted OFTSent Events - // When multiple OFTSent events are deleted, - // then each transfer should be processed correctly - it("4.3. should process multiple deleted OFTSent events correctly", async () => { - let oftSentEvents = await oftSentFixture.insertOftSentEvents([{}, {}, {}]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - oftSentEvents, - [], - 1, - ); - - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(3); - - oftSentEvents = await Promise.all( - oftSentEvents.map(async (event) => { - event!.deletedAt = new Date(); - return await dataSource.getRepository(entities.OFTSent).save(event!); - }), - ); - - await oftTransferAggregator.processDatabaseEvents( - oftSentEvents, - [], - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(0); - }); - - // Test 5.1: Deleted OFTReceived Event (Transfer Has No OFTSent) - // When an OFTReceived event is deleted and transfer has no OFTSent event, - // then the entire OftTransfer row should be deleted - it("5.1. should delete OFT transfer when OFTReceived event is deleted and transfer has no OFTSent event", async () => { - let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ - { ...defaultOftReceivedConfig }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - [oftReceivedEvent!], - 1, - ); - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - - oftReceivedEvent!.deletedAt = new Date(); - oftReceivedEvent = await dataSource - .getRepository(entities.OFTReceived) - .save(oftReceivedEvent!); - await oftTransferAggregator.processDatabaseEvents( - [], - [oftReceivedEvent!], - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(0); - }); - - // Test 5.2: Deleted OFTReceived Event (Transfer Has OFTSent) - // When an OFTReceived event is deleted but transfer has OFTSent event, - // then the OftTransfer should be updated with received fields nulled and status changed to Unfilled - it("5.2. should update OFT transfer when OFTReceived event is deleted and transfer has OFTSent event", async () => { - const sharedGuid = "0xdeleted456"; - const [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [oftReceivedEvent!], - 1, - ); - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.status).to.equal("filled"); - - oftReceivedEvent!.deletedAt = new Date(); - oftReceivedEvent = await dataSource - .getRepository(entities.OFTReceived) - .save(oftReceivedEvent!); - await oftTransferAggregator.processDatabaseEvents( - [], - [oftReceivedEvent!], - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.guid).to.equal(sharedGuid); - expect(oftTransfers[0]!.oftSentEventId).to.equal(oftSentEvent!.id); - expect(oftTransfers[0]!.oftReceivedEventId).to.be.null; - expect(oftTransfers[0]!.destinationTxnRef).to.be.null; - expect(oftTransfers[0]!.status).to.equal("unfilled"); - }); - - // Test 5.3: Multiple Deleted OFTReceived Events - // When multiple OFTReceived events are deleted, - // then each transfer should be processed correctly - it("5.3. should process multiple deleted OFTReceived events correctly", async () => { - let oftReceivedEvents = await oftReceivedFixture.insertOftReceivedEvents([ - { ...defaultOftReceivedConfig }, - { ...defaultOftReceivedConfig }, - { ...defaultOftReceivedConfig }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [], - oftReceivedEvents, - 1, - ); - - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(3); - - oftReceivedEvents = await Promise.all( - oftReceivedEvents.map(async (event) => { - event!.deletedAt = new Date(); - return await dataSource - .getRepository(entities.OFTReceived) - .save(event!); - }), - ); - - await oftTransferAggregator.processDatabaseEvents( - [], - oftReceivedEvents, - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(0); - }); - - // Test 6.1: Sequential Re-Org: Delete Then Re-Add - // When an OFTSent event is deleted then re-added with same GUID, - // then the transfer should be updated accordingly through both operations - it("6.1. should handle sequential re-org when OFTSent event is deleted then re-added", async () => { - const sharedGuid = "0xreorg123"; - let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - const [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents( - [ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ], - ); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [oftReceivedEvent!], - 1, - ); - - oftSentEvent!.deletedAt = new Date(); - oftSentEvent = await dataSource - .getRepository(entities.OFTSent) - .save(oftSentEvent!); - await oftTransferAggregator.processDatabaseEvents( - [oftSentEvent!], - [], - [], - [], - 1, - ); - - const [newOftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [newOftSentEvent!], - [], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - expect(oftTransfers[0]!.oftSentEventId).to.equal(newOftSentEvent!.id); - expect(oftTransfers[0]!.oftReceivedEventId).to.equal(oftReceivedEvent!.id); - expect(oftTransfers[0]!.status).to.equal("filled"); - }); - - // Test 6.2: Both Events Deleted Sequentially - // When both OFTSent and OFTReceived events are deleted sequentially, - // then the transfer should be completely deleted - it("6.2. should delete transfer when both OFTSent and OFTReceived events are deleted sequentially", async () => { - const sharedGuid = "0xbothdeleted"; - let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [oftReceivedEvent!], - 1, - ); - - oftSentEvent!.deletedAt = new Date(); - oftSentEvent = await dataSource - .getRepository(entities.OFTSent) - .save(oftSentEvent!); - await oftTransferAggregator.processDatabaseEvents( - [oftSentEvent!], - [], - [], - [], - 1, - ); - - let oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(1); - - oftReceivedEvent!.deletedAt = new Date(); - oftReceivedEvent = await dataSource - .getRepository(entities.OFTReceived) - .save(oftReceivedEvent!); - await oftTransferAggregator.processDatabaseEvents( - [], - [oftReceivedEvent!], - [], - [], - 1, - ); - - oftTransfers = await dataSource.getRepository(entities.OftTransfer).find(); - expect(oftTransfers).to.have.length(0); - }); - - // Test 6.3: Both Events Deleted Simultaneously - // When both OFTSent and OFTReceived events are deleted in parallel, - // then the transfer should be completely deleted - it("6.3. should delete transfer when both OFTSent and OFTReceived events are deleted simultaneously", async () => { - const sharedGuid = "0xsimuldelete"; - let [oftSentEvent] = await oftSentFixture.insertOftSentEvents([ - { guid: sharedGuid }, - ]); - let [oftReceivedEvent] = await oftReceivedFixture.insertOftReceivedEvents([ - { - ...defaultOftReceivedConfig, - guid: sharedGuid, - }, - ]); - await oftTransferAggregator.processDatabaseEvents( - [], - [], - [oftSentEvent!], - [oftReceivedEvent!], - 1, - ); - - oftSentEvent!.deletedAt = new Date(); - oftSentEvent = await dataSource - .getRepository(entities.OFTSent) - .save(oftSentEvent!); - oftReceivedEvent!.deletedAt = new Date(); - oftReceivedEvent = await dataSource - .getRepository(entities.OFTReceived) - .save(oftReceivedEvent!); - - await oftTransferAggregator.processDatabaseEvents( - [oftSentEvent!], - [oftReceivedEvent!], - [], - [], - 1, - ); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(0); - }); - - // Test 7.1: Empty Input Arrays - // When processDatabaseEvents is called with all empty arrays, - // then no errors should occur and database should remain unchanged - it("7.1. should handle empty input arrays without errors", async () => { - await oftTransferAggregator.processDatabaseEvents([], [], [], [], 1); - - const oftTransfers = await dataSource - .getRepository(entities.OftTransfer) - .find(); - expect(oftTransfers).to.have.length(0); - }); -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e538df9a..ef4df77e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -154,6 +154,9 @@ importers: '@across-protocol/sdk': specifier: ^4.3.75 version: 4.3.81(@babel/core@7.25.2)(@ethersproject/abi@5.8.0)(@ethersproject/hardware-wallets@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)))(@openzeppelin/defender-deploy-client-cli@0.0.1-alpha.10(encoding@0.1.13))(@openzeppelin/upgrades-core@1.44.1)(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(hardhat@2.22.19(bufferutil@4.0.8)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10))(ts-generator@0.1.1)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typechain@4.0.3(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@google-cloud/pubsub': + specifier: ^5.2.0 + version: 5.2.0 '@repo/error-handling': specifier: workspace:* version: link:../error-handling @@ -255,8 +258,8 @@ importers: packages/indexer-api: dependencies: '@across-protocol/sdk': - specifier: ^4.3.67 - version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + specifier: ^4.3.75 + version: 4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) '@repo/error-handling': specifier: workspace:* version: link:../error-handling @@ -352,8 +355,8 @@ importers: packages/indexer-database: dependencies: '@across-protocol/sdk': - specifier: ^4.3.67 - version: 4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) + specifier: ^4.3.75 + version: 4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) ethers: specifier: ^5.8.0 version: 5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -9385,10 +9388,10 @@ snapshots: - ws - zod - '@across-protocol/sdk@4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/sdk@4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@16.18.104)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - '@across-protocol/constants': 3.1.79 + '@across-protocol/constants': 3.1.83 '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) @@ -9439,10 +9442,10 @@ snapshots: - ws - zod - '@across-protocol/sdk@4.3.67(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': + '@across-protocol/sdk@4.3.81(@solana/sysvars@2.1.0(typescript@5.5.4))(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10)': dependencies: '@across-protocol/across-token': 1.0.0(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(ts-node@10.9.2(@types/node@24.3.1)(typescript@5.5.4))(typescript@5.5.4)(utf-8-validate@5.0.10) - '@across-protocol/constants': 3.1.79 + '@across-protocol/constants': 3.1.83 '@across-protocol/contracts': 4.1.11(buffer-layout@1.2.2)(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typescript@5.5.4)(utf-8-validate@5.0.10) '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.8)(encoding@0.1.13)(typescript@5.5.4)(utf-8-validate@5.0.10) '@eth-optimism/sdk': 3.3.3(bufferutil@4.0.8)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) @@ -18836,7 +18839,7 @@ snapshots: proto3-json-serializer@1.1.1: dependencies: - protobufjs: 7.3.2 + protobufjs: 7.5.4 proto3-json-serializer@3.0.3: dependencies: