Across
Across is a bridge protocol, so the parser focuses on identifying BRIDGE_OUT and BRIDGE_IN actions from its on-chain events.
🧩 Files Involved in the Across Parser
src/lib/Across/
├── abis/SpokePool.json ← Only needed ABI fragments
├── contracts.ts ← Address + event signature map
├── parser.ts ← Logic to build actions from tx logs
└── index.ts ← Parser class exposed to the framework1. contracts.ts — Contract Definitions & Event Signatures
contracts.ts — Contract Definitions & Event SignaturesThis file defines which contracts Across uses on each chain, and how to identify the logs they emit.
export enum ACROSS_CONTRACTS {
SPOKE_POOL = "SPOKE_POOL"
}
export const acrossContracts: IProtocolContractDefinitions = {
[CHAIN_ID.ETHEREUM]: {
[ACROSS_CONTRACTS.SPOKE_POOL]: {
address: "0x...", // SpokePool address on Ethereum
listener: LISTEN_FOR_TRANSACTIONS.TO,
abi: SpokePoolABI,
events: {
FilledRelay: "FilledRelay(address,address,address,uint256,uint256,uint256,bool,bytes32)",
Deposited: "Deposited(address,address,address,uint256,uint256,uint256,bytes32)"
}
}
},
...
};Here we:
Define what contract to listen to (e.g.
SpokePool)Where to listen (
toorfromin tx)Which events (logs) we care about
2. parser.ts — Parsing the Logs into Actions
parser.ts — Parsing the Logs into Actionsexport const parseAcrossTx = (tx: ITransaction, helper: ProtocolHelper): ITransactionAction[] => {
const actions: ITransactionAction[] = [];
for (const log of tx.logs) {
const parsed = helper.parseLog(log);
if (!parsed) continue;
const { name, args } = parsed;
if (name === "FilledRelay") {
actions.push({
action: ACTION_ENUM.BRIDGE_IN,
chainId: tx.chainId,
from: args.originToken,
to: args.destinationToken,
amount: args.amount,
userAddress: args.recipient,
txHash: tx.hash,
timestamp: tx.timestamp
});
}
if (name === "Deposited") {
actions.push({
action: ACTION_ENUM.BRIDGE_OUT,
chainId: tx.chainId,
from: args.originToken,
to: args.destinationToken,
amount: args.amount,
userAddress: args.depositor,
txHash: tx.hash,
timestamp: tx.timestamp
});
}
}
return actions;
};🧠 Note:
It loops through logs, uses a helper to parse each log via ABI
Builds high-level
ITransactionActionobjectsEach action gets:
action,chainId,tokens,user,amount,timestamp
3. index.ts — The Parser Class
index.ts — The Parser Classexport default class Across implements IProtocolParserExport {
readonly protocolIdentifier = "across";
parseTransaction(tx: ITransaction): ITransactionAction[] {
const helper = new ProtocolHelper(acrossContracts, tx);
if (!helper.txToAnyContract()) return [];
return parseAcrossTx(tx, helper);
}
getProtocolContracts() {
return acrossContracts;
}
}This is the entry point used by the global parser map. It:
Uses
ProtocolHelperto check if the tx is related to AcrossIf yes, passes it to
parseAcrossTxReturns any
ITransactionActions it detects
Recap: How Across Parser Works
Contract Setup
Define SpokePool addresses and events in contracts.ts
Parsing Logic
Loop through logs and map to BRIDGE_IN / BRIDGE_OUT
Runtime Class
Implements IProtocolParserExport to plug into SDK
Output
Returns typed ITransactionAction[] used for OpenRep scoring
Last updated