You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Updated Supabase setup instructions to match current UI, added --env-file=.env to npm scripts, and clarified that RLS policies are the only manual database step required. Restructured implementation sections under a new 'Build the Bot' heading with numbered Steps for better flow. Fixed rate limiting timeouts to 250ms, updated ngrok documentation to note account requirement, and added it to prerequisites.
Copy file name to clipboardExpand all lines: evm/build-a-top-holders-tracker-bot.mdx
+41-57Lines changed: 41 additions & 57 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,6 +29,7 @@ Before you begin, ensure you have:
29
29
-**Sim API Key** - [Get your API key](https://sim.dune.com)
30
30
-**Telegram Bot Token** - Create one via [@BotFather](https://t.me/botfather)
31
31
-**Supabase Account** - [Create a free account](https://supabase.com)
32
+
-**ngrok Account** - [Create a free account](https://dashboard.ngrok.com) for local development
32
33
33
34
## Features
34
35
@@ -61,10 +62,12 @@ Let's initialize the project.
61
62
</Step>
62
63
63
64
<Steptitle="Set Up Supabase">
64
-
1. Go to [supabase.com/dashboard](https://supabase.com/dashboard) and create a new project
65
-
2. Once created, go to **Project Settings** → **Database**
66
-
3. Scroll to **Connection string** and select the **URI** tab
67
-
4. Copy the **Transaction pooler** connection string (uses port `6543`)
65
+
1. Go to [supabase.com/dashboard](https://supabase.com/dashboard) and click **Create a new project**
66
+
2. Fill in your project details (project name, database password, region) and click **Create new project**
67
+
3. Once created, click **Connect** in the top navigation bar
68
+
4. Select the **Connection string** tab, then choose type **URI**
69
+
5. Select **Transaction pooler** and copy the connection string
70
+
6. Replace `[YOUR-PASSWORD]` with your [URL-encoded](https://www.urlencoder.org/) database password
68
71
69
72
<Note>
70
73
The Transaction pooler connection is recommended for serverless deployments like Vercel.
@@ -93,8 +96,8 @@ Let's initialize the project.
93
96
{
94
97
"type": "module",
95
98
"scripts": {
96
-
"dev": "node index.js",
97
-
"start": "node index.js"
99
+
"dev": "node --env-file=.env index.js",
100
+
"start": "node --env-file=.env index.js"
98
101
}
99
102
}
100
103
```
@@ -185,46 +188,21 @@ Let's initialize the project.
185
188
```
186
189
</Step>
187
190
188
-
<Step title="Create Tables and Enable Row Level Security">
189
-
In your Supabase dashboard, go to **SQL Editor** and run:
191
+
<Step title="Enable Row Level Security">
192
+
The application creates tables automatically on startup, but you need to enable Row Level Security (RLS) policies in the Supabase dashboard. Go to **SQL Editor** and run:
190
193
191
194
```sql expandable
192
-
--============================================
193
-
--1.CREATETABLES (Optional - app creates these automatically)
194
-
--============================================
195
-
196
-
CREATETABLEIFNOTEXISTStop_holders (
197
-
id SERIALPRIMARYKEY,
198
-
token_address TEXT,
199
-
chain_id INTEGER,
200
-
symbol TEXT,
201
-
blockchain TEXT,
202
-
holders_json TEXT,
203
-
UNIQUE(token_address, chain_id)
204
-
);
205
-
206
-
CREATETABLEIFNOTEXISTSsubscribers (
207
-
chat_id TEXTPRIMARYKEY,
208
-
subscribed_at TEXT
209
-
);
210
-
211
-
CREATETABLEIFNOTEXISTSwebhooks (
212
-
id TEXTPRIMARYKEY,
213
-
token_address TEXT,
214
-
chain_id INTEGER,
215
-
active INTEGERDEFAULT1
216
-
);
217
195
218
196
--============================================
219
-
--2.ENABLEROWLEVELSECURITY (Required)
197
+
--1.ENABLEROWLEVELSECURITY (Required)
220
198
--============================================
221
199
222
200
ALTERTABLE top_holders ENABLEROWLEVELSECURITY;
223
201
ALTERTABLE subscribers ENABLEROWLEVELSECURITY;
224
202
ALTERTABLE webhooks ENABLEROWLEVELSECURITY;
225
203
226
204
--============================================
227
-
--3.CREATEPERMISSIVEPOLICIES (Required)
205
+
--2.CREATEPERMISSIVEPOLICIES (Required)
228
206
--============================================
229
207
230
208
-- Drop existing policies if they exist (prevents errors on re-run)
@@ -243,7 +221,7 @@ CREATE POLICY "Allow all operations on webhooks" ON webhooks
243
221
FORALLUSING (true) WITHCHECK (true);
244
222
245
223
--============================================
246
-
--4.VERIFYSETUP (Run to check everything)
224
+
--3.VERIFYSETUP (Run to check everything)
247
225
--============================================
248
226
249
227
SELECT
@@ -254,13 +232,17 @@ WHERE schemaname = 'public'
254
232
AND tablename IN ('top_holders', 'subscribers', 'webhooks');
255
233
```
256
234
257
-
This creates three tables: `top_holders` for storing token holder data, `subscribers` for Telegram chat IDs, and `webhooks` for tracking active subscriptions. The RLS policies allow your server full access while keeping the database secure.
235
+
These RLS policies allow your server full access while keeping the database secure.
258
236
</Step>
259
237
</Steps>
260
238
261
-
## Get Top ERC20 Tokens
239
+
## Build the Bot
262
240
263
-
We need a list of popular tokens to monitor. Create a file called `tokens.csv` in your project root with the following content:
241
+
With the project set up, we'll now implement the core functionality: loading token data, fetching top holders from Sim's Token Holders API, setting up webhook subscriptions, and wiring everything to Telegram.
242
+
243
+
<Steps>
244
+
<Step title="Get Top ERC20 Tokens">
245
+
We need a list of popular tokens to monitor. Create a file called `tokens.csv` in your project root with the following content:
If developing locally, use ngrok to make your localhost accessible:
749
+
If developing locally, you can expose a port to the public internet so that Sim Subscriptions can call it. [ngrok](https://ngrok.com) is a utility that helps with that. You need an account on [dashboard.ngrok.com](https://dashboard.ngrok.com) to use it.
0 commit comments