From 8186963ab8a5e91b1a1c51cd1dc0f81fa6f7fa86 Mon Sep 17 00:00:00 2001
From: hzhu <hz@henryzhu.me>
Date: Tue, 31 Dec 2024 21:50:22 -0800
Subject: [PATCH] feat: worldchain support

---
 README.md               | 13 ++++----
 src/constants.ts        |  2 ++
 src/index.ts            |  2 ++
 src/tests/index.test.ts | 67 +++++++++++++++++++++++++++++++++++++++--
 src/types.ts            |  4 ++-
 src/utils/index.ts      |  2 ++
 6 files changed, 80 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 62972e3..8c0e039 100644
--- a/README.md
+++ b/README.md
@@ -86,6 +86,12 @@
     </td>
   </tr>
   <tr>
+    <td style="width:100px; text-align:center;">
+      <div align="center">
+        <img alt="Worldchain" src="https://cdn.prod.website-files.com/6503306c491d20f69e484470/6718ce22ee5879d832765fd6_66ced64f18a10922ffcff77d_65d8bce782514cfb6c149b7a_1VQdZPHJ_400x400.webp" width="22"/>
+        <br>Worldchain
+      </div>
+    </td>
     <td style="width:100px; text-align:center;">
       <div align="center">
         <img alt="coming soon" src="https://i.imgur.com/CexTjqF.png" width="22"/>
@@ -116,12 +122,7 @@
         <br>🔜
       </div>
     </td>    
-    <td style="width:100px; text-align:center;">
-      <div align="center">
-        <img alt="coming soon" src="https://uc0b21458bb164b77e02b55e693f.previews.dropboxusercontent.com/p/thumb/ACd46XAdDQOjnDUQFKFEF15nMyLugKxfdnezVxHzCDAGt4bVB8l6AJVJB83hl1gSLMXlMtGzODSzMu-HaX-B5fzDVqvAcLTidJitmhGWq8qUjnLMAXE7hwYZJvU9QcKmwdJD9Qb9QyXzB-eGceNuj0b_IWLWL3vrQZguOjJWdMm9rT68SpLT7nG13gnxZxoXuCV5myYxOYVQ5zBx6DchblRIzFzeEpxuI4ciaH9phUCbP_4M5cV1aqSDBtwfWgbMHzTJ5nukSPY4-1hg2irDAFYgclLXV-pw_jfKmZgqKfW7HizolfD5-Gb1EL10Os2dfsurNu0FTqLrxYJrTZ7Qhzxzr1hwI9-m1Qo--3R2AezSNYgv4YGBy33sDvWhNgy-Xn8K1MhNtG8HMInuEYkaKv6XtVDJssG8wEbW1hDOfmqpaV2SMuWwPehX0Ry4dvJ6dN7axGNBU-Xcorl52AWan5C3727K9RaifMl2TAFvunoCNxtFghRjNpYuiV3Q9IBXd--O4Cca8K07bloVSH-ectkbJIp_tT4dI_yBL32qnG26fL4a1sGzKpcrZZCQsyq0fwVWll2yzru3k71EQRoIjvnuFcyvGOScYrnJOWmFp7d2eABwlG4-T3U8ZYvjn5NY2UYo9kUeCY-Ev--2WExLqfCKga_19tA6FGk8CMhuf_gvAE0hfsgmi3PYiqTjj1mviJIc_o3Mkx6eLMIXHHaTIxqjvP_V219UiimJgNwfreCM7wkIpkGW0BuRyBzAjfgW3C2hB2cJGF8OhBn-cKnrNEU1WSC-TVKrcPwlDH3ticPQOD7hXucL110aBmxY_KacBPI2Br4HioXKYTWsTfrRnVbjB0KpE0RWtstyryG-pMq-vA/p.png" width="22"/>
-        <br>🔜
-      </div>
-    </td>
+    
   </tr>
 </table>
 
diff --git a/src/constants.ts b/src/constants.ts
index 42a9b19..0d9d34d 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -11,6 +11,7 @@ import {
   arbitrum,
   optimism,
   avalanche,
+  worldchain,
 } from "viem/chains";
 import type { SupportedChainId } from "./types";
 
@@ -59,6 +60,7 @@ export const NATIVE_SYMBOL_BY_CHAIN_ID: { [key in SupportedChainId]: string } =
     [optimism.id]: optimism.nativeCurrency.symbol,
     [arbitrum.id]: arbitrum.nativeCurrency.symbol,
     [avalanche.id]: avalanche.nativeCurrency.symbol,
+    [worldchain.id]: worldchain.nativeCurrency.symbol,
   };
 
 export const NATIVE_TOKEN_ADDRESS = `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE`;
