Envelop is the service behind Snapshot mailing list .
This service is API only, and should be used together with Envelop-UI to handle all front-end related matters.
This service depends on a couple of services:
- Node.js 18.x
- MySQL 5+
- Redis
- A sendgrid account (email provider)
- An Envelop-UI instance
yarn
Make a copy of .env.example
and rename it as .env
. Then update the credentials in the file to the correct values for your local setup.
Key | Description | Example |
---|---|---|
HOST |
Hostname of the current envelop instance | http://localhost:3006 |
FRONT_HOST |
Hostname of the envelop-ui instance | http://localhost:8080 |
HUB_URL |
Hostname of snapshot's hub service | https://hub.snapshot.org |
WALLET_PRIVATE_KEY |
Private key of the wallet used to sign the emails | 0x... |
DATABASE_URL |
URL of the MySQL database | mysql://root:root@localhost:3306/envelop |
REDIS_URL |
URL of the Redis database | redis://localhost:6379 |
SENDGRID_API_KEY |
API key of the sendgrid account | SG.1234567890 |
WEBHOOK_AUTH_SECRET |
Authentication header sent by snapshot's webhook service | abc123 |
SENTRY_DSN |
Sentry DSN key | https://[email protected]/1 |
SENTRY_TRACE_SAMPLE_RATE |
Sentry trace sample rate, nunmber between 0 and 1 | 0.1 |
Start the service with
yarn dev
All tests are run using their own .env (test/.env.test
).
yarn test:setup
This task should also be ran after each schema.sql change, to ensure your test database schema is up-to-date.
yarn test:unit
yarn test:e2e
You can run and generate the coverage for all tests at once with
yarn test
yarn lint
yarn typecheck
Make sure to run the lints to ensure your code follow the coding standard before submitting any commits. You can optionally run these tasks automatically on commit and on push by installing the git hooks with husky:
yarn husky install
All the endpoints return a JSON response.
This endpoint will trigger different action depending on the payload method
param.
Subscribe an email and a wallet address to the mailing list
curl -X POST localhost:3006/ -H "Content-Type: application/json" -d '{"method": "snapshot.subscribe", "params": { "email": "[email protected]", "address": "0xabc", "signature": "0x123" }}'
{
jsonrpc: '2.0',
'OK',
''
}
Email verification, triggered by the user via envelop-ui
curl -X POST localhost:3006/ -H "Content-Type: application/json" -d '{"method": "snapshot.verify", "params": { "email": "[email protected]", "address": "0xabc", "salt": "1234", "signature": "0x123" }}'
{
jsonrpc: '2.0',
'OK',
''
}
Update an email's subscription
curl -X POST localhost:3006/ -H "Content-Type: application/json" -d '{"method": "snapshot.update", "params": { "address": "0xabc", "subscriptions": ["summary"], "signature": "0x123" }}'
{
jsonrpc: '2.0',
'OK',
''
}
Unsubscribe an email from the database.
curl -X POST localhost:3006/ -H "Content-Type: application/json" -d '{"method": "snapshot.unsubscribe", "params": { "email": "[email protected]", "address": "0xabc", "signature": "0x123" }}'
{
jsonrpc: '2.0',
'OK',
''
}
Return a subscriber, given a wallet address
# Response signature
{
status: 'VERIFIED' | 'UNVERIFIED' | 'NOT_SUBSCRIBED';
subscriptions: templateId[]
}
curl -X POST localhost:3006/subscriber -H "Content-Type: application/json" -d '{"address": "0x91FD2c8d24767db4Ece7069AA27832ffaf8590f3"}'
{
"status": "VERIFIED",
"subscriptions": ["summary", "newProposal", "closedProposal"]
}
Return the list of all available subscription type
# Response signature
{
[key: templateId]: {
name: string;
description: string;
}
}
curl localhost:3006/subscriptionsList
{
"summary": {
"name": "Weekly digest",
"description": "Get a weekly report detailing the activity in your followed spaces."
},
"newProposal": {
"name": "Proposal creation",
"description": "Get informed when a new proposal is submitted in your followed spaces."
},
"closedProposal": {
"name": "Proposal closure",
"description": "Get informed when a proposal is closed in your followed spaces."
}
}
Receive and trigger emails from webhook events.
Data payload should follow Snapshot webhook format.
CLI tests scripts are provided (see below) for easier testing, instead of sending CURL command
All endpoints will respond with a JSON-RPC 2.0 error response on error:
{
"jsonrpc":"2.0",
"error":{
"code": CODE,
"message": MESSAGE
},
"id": ID
}
Description | CODE |
MESSAGE |
---|---|---|
Request contains invalid data | 400 | INVALID_PARAMS |
Verifying an address already attached to another verified email | 400 | ADDRESS_ALREADY_VERIFIED_WITH_ANOTHER_EMAIL |
Signature is not valid | 401 | UNAUTHORIZED |
Address/email/record does not exist | 404 | RECORD_NOT_FOUND |
Server error | 500 | SERVER_ERROR |
Take advantage of the MESSAGE
code to show meaningful error message to your end user.
As triggering emails involve a few tedious steps on the UI, a few CLI scripts are provided to trigger the email sending directly to a given email address.
yarn ts-node scripts/send-verify.ts [EMAIL] [ADDRESS]
// E.g.
// yarn ts-node scripts/send-verify.ts [email protected] 0xeF8305E140ac520225DAf050e2f71d5fBcC543e7
EMAIL
: your email address (not required to already exist in the database)ADDRESS
: a wallet address (not required to already exist in the database)
yarn ts-node scripts/send-summary.ts [EMAIL] [ADDRESSES] [SEND_DATE]
# E.g.
# yarn ts-node scripts/send-summary.ts [email protected] 0x07ecdeD990C06Bb6756EC300844B3F91677338d0 2023-04-25
EMAIL
: your email address (not required to already exist in the database)ADDRESSES
: one or more wallet addresses (separated by a comma)SEND_DATE
: ayyyy-mm-dd
formatted date, to emulate the date the email is sent (affects the summary report time window)
yarn ts-node scripts/send-new-proposal.ts [EMAIL] [PROPOSAL-ID]
# E.g.
# yarn ts-node scripts/send-new-proposal.ts [email protected] 0xeF8305E140ac520225DAf050e2f71d5fBcC543e7
EMAIL
: your email address (not required to already exist in the database)PROPOSAL-id
: a proposal ID
yarn ts-node scripts/send-closed-proposal.ts [EMAIL] [PROPOSAL-ID]
# E.g.
# yarn ts-node scripts/send-closed-proposal.ts [email protected] 0xeF8305E140ac520225DAf050e2f71d5fBcC543e7
EMAIL
: your email address (not required to already exist in the database)PROPOSAL-id
: a proposal ID
Emulate an incoming webhook event from snapshot's webhook service (require that the envelop instance to be started e.g. with yarn dev
, else the emails will just be queued without being sent).
yarn ts-node scripts/trigger-webhook-proposal.ts [EVENT] [ID]
# E.g.
# yarn ts-node scripts/trigger-webhook.ts proposal/created proposal/0x88583c43b196ec86cee45345611b582108f1d6933ab688a7cae992a6baa552a6
EVENT
: webhook event nameID
: webhook ID
See Snapshot webhooks documentation for the list of available event
type.
# Build the project
yarn build
# Start the service
yarn start
See the contribution guideline
Envelop is open-sourced software licensed under the © MIT license.