Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ jobs:
- run:
name: Install jq
command: |
# Cypress image ships a Google Chrome apt source whose GPG key can expire
# and make `apt-get update` fail with NO_PUBKEY / exit 100 before jq installs.
rm -f /etc/apt/sources.list.d/google-chrome*.list /etc/apt/sources.list.d/*chrome*.list || true
apt-get update && apt-get install -y curl jq

# Clone secondary repo and run Playwright tests
Expand Down
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ VITE_SWAP_BUTTON_SWITCH="true"
VITE_PAYMASTER_URL="http://localhost:5050"
VITE_SENTRY_ENVIRONMENT="staging"
VITE_PULSE_NODE_URL="https://pulse.etherspot.io"
VITE_MOBULA_API_KEY="your_api_key_here"
1 change: 1 addition & 0 deletions .github/workflows/notifications.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Send Slack deployment notifications
continue-on-error: true
uses: arddluma/cloudflare-pages-slack-notification@v4
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
Expand Down
7 changes: 7 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Disable git operations during npm install to prevent issues in CI/CD environments
# This fixes the git config error during Cloudflare Pages deployment
unsafe-perm=true
ignore-scripts=false

# Configure git to use system config only
git-tag-version=false
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20
118 changes: 118 additions & 0 deletions Builders codes/fetch_builder_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
const https = require('https');
const fs = require('fs');
const lz4js = require('lz4js');

const builderAddress = '0x5e1d081488a5e746c1a13bf92103c1b9ee5962a2';
// 2026-01-12 is today. Let's check 12, 11, 10.
const dates = ['20260112', '20260111', '20260110', '20260109'];

async function fetchAndProcess(date) {
const url = `https://stats-data.hyperliquid.xyz/Mainnet/builder_fills/${builderAddress}/${date}.csv.lz4`;
// console.log(`Fetching ${url}...`);

return new Promise((resolve) => {
https.get(url, (res) => {
if (res.statusCode !== 200) {
// console.log(`No data for ${date} (Status: ${res.statusCode})`);
resolve(null);
return;
}

const chunks = [];
res.on('data', chunk => chunks.push(chunk));
res.on('end', () => {
const buffer = Buffer.concat(chunks);
try {
const decompressed = lz4js.decompress(buffer);
const csv = Buffer.from(decompressed).toString('utf8');
resolve({ date, csv });
} catch (e) {
console.error(`Error decompressing ${date}:`, e.message);
resolve(null);
}
});
res.on('error', () => resolve(null));
});
});
}

function parseCSV(csv) {
const lines = csv.trim().split('\n');
const headers = lines[0].split(',');
const data = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
const row = {};
headers.forEach((h, index) => {
row[h] = values[index];
});
data.push(row);
}
return data;
}

async function main() {
const results = [];
for (const date of dates) {
const result = await fetchAndProcess(date);
if (result) {
results.push(result);
}
}

if (results.length === 0) {
console.log("No builder referral data found for the last 3-4 days.");
return;
}

console.log("Builder Code Referrals (Last available data):");
let totalFees = 0;
const uniqueUsers = new Set();
const dailyStats = {};

results.forEach(({ date, csv }) => {
const records = parseCSV(csv);
let dailyFees = 0;
let dailyUsers = new Set();

records.forEach(r => {
const fee = parseFloat(r.builder_fee || 0);
dailyFees += fee;
totalFees += fee;
if (r.user) {
uniqueUsers.add(r.user);
dailyUsers.add(r.user);
}
});

dailyStats[date] = {
fees: dailyFees,
users: dailyUsers.size,
transactions: records.length
};
});

console.table(dailyStats);
console.log(`\nTotal Builder Fees: ${totalFees.toFixed(6)} USDC`);
console.log(`Total Unique Users: ${uniqueUsers.size}`);

console.log("\nUser Breakdown:");
const userBreakdown = {};
results.forEach(({ csv }) => {
const records = parseCSV(csv);
records.forEach(r => {
if (r.user) {
if (!userBreakdown[r.user]) {
userBreakdown[r.user] = 0;
}
userBreakdown[r.user] += parseFloat(r.builder_fee || 0);
}
});
});

Object.entries(userBreakdown).forEach(([user, fee]) => {
console.log(`User: ${user}, Total Fee: ${fee.toFixed(6)} USDC`);
});
}

main();
14 changes: 14 additions & 0 deletions Builders codes/node_modules/.package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Builders codes/node_modules/lz4js/.eslintrc

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Builders codes/node_modules/lz4js/.npmignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Builders codes/node_modules/lz4js/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions Builders codes/node_modules/lz4js/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading