Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 74 additions & 57 deletions tee-apps/sealed-bid-auction/script/server.ts
Original file line number Diff line number Diff line change
@@ -1,80 +1,97 @@
import * as dotenv from "dotenv";
import {AuctionApiServer} from "../src/api/AuctionApiServer.ts";
import {ViemIntentObserver} from "../src/blockchain/ViemIntentObserver.ts";
import {SolverPriceBook} from "../src/core/SolverPriceBook.ts";
import {AuctionService} from "../src/core/AuctionService.ts";
import {arbitrum, arbitrumSepolia, base, baseSepolia} from "viem/chains";
import {BlockchainClient} from "../src/blockchain/BlockchainClient.ts";
import * as dotenv from "dotenv"
import { AuctionApiServer } from "../src/api/AuctionApiServer.ts"
import { ViemIntentObserver } from "../src/blockchain/ViemIntentObserver.ts"
import { SolverPriceBook } from "../src/core/SolverPriceBook.ts"
import { AuctionService } from "../src/core/AuctionService.ts"
import { arbitrum, arbitrumSepolia, base, baseSepolia } from "viem/chains"
import { BlockchainClient } from "../src/blockchain/BlockchainClient.ts"

dotenv.config();
dotenv.config()

const USE_TLS = process.env.USE_TLS as string === "true";
const IS_MAINNET = process.env.IS_MAINNET as string === "true";
const USE_TLS = (process.env.USE_TLS as string) === "true"
const IS_MAINNET = (process.env.IS_MAINNET as string) === "true"
const SOLVER_PRICE_TTL_SECONDS = process.env.SOLVER_PRICE_TTL_SECONDS
const TEN_MINUTES_IN_SECONDS = 600;
const TEN_MINUTES_IN_SECONDS = 600

const BASE_T1_ERC_7683_CONTRACT_ADDRESS = process.env.BASE_T1_ERC7683_CONTRACT_ADDRESS as `0x${string}`;
const ARBITRUM_T1_ERC_7683_CONTRACT_ADDRESS = process.env.ARBITRUM_T1_ERC7683_CONTRACT_ADDRESS as `0x${string}`;
const BASE_T1_ERC_7683_CONTRACT_ADDRESS = process.env
.BASE_T1_ERC7683_CONTRACT_ADDRESS as `0x${string}`
const ARBITRUM_T1_ERC_7683_CONTRACT_ADDRESS = process.env
.ARBITRUM_T1_ERC7683_CONTRACT_ADDRESS as `0x${string}`

const ARBITRUM_WS = (process.env.ARBITRUM_WS) as string;
const BASE_WS = (process.env.BASE_WS) as string;
const ARBITRUM_WS = process.env.ARBITRUM_WS as string
const BASE_WS = process.env.BASE_WS as string

const solverPriceBook = new SolverPriceBook(SOLVER_PRICE_TTL_SECONDS ? Number(SOLVER_PRICE_TTL_SECONDS as string) : TEN_MINUTES_IN_SECONDS);
const auctionService = new AuctionService(solverPriceBook);
const solverPriceBook = new SolverPriceBook(
SOLVER_PRICE_TTL_SECONDS
? Number(SOLVER_PRICE_TTL_SECONDS as string)
: TEN_MINUTES_IN_SECONDS
)
const auctionService = new AuctionService(solverPriceBook)

const httpServer = new AuctionApiServer(solverPriceBook, auctionService);
const httpServer = new AuctionApiServer(solverPriceBook, auctionService)
const arbitrumClient = new BlockchainClient(
ARBITRUM_WS,
IS_MAINNET ? arbitrum : arbitrumSepolia,
process.env.ARBITRUM_SIGNER_PRIVATE_KEY as `0x${string}`
);
ARBITRUM_WS,
IS_MAINNET ? arbitrum : arbitrumSepolia,
process.env.ARBITRUM_SIGNER_PRIVATE_KEY as `0x${string}`
)
const baseClient = new BlockchainClient(
BASE_WS,
IS_MAINNET ? base : baseSepolia,
process.env.BASE_SIGNER_PRIVATE_KEY as `0x${string}`
);
BASE_WS,
IS_MAINNET ? base : baseSepolia,
process.env.BASE_SIGNER_PRIVATE_KEY as `0x${string}`
)

const fromBlockEnv = process.env.INTENT_OBSERVER_FROM_BLOCK
const fromBlock = fromBlockEnv ? BigInt(fromBlockEnv) : null
const auctionPollingInterval = 500;

