Suivi du portefeuille
Surveillez facilement une liste d'adresses de portefeuilles sur Solana et Ethereum grâce à Quicknode Streams. Mettez à jour la liste des portefeuilles via une interface utilisateur simple.
Aperçu
Cette application exemple propose un flux en direct de l'activité des utilisateurs qui combine Quicknode Streams et Key-Value Store (KV Store) pour surveiller les adresses, vérifier les webhooks, stocker les événements dans SQLite via Prisma et diffuser les mises à jour en temps réel via SSE (EVM + Solana).
Architecture
Blockchain (EVM + Solana)
-> Quicknode Streams + KV
-> POST /api/webhook/streams (signature vérifiée)
-> Insertion dans la base de données + émission SSE
-> Flux en direct dans l'interface utilisateur
Fonctionnalités
- Scripts de configuration de Quicknode Streams (création + activation)
- Filtre EVM pour les transferts natifs et les journaux de transfert ERC-20
- Filtre Solana pour les transferts natifs et les transferts de jetons SPL
- Suivi des utilisateurs basé sur la liste KV de Quicknode, permettant un suivi dynamique des utilisateurs sans avoir à redéployer le flux
- Marquage des adresses surveillées
- Ajouter en masse des adresses surveillées
- Vérification de la signature des webhooks et contrôle de l'horodatage
- Actualités en direct de la SSE
- Résolution ENS pour les adresses EVM
- Prisma + stockage local SQLite
Prérequis
- Node.js 20+ et un gestionnaire de paquets (pnpm, yarn, npm).
- Compte Quicknode et clé API : Créez un compte et récupérez votre Clé API d'administration pour
QN_API_KEY. - Point de terminaison EVM pour les métadonnées ENS/ERC-20 : créez un point de terminaison Ethereum et copiez l'URL HTTPS correspondant à
QN_EVM_ENDPOINT. - Point de terminaison RPC Solana pour les métadonnées des jetons SPL : créez un point de terminaison Solana et copiez l'URL HTTPS correspondant à
QN_SOLANA_ENDPOINT. - URL publique du webhook : utilisez un tunnel tel que
ngrokou déployez l'application de manière à ce queAPP_URLest accessible via Quicknode.
Structure du projet
filters/
evm-filter.js # Filtre Quicknode Streams (EVM)
solana-filter.js # Filtre Quicknode Streams (Solana)
scripts/
setup-streams.ts # Crée des listes KV + un flux (en pause)
activate-streams.ts # Active un flux par ID
src/
app/api/ # Routes API (webhooks, utilisateurs, SSE)
lib/ # Aides pour Quicknode, les webhooks et le SSE
types/ # Types de données des flux
prisma/
schema.prisma # Schéma SQLite
Variables d'environnement
Copier .env.example to .env et complétez :
QN_API_KEY="" # Clé API Quicknode
QN_STREAM_SECURITY_TOKEN_EVM="" # Jeton de sécurité du flux EVM (issu de la configuration)
QN_STREAM_SECURITY_TOKEN_SOL="" # Jeton de sécurité du flux Solana (issu de la configuration)
QN_EVM_ENDPOINT="" # URL du point de terminaison EVM de Quicknode
QN_SOLANA_ENDPOINT="" # URL du point de terminaison RPC Solana
DATABASE_URL="file:./dev.db" # Base de données SQLite
APP_URL="http://localhost:3000" # URL publique de l'application (ngrok pour les webhooks locaux)
Remarques :
QN_STREAM_SECURITY_TOKEN_EVMetQN_STREAM_SECURITY_TOKEN_SOLsont renvoyées parconfiguration : fluxpar chaîne.APP_URLdoit être accessible via Quicknode (utilisez ngrok ou une URL déployée).
Démarrer
1. Installer les dépendances
npm installer
# pnpm install
# yarn install
2. Créez votre fichier d'environnement
cp .env.example .env
3. Ajouter les variables requises
Remplissez .env (voir Prérequis).
Pour les webhooks locaux, exposez votre application avec ngrok et copiez l'URL HTTPS dans APP_URL:
ngrok http 3000
4. Créer des flux Quicknode et des listes KV
npm exécuter setup:streams
# pnpm run setup:streams
# yarn setup:streams
Copiez le jeton de sécurité imprimé dans .env (QN_STREAM_SECURITY_TOKEN_EVM ou QN_STREAM_SECURITY_TOKEN_SOL).
Si vous souhaitez utiliser Solana, relancez la commande avec chaîne=solana-mainnet (voir Configuration de Quicknode Streams (pour les options).
5. Configurer la base de données et lancer l'application
npx prisma migrate dev --name init
# pnpm prisma migrate dev --name init
# yarn prisma migrate dev --name init
npm run dev
# pnpm dev
# yarn dev
6. Activer le flux
npm exécuter activate:streams
# pnpm run activate:streams
# yarn activate:streams
Ouvrir http://localhost:3000, ajoutez des adresses de portefeuille, et vous devriez voir les événements en direct à mesure que les flux transmettent des webhooks.
Base de données
SQLite est utilisé par défaut. Le schéma Prisma se trouve dans prisma/schema.prisma.
Commandes courantes :
pnpm prisma migrate dev --name init
pnpm prisma studio
Configuration de Quicknode Streams
Il suffit de suivre les instructions de la section « Pour commencer ». Toutefois, si vous souhaitez gérer manuellement les paramètres des flux ou les listes KV, procédez comme suit.
1. Vérifiez le filtre
Le filtre EVM se trouve dans filters/evm-filter.js. Il émet :
nativeTransferévénements (transferts en ETH d'une valeur non nulle)erc20Transferévénements (journaux de transfert ERC-20)
Le filtre vérifie les adresses par rapport à la userstream_utilisateurs_surveillés_evm Liste KV.
Le filtre Solana se trouve dans filters/solana-filter.js. Il émet :
solTransferévénements (transferts SOL natifs)splTransferévénements (transferts de jetons SPL)
Le filtre vérifie les adresses par rapport à la userstream_monitored_users_sol Liste KV.
L'ajout d'adresses via l'interface utilisateur mettra automatiquement à jour la liste clé-valeur. Toutefois, si vous avez besoin de gérer manuellement les listes clé-valeur, vous pouvez le faire via l'API REST de Quicknode. Consultez la page de documentation sur le magasin clé-valeur pour en savoir plus.
2. Créer un flux et des listes clé-valeur
pnpm run setup:streams
Cela permettra de :
- Créer la liste KV pour la chaîne sélectionnée (
userstream_utilisateurs_surveillés_evmouuserstream_monitored_users_sol) - Encoder le filtre en Base64 pour la chaîne choisie
- Testez le filtre à l'aide d'un numéro de bloc de test (la liste KV étant vide au départ, aucun événement ne sera émis).
- Créez un flux à l'aide de :
status=en pauseensemble de données=block_with_receipts(EVM) ouensemble de données=bloc(Solana)- attributs obligatoires du webhook (compression, tentatives de reconnexion, délais d'expiration)
- Enregistrez l'identifiant du flux dans
.quicknode/streams.json - Imprimer le
jeton_de_sécuritépour.env(QN_STREAM_SECURITY_TOKEN_EVMouQN_STREAM_SECURITY_TOKEN_SOL) - Crée un flux unique par exécution (réexécuter avec
chaîne=solana-mainnetouchain=ethereum-mainnetpour créer les deux).
Vous pouvez remplacer les options à l'aide de clé=valeur args, par exemple :
pnpm run setup:streams chain=ethereum-mainnet name="UserStream EVM Monitor" test_block_number=24223192
pnpm run setup:streams chain=solana-mainnet name="UserStream Solana Monitor" test_block_number=393612994
Options courantes :
chain=ethereum-mainnet(alias :réseau=ethereum-mainnet)ensemble de données=block_with_receiptsdataset_batch_size=1status=en pauseelastic_batch_enabled=truefilter_path=filters/evm-filter.jstest_block_number=24223192destination_compression=nonedestination_headers='{"Content-Type":"application/json"}'destination_max_retry=3destination_retry_interval_sec=1destination_post_timeout_sec=10
Sécurité et charge utile des webhooks
- Point final :
POST /api/webhook/streams - En-têtes obligatoires :
x-qn-nonce,x-qn-timestamp,x-qn-signature - La charge utile peut être compressée au format gzip ; le gestionnaire la détecte automatiquement
content-encoding : gzip - Utilisations de la vérification des signatures
QN_STREAM_SECURITY_TOKEN_EVMouQN_STREAM_SECURITY_TOKEN_SOL
Points de terminaison de l'API
GET /api/health- bilan de santéGET /api/users- afficher la liste des utilisateurs surveillésPOST /api/users- ajouter un utilisateur (adresse de portefeuille, facultatifnom)PATCH /api/users?id=...- mettre à jour le nom d'utilisateur/nom d'affichageDELETE /api/users?id=...- supprimer un utilisateurPOST /api/users/bulk- ajout groupé d'utilisateurs (séparés par des sauts de ligne)POST /api/webhook/streams- Webhook Quicknode StreamsPOST /api/webhook/test- Test de webhook en mode local uniquementGET /api/sse- Flux d'événements liés aux activités SSE
Aperçu
![]()
- Créer une branche du dépôt
- Créer une branche de fonctionnalité :git checkout -b feature/amazing-feature
- Validez vos modifications :git commit -m "Ajout d'une fonctionnalité géniale"
- Publiez votre branche :git push origin feature/amazing-feature
- Créez une Pull Request.