Skip to content

Commit 51662ad

Browse files
committed
add wormhole
1 parent 3b7a80b commit 51662ad

File tree

12 files changed

+552
-42
lines changed

12 files changed

+552
-42
lines changed

.github/workflows/deploy.yml

+27-27
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,34 @@ name: Deploy
22

33
on:
44
push:
5-
branches: [ master ]
6-
5+
branches: [master]
6+
77
jobs:
88
deploy:
99
runs-on: ubuntu-latest
1010
steps:
11-
- uses: actions/checkout@v2
12-
- name: Get Node.js
13-
uses: actions/setup-node@v1
14-
with:
15-
node-version: '16'
16-
- run: npm ci
17-
- name: Type Check
18-
run: npm run ts
19-
- name: Deploy infrastructure stack
20-
run: npm run deploy:prod
21-
env:
22-
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
23-
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
24-
PSQL_URL: ${{ secrets.PSQL_URL }}
25-
PSQL_USERNAME: ${{ secrets.PSQL_USERNAME }}
26-
PSQL_PW: ${{ secrets.PSQL_PW }}
27-
BSC_RPC: ${{ secrets.BSC_RPC }}
28-
CELO_RPC: ${{ secrets.CELO_RPC }}
29-
ETHEREUM_RPC: ${{ secrets.ETHEREUM_RPC }}
30-
OPTIMISM_RPC: ${{ secrets.OPTIMISM_RPC }}
31-
AURORA_RPC: ${{ secrets.AURORA_RPC }}
32-
ARBITRUM_RPC: ${{ secrets.ARBITRUM_RPC }}
33-
SOLANA_RPC: ${{ secrets.SOLANA_RPC }}
34-
RSK_ARCHIVAL_RPC: ${{ secrets.RSK_ARCHIVAL_RPC }}
35-
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
11+
- uses: actions/checkout@v2
12+
- name: Get Node.js
13+
uses: actions/setup-node@v1
14+
with:
15+
node-version: "16"
16+
- run: npm ci
17+
- name: Type Check
18+
run: npm run ts
19+
- name: Deploy infrastructure stack
20+
run: npm run deploy:prod
21+
env:
22+
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
23+
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
24+
PSQL_URL: ${{ secrets.PSQL_URL }}
25+
PSQL_USERNAME: ${{ secrets.PSQL_USERNAME }}
26+
PSQL_PW: ${{ secrets.PSQL_PW }}
27+
BSC_RPC: ${{ secrets.BSC_RPC }}
28+
CELO_RPC: ${{ secrets.CELO_RPC }}
29+
ETHEREUM_RPC: ${{ secrets.ETHEREUM_RPC }}
30+
OPTIMISM_RPC: ${{ secrets.OPTIMISM_RPC }}
31+
AURORA_RPC: ${{ secrets.AURORA_RPC }}
32+
ARBITRUM_RPC: ${{ secrets.ARBITRUM_RPC }}
33+
RSK_ARCHIVAL_RPC: ${{ secrets.RSK_ARCHIVAL_RPC }}
34+
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
35+
ALLIUM_API_KEY: ${{ secrets.ALLIUM_API_KEY }}

package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"axios": "^0.21.0",
3636
"axios-rate-limit": "^1.3.0",
3737
"bignumber.js": "^9.0.1",
38+
"dayjs": "^1.11.13",
3839
"dotenv": "^8.2.0",
3940
"ethers": "^5",
4041
"graphql": "^16.0.0",

serverless.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ provider:
6666
OPTIMISM_RPC: ${env:OPTIMISM_RPC}
6767
AURORA_RPC: ${env:AURORA_RPC}
6868
ARBITRUM_RPC: ${env:ARBITRUM_RPC}
69-
SOLANA_RPC: ${env:SOLANA_RPC}
7069
RSK_ARCHIVAL_RPC: ${env:RSK_ARCHIVAL_RPC}
7170
DISCORD_WEBHOOK: ${env:DISCORD_WEBHOOK}
71+
ALLIUM_API_KEY: ${env:ALLIUM_API_KEY}
7272

7373
functions:
7474
bridgeDayStats:
@@ -177,6 +177,12 @@ functions:
177177
- http:
178178
path: netflows/{period}
179179
method: get
180+
runWormhole:
181+
handler: src/handlers/runWormhole.default
182+
timeout: 900
183+
events:
184+
- schedule: cron(0 * * * ? *)
185+
180186
resources:
181187
# CORS for api gateway errors
182188
- ${file(resources/api-gateway-errors.yml)}

src/adapters/index.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ import fastbtc from "./rootstock-fastbtc-bridge";
6969
import crowdswap from "./crowdswap";
7070
import mint from "./mint";
7171
import suibridge from "./suibridge";
72-
import retrobridge from "./retrobridge"
73-
import layerswap from "./layerswap"
72+
import retrobridge from "./retrobridge";
73+
import layerswap from "./layerswap";
7474
import hyperlane from "./hyperlane";
75+
import wormhole from "./wormhole";
7576

7677
export default {
7778
polygon,
@@ -147,6 +148,7 @@ export default {
147148
retrobridge,
148149
layerswap,
149150
hyperlane,
151+
wormhole,
150152
} as {
151153
[bridge: string]: BridgeAdapter | AsyncBridgeAdapter;
152154
};

src/adapters/wormhole/index.ts

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import dayjs from "dayjs";
2+
import { queryAllium } from "../../helpers/allium";
3+
4+
type WormholeBridgeEvent = {
5+
block_timestamp: string;
6+
transaction_hash: string;
7+
token_transfer_from_address: string;
8+
token_transfer_to_address: string;
9+
token_address: string;
10+
token_usd_amount: string;
11+
token_amount: string;
12+
source_chain: string;
13+
destination_chain: string;
14+
};
15+
16+
const chains = [
17+
"ethereum",
18+
"avalanche",
19+
"avax",
20+
"bsc",
21+
"polygon",
22+
"arbitrum",
23+
"optimism",
24+
"base",
25+
"zksync",
26+
"scroll",
27+
"aptos",
28+
"sui",
29+
"solana",
30+
"sei",
31+
"mantle",
32+
"fantom",
33+
"injective",
34+
"moonbeam",
35+
"oasis",
36+
"celo",
37+
"kaia",
38+
"near",
39+
"algorand",
40+
"terra",
41+
"terra classic",
42+
"karura",
43+
"acala",
44+
];
45+
46+
export const chainNameMapping: { [key: string]: string } = {
47+
ethereum: "Ethereum",
48+
avalanche: "Avalanche",
49+
avax: "Avalanche",
50+
polygon: "Polygon",
51+
arbitrum: "Arbitrum",
52+
optimism: "Optimism",
53+
fantom: "Fantom",
54+
base: "Base",
55+
solana: "Solana",
56+
sui: "Sui",
57+
aptos: "Aptos",
58+
celo: "Celo",
59+
mantle: "Mantle",
60+
scroll: "Scroll",
61+
algorand: "Algorand",
62+
sei: "Sei",
63+
moonbeam: "Moonbeam",
64+
injective: "Injective",
65+
kaia: "Kaia",
66+
oasis: "Oasis",
67+
BNB_Smart_Chain: "BSC",
68+
bnb_smart_chain: "BSC",
69+
terra: "Terra Classic",
70+
terra2: "Terra",
71+
"terra classic": "Terra Classic",
72+
near: "Near",
73+
};
74+
75+
export function normalizeChainName(chainName: string): string {
76+
const lowercaseChain = chainName.toLowerCase();
77+
78+
const mapping = chainNameMapping[lowercaseChain] || chainNameMapping[chainName];
79+
80+
if (mapping) {
81+
return mapping?.toLowerCase();
82+
}
83+
84+
return chainName?.toLowerCase();
85+
}
86+
87+
export const fetchWormholeEvents = async (
88+
fromTimestamp: number,
89+
toTimestamp: number
90+
): Promise<WormholeBridgeEvent[]> => {
91+
let allResults: WormholeBridgeEvent[] = [];
92+
let currentTimestamp = fromTimestamp;
93+
const BATCH_SIZE = 10000;
94+
95+
while (currentTimestamp < toTimestamp) {
96+
const result = await queryAllium(`
97+
select
98+
BLOCK_TIMESTAMP,
99+
TOKEN_TRANSFER_FROM_ADDRESS,
100+
TOKEN_TRANSFER_TO_ADDRESS,
101+
TOKEN_ADDRESS,
102+
TOKEN_USD_AMOUNT,
103+
TOKEN_AMOUNT,
104+
SOURCE_CHAIN,
105+
DESTINATION_CHAIN,
106+
UNIQUE_ID AS transaction_hash
107+
from org_db__defillama.default.wormhole_token_transfers
108+
where
109+
block_timestamp BETWEEN TO_TIMESTAMP_NTZ(${currentTimestamp}) AND TO_TIMESTAMP_NTZ(${toTimestamp})
110+
and status != 'REFUNDED'
111+
order by block_timestamp
112+
limit ${BATCH_SIZE};
113+
`);
114+
115+
if (result.length === 0) break;
116+
117+
const normalizedBatch = result.map((row: any) => ({
118+
...row,
119+
block_timestamp: dayjs(row.block_timestamp).unix(),
120+
}));
121+
122+
allResults = [...allResults, ...normalizedBatch];
123+
console.log(`Fetched ${allResults.length} Wormhole events.`);
124+
125+
currentTimestamp = normalizedBatch[normalizedBatch.length - 1].block_timestamp + 1;
126+
127+
if (result.length < BATCH_SIZE) break;
128+
}
129+
130+
return allResults;
131+
};
132+
133+
const adapter = chains.reduce((acc: any, chain: string) => {
134+
acc[chain] = true;
135+
return acc;
136+
}, {});
137+
138+
export default adapter;

src/data/bridgeNetworkData.ts

+40-3
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ export default [
122122
// avalanche: "avax",
123123
// },
124124
// },
125-
126125

127126
{
128127
id: 10,
@@ -1514,7 +1513,7 @@ export default [
15141513
bridgeDbName: "retrobridge",
15151514
iconLink: "icons:retrobridge",
15161515
largeTxThreshold: 10000,
1517-
url: 'https://retrobridge.io/',
1516+
url: "https://retrobridge.io/",
15181517
chains: [
15191518
"Ethereum",
15201519
"Arbitrum",
@@ -1573,7 +1572,7 @@ export default [
15731572
"Linea",
15741573
"Blast",
15751574
"Scroll",
1576-
"BSC",
1575+
"BSC",
15771576
"X Layer",
15781577
"Taiko",
15791578
"ZKsync Era",
@@ -1689,4 +1688,42 @@ export default [
16891688
avalanche: "avax",
16901689
},
16911690
},
1691+
{
1692+
id: 77,
1693+
displayName: "Wormhole",
1694+
bridgeDbName: "wormhole",
1695+
iconLink: "icons:portal",
1696+
largeTxThreshold: 10000,
1697+
url: "https://portalbridge.com/",
1698+
chains: [
1699+
"Ethereum",
1700+
"Polygon",
1701+
"Fantom",
1702+
"Avalanche",
1703+
"Aurora",
1704+
"Celo",
1705+
"Klaytn",
1706+
"BSC",
1707+
"Moonbeam",
1708+
"Optimism",
1709+
"Arbitrum",
1710+
"Base",
1711+
"Solana",
1712+
"Near",
1713+
"Aptos",
1714+
"Sui",
1715+
"Sei",
1716+
"Karura",
1717+
"Acala",
1718+
"Algorand",
1719+
"Terra",
1720+
"Terra Classic",
1721+
"Oasis",
1722+
"Celo",
1723+
"Kaia",
1724+
],
1725+
chainMapping: {
1726+
avalanche: "avax",
1727+
},
1728+
},
16921729
] as BridgeNetwork[];

0 commit comments

Comments
 (0)