diff --git a/src/index.ts b/src/index.ts
index 20e7111..7a10fec 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -189,6 +189,7 @@ export async function parseSwap({
         { symbol: "", amount: "", address: "" }
       );
 
+    console.log("B");
     return {
       tokenIn: {
         symbol: NATIVE_SYMBOL_BY_CHAIN_ID[chainId],
@@ -208,6 +209,7 @@ export async function parseSwap({
   }
   /* v8 ignore stop */
 
+  console.log("A");
   return {
     tokenIn: {
       symbol: input.symbol,
diff --git a/src/tests/index.test.ts b/src/tests/index.test.ts
index 64eb131..d1be1cc 100644
--- a/src/tests/index.test.ts
+++ b/src/tests/index.test.ts
@@ -16,6 +16,7 @@ import {
   arbitrum,
   optimism,
   mantle,
+  worldchain,
 } from "viem/chains";
 import { test, expect } from "vitest";
 import { parseSwap } from "../index";
@@ -642,9 +643,7 @@ test("parse a gasless swap on Optimism (USDC for OP) for execute", async () => {
   });
 });
 
-// TODO: remove skip or test different tx hash, RPC provider cannot fetch this transaction hash.
-// https://bscscan.com/tx/0xdda12da1e32c3320082355c985d6f2c6559169989de51e3cc83123395516c057
-test.skip("parse a swap on BNB Chain (ETH for USDC) for execute", async () => {
+test("parse a swap on BNB Chain (ETH for USDC) for execute", async () => {
   const publicClient = createPublicClient({
     chain: optimism,
     transport: http(
@@ -1233,3 +1232,65 @@ test("parse a swap on Mode (ezETH for MODE) with SettlerMetaTxn", async () => {
     },
   });
 });
+
+// https://worldscan.org/tx/0xc6b6a747910ff6ff6262f3a7067db5d48fb83d774f3556bee7654b020f0e875d
+test("parse a swap on Worldchain (USDC.e for WLD) with Settler", async () => {
+  const publicClient = createPublicClient({
+    chain: worldchain,
+    transport: http(
+      `https://worldchain-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`
+    ),
+  }) as PublicClient<Transport, Chain>;
+
+  const transactionHash = `0xc6b6a747910ff6ff6262f3a7067db5d48fb83d774f3556bee7654b020f0e875d`;
+
+  const result = await parseSwap({
+    publicClient,
+    transactionHash,
+  });
+
+  expect(result).toEqual({
+    tokenIn: {
+      symbol: "USDC.e",
+      amount: "0.8",
+      address: "0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",
+    },
+    tokenOut: {
+      symbol: "WLD",
+      amount: "0.382406307673532742",
+      address: "0x2cFc85d8E48F8EAB294be644d9E25C3030863003",
+    },
+  });
+});
+
+// https://worldscan.org/tx/0x4c095630a5b87cd2c04fcc2cf08940ed8251f6d451efc61e1e90b42775d4f051
+test("parse a swap on Worldchain (ETH for USDC.e) with Settler", async () => {
+  const publicClient = createPublicClient({
+    chain: worldchain,
+    transport: http(
+      `https://worldchain-mainnet.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`
+    ),
+  }) as PublicClient<Transport, Chain>;
+
+  const transactionHash = `0x4c095630a5b87cd2c04fcc2cf08940ed8251f6d451efc61e1e90b42775d4f051`;
+
+  const result = await parseSwap({
+    publicClient,
+    transactionHash,
+  });
+
+  console.log(result, "<--result");
+
+  expect(result).toEqual({
+    tokenIn: {
+      symbol: "ETH",
+      amount: "0.001",
+      address: NATIVE_TOKEN_ADDRESS,
+    },
+    tokenOut: {
+      symbol: "USDC.e",
+      amount: "3.332454",
+      address: "0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",
+    },
+  });
+});
diff --git a/src/types.ts b/src/types.ts
index 7f7a2b1..775f46f 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -11,6 +11,7 @@ import {
   arbitrum,
   optimism,
   avalanche,
+  worldchain,
 } from "viem/chains";
 
 import type {
@@ -35,7 +36,8 @@ export type SupportedChainId =
   | typeof polygon.id
   | typeof arbitrum.id
   | typeof optimism.id
-  | typeof avalanche.id;
+  | typeof avalanche.id
+  | typeof worldchain.id;
 
 export interface EnrichLogsArgs {
   transactionReceipt: TransactionReceipt;
diff --git a/src/utils/index.ts b/src/utils/index.ts
index f549597..a787244 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -12,6 +12,7 @@ import {
   arbitrum,
   optimism,
   avalanche,
+  worldchain,
 } from "viem/chains";
 import { NATIVE_SYMBOL_BY_CHAIN_ID, NATIVE_TOKEN_ADDRESS } from "../constants";
 import type { Address } from "viem";
@@ -38,6 +39,7 @@ export function isChainIdSupported(
     arbitrum.id,
     optimism.id,
     avalanche.id,
+    worldchain.id,
   ];
   return supportedChainIds.includes(chainId);
 }