const arbitrumSepoliaIntentObserver = new ViemIntentObserver(
arbitrumClient,
ARBITRUM_T1_ERC_7683_CONTRACT_ADDRESS,
auctionService,
httpServer,
baseClient.publicClient.chain.id,
BASE_T1_ERC_7683_CONTRACT_ADDRESS
);
arbitrumClient,
ARBITRUM_T1_ERC_7683_CONTRACT_ADDRESS,
auctionService,
httpServer,
baseClient.publicClient.chain.id,
BASE_T1_ERC_7683_CONTRACT_ADDRESS,
auctionPollingInterval,
fromBlock
)
const baseSepoliaIntentObserver = new ViemIntentObserver(
baseClient,
BASE_T1_ERC_7683_CONTRACT_ADDRESS,
auctionService,
httpServer,
arbitrumClient.publicClient.chain.id,
ARBITRUM_T1_ERC_7683_CONTRACT_ADDRESS
);
baseClient,
BASE_T1_ERC_7683_CONTRACT_ADDRESS,
auctionService,
httpServer,
arbitrumClient.publicClient.chain.id,
ARBITRUM_T1_ERC_7683_CONTRACT_ADDRESS,
auctionPollingInterval,
null
)

async function main() {
console.log(`Starting ${IS_MAINNET ? 'mainnet' : 'testnet'} Sealed Bid API server...`);
await httpServer.start(Number(process.env.SERVER_PORT as string), USE_TLS);
arbitrumSepoliaIntentObserver.start();
baseSepoliaIntentObserver.start();
console.log(
`Starting ${IS_MAINNET ? "mainnet" : "testnet"} Sealed Bid API server...`
)
await httpServer.start(Number(process.env.SERVER_PORT as string), USE_TLS)
arbitrumSepoliaIntentObserver.start()
baseSepoliaIntentObserver.start()
}

async function stopAll() {
await httpServer.stop();
await httpServer.stop()
}

main()
.then()
.catch(async (error) => {
await stopAll();
console.error("", error);
process.exit(1);
});
.then()
.catch(async (error) => {
await stopAll()
console.error("", error)
process.exit(1)
})

process.on("SIGINT", async () => {
await stopAll();
process.exit(0);
});
await stopAll()
process.exit(0)
})

process.on("SIGTERM", async () => {
await stopAll();
process.exit(0);
});
await stopAll()
process.exit(0)
})
53 changes: 50 additions & 3 deletions tee-apps/sealed-bid-auction/src/blockchain/ViemIntentObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
decodeAbiParameters,
parseEventLogs,
trim,
type Log,
type WatchEventOnLogsParameter,
} from "viem";

Expand All @@ -16,24 +17,35 @@ import { serialize, WinstonLogger } from "../utils/WinstonLogger.ts";
import type { BlockchainClient } from "./BlockchainClient.ts";
import type { AuctionResult } from "../api/types.ts";

const HISTORICAL_BLOCK_CHUNK_SIZE = 100n;

export class ViemIntentObserver {
private logger: WinstonLogger;

constructor(
private readonly sourceChainClient: BlockchainClient,
private readonly sourceChainT1Erc7683ContractAddress: `0x${string}`,
private readonly auctionService: AuctionService,
private readonly apiServer: AuctionApiServer,
private readonly destinationChainId: number,
private readonly destinationChainT1Erc7683ContractAddress: `0x${string}`,
private readonly auctionPollingInterval: number = 500
private readonly auctionPollingInterval: number = 500,
private readonly fromBlock: bigint | null
) {
this.logger = new WinstonLogger(
`${ViemIntentObserver.name}[${this.sourceChainClient.publicClient.chain.name}]`
);
}

public start() {
public async start() {
if (this.fromBlock !== null) {
await this.fetchHistoricalLogs();
}

this.startWatching();
}

private startWatching() {
this.sourceChainClient.publicClient.watchEvent({
address: this.sourceChainT1Erc7683ContractAddress,
event: OPEN_INTENT_ABI_EVENT,
Expand All @@ -46,6 +58,41 @@ export class ViemIntentObserver {
);
}

private async fetchHistoricalLogs() {
if (this.fromBlock === null) return;

const currentBlock = await this.sourceChainClient.publicClient.getBlockNumber();
this.logger.info(
`Fetching historical logs from block ${this.fromBlock} to ${currentBlock}`
);

let fromBlock = this.fromBlock;

while (fromBlock <= currentBlock) {
const toBlock = fromBlock + HISTORICAL_BLOCK_CHUNK_SIZE - 1n > currentBlock
? currentBlock
: fromBlock + HISTORICAL_BLOCK_CHUNK_SIZE - 1n;

this.logger.info(`Fetching logs from block ${fromBlock} to ${toBlock}`);

const logs = await this.sourceChainClient.publicClient.getLogs({
address: this.sourceChainT1Erc7683ContractAddress,
event: OPEN_INTENT_ABI_EVENT,
fromBlock,
toBlock,
});

if (logs.length > 0) {
this.logger.info(`Found ${logs.length} historical logs in blocks ${fromBlock}-${toBlock}`);
await this.processIntentLogs(logs as unknown as WatchEventOnLogsParameter);
}

fromBlock = toBlock + 1n;
}

this.logger.info(`Finished fetching historical logs, caught up to block ${currentBlock}`);
}

private async processIntentLogs(logs: WatchEventOnLogsParameter) {
this.logger.info("Intent was Open-ed!");

Expand Down