Repository: DefiLlama/bridges-server
Pull request #368: Everclear Adapter
Author: login: 0xanedi
Created: 2025-05-06T17:44:47Z | Merged: 2025-05-17T16:38:00Z

This adapter tracks dailyVolume for https://www.everclear.org/


Diff:
diff --git a/package-lock.json b/package-lock.json
index 3ad96780..40b55376 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
         "@aws-sdk/client-s3": "^3.749.0",
         "@aws-sdk/client-sts": "^3.749.0",
         "@aws-sdk/credential-providers": "^3.749.0",
-        "@defillama/sdk": "^5.0.119",
+        "@defillama/sdk": "^5.0.137",
         "@fastify/cors": "^9.0.1",
         "@graphql-typed-document-node/core": "^3.2.0",
         "@solana/web3.js": "^1.87.3",
@@ -6588,9 +6588,10 @@
       }
     },
     "node_modules/@defillama/sdk": {
-      "version": "5.0.119",
-      "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-5.0.119.tgz",
-      "integrity": "sha512-panCbRH7/AM9IOEdtXvpRcd4Y4ZAvOC8ulXQlQKdE392CP6n0WS1h7JT4sUzwxVqu2AC7/CfXbyPQ6BZpSjc/Q==",
+      "version": "5.0.137",
+      "resolved": "https://registry.npmjs.org/@defillama/sdk/-/sdk-5.0.137.tgz",
+      "integrity": "sha512-qeLgEy8fuQsE2HOojyQSHCQ3fgIJmNZwX7Nqc5Vs9QEKrq3LBGPxM/MZPoBuIm7GiPM57rJGRf6tE0u/oR2KQQ==",
+      "license": "ISC",
       "dependencies": {
         "@aws-sdk/client-s3": "^3.400.0",
         "@elastic/elasticsearch": "^8.13.1",
diff --git a/package.json b/package.json
index 240777ca..49915039 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,6 @@
     "build": "vite build",
     "start": "node ./dist/index.js",
     "start:dev": "node ./dist/index.js",
-
     "start:cron": "node ./dist/startCron.js"
   },
   "devDependencies": {
@@ -38,7 +37,7 @@
     "@aws-sdk/client-s3": "^3.749.0",
     "@aws-sdk/client-sts": "^3.749.0",
     "@aws-sdk/credential-providers": "^3.749.0",
-    "@defillama/sdk": "^5.0.119",
+    "@defillama/sdk": "^5.0.137",
     "@fastify/cors": "^9.0.1",
     "@graphql-typed-document-node/core": "^3.2.0",
     "@solana/web3.js": "^1.87.3",
diff --git a/src/adapters/everclear/index.ts b/src/adapters/everclear/index.ts
new file mode 100644
index 00000000..6fe956df
--- /dev/null
+++ b/src/adapters/everclear/index.ts
@@ -0,0 +1,125 @@
+import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type";
+import { Chain } from "@defillama/sdk/build/general";
+import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
+import { ethers } from "ethers";
+
+const contractAddresses = {
+  //EverclearSpoke contract addresses for each chain
+  ethereum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"], 
+  optimism: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  bsc: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  unichain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  polygon: ["0x7189C59e245135696bFd2906b56607755F84F3fD"],
+  zksync: ["0x7F5e085981C93C579c865554B9b723B058AaE4D3"],
+  ronin: ["0xdCA40903E271Cc76AECd62dF8D6c19f3Ac873E64"],
+  base: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  apechain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  mode: ["0xeFa6Ac3F931620fD0449eC8c619f2A14A0A78E99"],
+  arbitrum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  avalanche: ["0x9aA2Ecad5C77dfcB4f34893993f313ec4a370460"],
+  zircuit: ["0xD0E86F280D26Be67A672d1bFC9bB70500adA76fe"],
+  linea: ["0xc24dC29774fD2c1c0c5FA31325Bb9cbC11D8b751"],
+  blast: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+  scroll: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  taiko: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+  sonic: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  berachain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  mantle: ["0xe0F010e465f15dcD42098dF9b99F1038c11B3056"],
+  ink: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+} as const;
+
+// Helper function to convert bytes32 to address
+function bytes32ToAddress(bytes32: string) {
+  return ethers.utils.getAddress('0x' + bytes32.slice(26));
+}
+
+// Deposit event (IntentAdded)
+const depositIntent: PartialContractEventParams = {
+  target: "",
+  topic: "IntentAdded(bytes32,bytes32,(bytes32,bytes32,bytes32,bytes32,uint24,uint32,uint64,uint48,uint48,uint256,uint32[],bytes))",
+  abi: [
+    "event IntentAdded(bytes32 indexed _intentId, bytes32 indexed _queueId, tuple(bytes32 initiator, bytes32 receiver, bytes32 inputAsset, bytes32 outputAsset, uint24 maxFee, uint32 origin, uint64 nonce, uint48 timestamp, uint48 ttl, uint256 amount, uint32[] destinations, bytes data) _intent)",
+  ],
+  logKeys: {
+    blockNumber: "blockNumber",
+    txHash: "transactionHash",
+  },
+  argKeys: {
+    amount: "_intent.amount",
+    from: "_intent.initiator",
+    token: "_intent.inputAsset",
+  },
+  argGetters: {
+    from: (logArgs: any) => bytes32ToAddress(logArgs._intent.initiator),
+    token: (logArgs: any) => bytes32ToAddress(logArgs._intent.inputAsset)
+  },
+  isDeposit: true,
+};
+
+// Withdrawal event (Settled)
+const withdrawalIntent: PartialContractEventParams = {
+  target: "",
+  topic: "Settled(bytes32,address,address,uint256)",
+  abi: [
+    "event Settled(bytes32 indexed _intentId, address _account, address _asset, uint256 _amount)",
+  ],
+  logKeys: {
+    blockNumber: "blockNumber",
+    txHash: "transactionHash",
+  },
+  argKeys: {
+    amount: "_amount",
+    to: "_account",
+    from: "_account",
+    token: "_asset",
+  },
+  isDeposit: false,
+};
+
+const constructParams = (chain: Chain) => {
+  const chainConfig = contractAddresses[chain as keyof typeof contractAddresses];
+
+  // Create event params for both deposit and withdrawal events for each contract address
+  const eventParams: PartialContractEventParams[] = [];
+  
+  // Add deposit (IntentAdded) events
+  chainConfig.forEach(address => {
+    eventParams.push({...depositIntent, target: address});
+  });
+  
+  // Add withdrawal (Settled) events
+  chainConfig.forEach(address => {
+    eventParams.push({...withdrawalIntent, target: address});
+  });
+
+  return async (fromBlock: number, toBlock: number) => {
+    console.log("Fetching Everclear bridge volume from block:", fromBlock, "to block:", toBlock)
+    return getTxDataFromEVMEventLogs("everclear", chain, fromBlock, toBlock, eventParams);
+  };
+};
+
+const adapter: BridgeAdapter = {
+  ethereum:  constructParams("ethereum"),
+  optimism:  constructParams("optimism"),
+  bsc:       constructParams("bsc"),
+  unichain:  constructParams("unichain"),
+  polygon:   constructParams("polygon"),
+  zksync:    constructParams("zksync"),
+  ronin:     constructParams("ronin"),
+  base:      constructParams("base"),
+  apechain:  constructParams("apechain"),
+  mode:      constructParams("mode"),
+  arbitrum:  constructParams("arbitrum"),
+  avalanche: constructParams("avalanche"),
+  zircuit:   constructParams("zircuit"),
+  linea:     constructParams("linea"),
+  blast:     constructParams("blast"),
+  scroll:    constructParams("scroll"),
+  taiko:     constructParams("taiko"),
+  sonic:     constructParams("sonic"),
+  berachain: constructParams("berachain"),
+  mantle:    constructParams("mantle"),
+  ink:       constructParams("ink"),
+};
+
+export default adapter;
\ No newline at end of file
diff --git a/src/adapters/index.ts b/src/adapters/index.ts
index 7f8ba027..b1655595 100644
--- a/src/adapters/index.ts
+++ b/src/adapters/index.ts
@@ -1,4 +1,5 @@
 import { BridgeAdapter, AsyncBridgeAdapter } from "../helpers/bridgeAdapter.type";
+import everclear from "./everclear";
 import polygon from "./polygon";
 import synapse from "./synapse";
 import hop from "./hop";
@@ -172,6 +173,7 @@ export default {
   train,
   assetchainbridge,
   fuel,
+  everclear,
   lighter,
   movement,
   intersoon,
diff --git a/src/data/bridgeNetworkData.ts b/src/data/bridgeNetworkData.ts
index 52394d47..3d31acac 100644
--- a/src/data/bridgeNetworkData.ts
+++ b/src/data/bridgeNetworkData.ts
@@ -2106,7 +2106,8 @@ export default [
     url: "https://bridge.movementnetwork.xyz/",
     chains: ["Ethereum", "Movement"],
     destinationChain: "Movement",
-  }, {
+  }, 
+  {
     id: 89,
     displayName: "Asset Chain Bridge",
     bridgeDbName: "assetchainbridge",
@@ -2125,4 +2126,35 @@ export default [
     url: "https://intersoon.soo.network",
     chains: ["Solana", "Ton"],
   },
+  {
+    id: 91,
+    displayName: "Everclear",
+    bridgeDbName: "everclear",
+    iconLink: "icons:everclear",
+    largeTxThreshold: 10000,
+    url:"https://explorer.everclear.org/",                  
+    chains: [
+      "Ethereum",
+      "Optimism",
+      "BSC",
+      "Unichain",
+      "Polygon",
+      "ZKsync Era",
+      "Ronin",
+      "Base",
+      "ApeChain",
+      "Mode",
+      "Arbitrum",
+      "Avalanche",
+      "Zircuit",
+      "Linea",
+      "Blast",
+      "Scroll",
+      "Taiko",
+      "Sonic",
+      "Berachain",
+      "Mantle",
+      "Ink",
+    ],
+  },
 ] as BridgeNetwork[];
diff --git a/tsconfig.json b/tsconfig.json
index 665331f5..6d4bfb9a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,7 +20,7 @@
     "noImplicitThis": false,
     "noUnusedLocals": false,
     "noUnusedParameters": true,
-    "lib": ["ES2019"],
+    "lib": ["ES2019", "DOM"],
     "outDir": ".webpack",
     "rootDir": "./src",
     "sourceMap": true


Reviews:
user: login: vrtnd
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-09T08:17:43Z
user: login: 0xanedi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T16:18:19Z
user: login: vrtnd
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-16T13:50:35Z
user: login: 0xanedi
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-16T14:25:20Z
user: login: vrtnd
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-17T16:37:20Z

Review comments:
diff_hunk: @@ -0,0 +1,85 @@
+import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type";
+import { Chain } from "@defillama/sdk/build/general";
+import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
+
+
+const contractAddresses = {
+  //EverclearSpoke contract addresses for each chain
+  ethereum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"], 
+  optimism: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  bsc: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  unichain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  polygon: ["0x7189C59e245135696bFd2906b56607755F84F3fD"],
+  zksync: ["0x7F5e085981C93C579c865554B9b723B058AaE4D3"],
+  ronin: ["0xdCA40903E271Cc76AECd62dF8d6c19f3Ac873E64"],
+  base: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  apechain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  mode: ["0xeFa6Ac3F931620fD0449eC8c619f2A14A0A78E99"],
+  arbitrum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  avalanche: ["0x9aA2Ecad5C77dfcB4f34893993f313ec4a370460"],
+  zircuit: ["0xD0E86F280D26Be67A672d1bFC9bB70500adA76fe"],
+  linea: ["0xc24dC29774fD2c1c0c5FA31325Bb9cbC11D8b751"],
+  blast: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+  scroll: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  taiko: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+} as const;
+
+
+const newIntent: PartialContractEventParams = {
+  target: "",
+  topic:
+    "Settled(bytes32,address,address,uint256)",
+  abi: [
+    "event Settled(bytes32 indexed _intentId, address _account, address _asset, uint256 _amount)",
+  ],
+  logKeys: {
+    blockNumber: "blockNumber",
+    txHash: "transactionHash",
+  },
+  argKeys: {
+    amount: "_amount",
+    to: "_account",
+    from: "_account",
+    token: "_asset",
+  },
+  isDeposit: true,
+};
+
+
+/*
+Withdrawal function is not needed for this use case.
path: src/adapters/everclear/index.ts
user: login: vrtnd
body: need to track withdrawals too, otherwise only half of the volume will be shown 
created_at: 2025-05-09T08:17:43Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,85 @@
+import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type";
+import { Chain } from "@defillama/sdk/build/general";
+import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
+
+
+const contractAddresses = {
+  //EverclearSpoke contract addresses for each chain
+  ethereum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"], 
+  optimism: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  bsc: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  unichain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  polygon: ["0x7189C59e245135696bFd2906b56607755F84F3fD"],
+  zksync: ["0x7F5e085981C93C579c865554B9b723B058AaE4D3"],
+  ronin: ["0xdCA40903E271Cc76AECd62dF8d6c19f3Ac873E64"],
+  base: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  apechain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  mode: ["0xeFa6Ac3F931620fD0449eC8c619f2A14A0A78E99"],
+  arbitrum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  avalanche: ["0x9aA2Ecad5C77dfcB4f34893993f313ec4a370460"],
+  zircuit: ["0xD0E86F280D26Be67A672d1bFC9bB70500adA76fe"],
+  linea: ["0xc24dC29774fD2c1c0c5FA31325Bb9cbC11D8b751"],
+  blast: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+  scroll: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  taiko: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+} as const;
+
+
+const newIntent: PartialContractEventParams = {
+  target: "",
+  topic:
+    "Settled(bytes32,address,address,uint256)",
+  abi: [
+    "event Settled(bytes32 indexed _intentId, address _account, address _asset, uint256 _amount)",
+  ],
+  logKeys: {
+    blockNumber: "blockNumber",
+    txHash: "transactionHash",
+  },
+  argKeys: {
+    amount: "_amount",
+    to: "_account",
+    from: "_account",
+    token: "_asset",
+  },
+  isDeposit: true,
+};
+
+
+/*
+Withdrawal function is not needed for this use case.
path: src/adapters/everclear/index.ts
user: login: 0xanedi
body: There’s no way to get deposits/withdrawals separately as that concept doesn’t apply directly to how our system works. Everything moving through the system is a `newIntent` and it nets against other orders - these intents then emit the event of `Settled` when they exit the system.
This means you’re tracking 100% of flow with `Settled`, so it should work fine.
created_at: 2025-05-12T16:18:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,85 @@
+import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type";
+import { Chain } from "@defillama/sdk/build/general";
+import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
+
+
+const contractAddresses = {
+  //EverclearSpoke contract addresses for each chain
+  ethereum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"], 
+  optimism: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  bsc: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  unichain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  polygon: ["0x7189C59e245135696bFd2906b56607755F84F3fD"],
+  zksync: ["0x7F5e085981C93C579c865554B9b723B058AaE4D3"],
+  ronin: ["0xdCA40903E271Cc76AECd62dF8d6c19f3Ac873E64"],
+  base: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  apechain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  mode: ["0xeFa6Ac3F931620fD0449eC8c619f2A14A0A78E99"],
+  arbitrum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  avalanche: ["0x9aA2Ecad5C77dfcB4f34893993f313ec4a370460"],
+  zircuit: ["0xD0E86F280D26Be67A672d1bFC9bB70500adA76fe"],
+  linea: ["0xc24dC29774fD2c1c0c5FA31325Bb9cbC11D8b751"],
+  blast: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+  scroll: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  taiko: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+} as const;
+
+
+const newIntent: PartialContractEventParams = {
+  target: "",
+  topic:
+    "Settled(bytes32,address,address,uint256)",
+  abi: [
+    "event Settled(bytes32 indexed _intentId, address _account, address _asset, uint256 _amount)",
+  ],
+  logKeys: {
+    blockNumber: "blockNumber",
+    txHash: "transactionHash",
+  },
+  argKeys: {
+    amount: "_amount",
+    to: "_account",
+    from: "_account",
+    token: "_asset",
+  },
+  isDeposit: true,
+};
+
+
+/*
+Withdrawal function is not needed for this use case.
path: src/adapters/everclear/index.ts
user: login: vrtnd
body: ![image](https://github.com/user-attachments/assets/26692429-1a0b-4339-98c4-e77e55394162)
we still need some events to be marked as withdrawals or chart will have only deposit side of the volume which is incorrect 

created_at: 2025-05-16T13:50:35Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,85 @@
+import { BridgeAdapter, PartialContractEventParams } from "../../helpers/bridgeAdapter.type";
+import { Chain } from "@defillama/sdk/build/general";
+import { getTxDataFromEVMEventLogs } from "../../helpers/processTransactions";
+
+
+const contractAddresses = {
+  //EverclearSpoke contract addresses for each chain
+  ethereum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"], 
+  optimism: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  bsc: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  unichain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  polygon: ["0x7189C59e245135696bFd2906b56607755F84F3fD"],
+  zksync: ["0x7F5e085981C93C579c865554B9b723B058AaE4D3"],
+  ronin: ["0xdCA40903E271Cc76AECd62dF8d6c19f3Ac873E64"],
+  base: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  apechain: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  mode: ["0xeFa6Ac3F931620fD0449eC8c619f2A14A0A78E99"],
+  arbitrum: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  avalanche: ["0x9aA2Ecad5C77dfcB4f34893993f313ec4a370460"],
+  zircuit: ["0xD0E86F280D26Be67A672d1bFC9bB70500adA76fe"],
+  linea: ["0xc24dC29774fD2c1c0c5FA31325Bb9cbC11D8b751"],
+  blast: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+  scroll: ["0xa05A3380889115bf313f1Db9d5f335157Be4D816"],
+  taiko: ["0x9ADA72CCbAfe94248aFaDE6B604D1bEAacc899A7"],
+} as const;
+
+
+const newIntent: PartialContractEventParams = {
+  target: "",
+  topic:
+    "Settled(bytes32,address,address,uint256)",
+  abi: [
+    "event Settled(bytes32 indexed _intentId, address _account, address _asset, uint256 _amount)",
+  ],
+  logKeys: {
+    blockNumber: "blockNumber",
+    txHash: "transactionHash",
+  },
+  argKeys: {
+    amount: "_amount",
+    to: "_account",
+    from: "_account",
+    token: "_asset",
+  },
+  isDeposit: true,
+};
+
+
+/*
+Withdrawal function is not needed for this use case.
path: src/adapters/everclear/index.ts
user: login: 0xanedi
body: Okay. A team member found a way to adapt it to match the requirement. It should work now.
created_at: 2025-05-16T14:25:20Z
author_association: CONTRIBUTOR

PR comments:
user: login: 0xanedi
created_at: 2025-05-07T20:37:50Z
body: @vrtnd Pushed changes to PR. Should be tracking properly now on all chains. Commented out chains with missing contract addresses.
author_association: CONTRIBUTOR
user: login: aryabhuptani
created_at: 2025-05-22T14:36:07Z
body: Hey @vrtnd - is there a reason why metrics aren't showing up in the UI despite this PR being merged several days ago? Happy to make any changes if something isn't working here!
author_association: CONTRIBUTOR