
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
substreams-sink-webhook
Advanced tools
Substreams Sink Webhook
substreams-sink-webhookis a tool that allows developers to pipe data extracted from a blockchain to Webhook.
Bun - https://bun.sh/Express - https://expressjs.com/node:http - https://nodejs.org/api/http.htmlThe POST message will be a JSON object with the following structure:
headers
POST http://localhost:3000 HTTP/1.1
content-type: application/json
x-signature-ed25519: 8f01c66ccda5b987c43d913290419572ea586dbef2077fa166c4a84797e1d2c76b305bc67ed43efb1fc841562620a61cb59c4d8a13de689a2e98ead19190f80c
x-signature-timestamp: 1707776632
body
The body will be a flatten JSON string with the following structure:
{
"status": 200,
"cursor": "OJGbpO9ZnZcwvxW38_FO8KWwLpcyA1lrUQPgKRFL04Py8yCW35v1VTB1O0-Elami3RztQlOp2tmcHC9y9ZQFuoDrxLpj6yU-FXorwoHr_OfqLPumMQwTJ-hgWeuKYNLeWDjTagn4ersEtNGzbvLaY0UxZZUhK2G62z1VptdXJfEWuiJmyjmrIZrRhK-WoNAS_rEkQ7L1xCmhDzJ4K0dTPcSDNPKZuDR2",
"session": {
"traceId": "3cbb0a1c772a47a72995d95f4c6d2cff",
"resolvedStartBlock": 53448515
},
"clock": {
"timestamp": "2024-02-12T22:23:51.000Z",
"number": 53448530,
"id": "f843bc26cea0cbd50b09699546a8a97de6a1727646c17a857c5d8d868fc26142"
},
"manifest": {
"substreamsEndpoint": "https://polygon.substreams.pinax.network:443",
"chain": "polygon",
"finalBlockOnly": "false",
"moduleName": "map_blocks",
"type": "sf.substreams.v1.Clock",
"moduleHash": "44c506941d5f30db6cca01692624395d1ac40cd1"
},
"data": {
...
}
}
$ bunx substreams-sink-webhook keypair
{
"publicKey": "36a89085d54d866c60ecccc2bf332d1c0dd5f1a810af175b1cfb7ff9e64b67d6",
"privateKey": "67603675f8160b4e4ca67770eaf7df797f3a9617665a84ec3e9baf92c403fb4f"
}
or using curl
$ curl http://localhost:9102/keypair
import nacl from "tweetnacl";
// ...HTTP server
const PUBLIC_KEY = "APPLICATION_PUBLIC_KEY";
// get headers and body from POST request
const signature = request.headers.get("x-signature-ed25519");
const timestamp = request.headers.get("x-signature-timestamp");
const body = await request.text();
// validate signature using public key
const isVerified = nacl.sign.detached.verify(
Buffer.from(timestamp + body),
Buffer.from(signature, "hex"),
Buffer.from(PUBLIC_KEY, "hex")
);
if (!isVerified) {
return new Response("invalid request signature", { status: 401 });
}
.env Environment variables# Webhook
PORT=9102
WEBHOOK_URL=http://127.0.0.1:3000
# Get Substreams API Key
# https://app.pinax.network
# https://app.streamingfast.io/
SUBSTREAMS_API_KEY=<Substreams API Token @ https://pinax.network>
# Substreams Package (*.spkg)
MANIFEST=https://github.com/pinax-network/substreams/releases/download/blocks-v0.1.0/blocks-v0.1.0.spkg
MODULE_NAME=map_blocks
START_BLOCK=-10
PRODUCTION_MODE=true
# Webhook (Optional)
PRIVATE_KEY=<Ed25519 Private Key>
MAXIMUM_ATTEMPTS=100
VERBOSE=true
$ substreams-sink-webhook --help
Usage: substreams-sink-webhook run [options]
Substreams Sink Webhook
Options:
-e --substreams-endpoint <string> Substreams gRPC endpoint to stream data from (env: SUBSTREAMS_ENDPOINT)
--manifest <string> URL of Substreams package (env: MANIFEST)
--module-name <string> Name of the output module (declared in the manifest) (env: MODULE_NAME)
-s --start-block <int> Start block to stream from (defaults to -1, which means the initialBlock of the first module you are streaming) (default: "-1", env: START_BLOCK)
-t --stop-block <int> Stop block to end stream at, inclusively (env: STOP_BLOCK)
-p, --params <string...> Set a params for parameterizable modules. Can be specified multiple times. (ex: -p module1=valA -p module2=valX&valY) (default: [], env: PARAMS)
--substreams-api-key <string> API key for the Substream endpoint (env: SUBSTREAMS_API_KEY)
--delay-before-start <int> Delay (ms) before starting Substreams (default: 0, env: DELAY_BEFORE_START)
--cursor-path <string> File path or URL to cursor lock file (default: "cursor.lock", env: CURSOR_PATH)
--http-cursor-auth <string> Basic auth credentials for http cursor (ex: username:password) (env: HTTP_CURSOR_AUTH)
--production-mode <boolean> Enable production mode, allows cached Substreams data if available (default: "false", env: PRODUCTION_MODE)
--inactivity-seconds <int> If set, the sink will stop when inactive for over a certain amount of seconds (default: 300, env: INACTIVITY_SECONDS)
--hostname <string> The process will listen on this hostname for any HTTP and Prometheus metrics requests (default: "localhost", env: HOSTNAME)
--port <int> The process will listen on this port for any HTTP and Prometheus metrics requests (default: 9102, env: PORT)
--metrics-labels [string...] To apply generic labels to all default metrics (ex: --labels foo=bar) (default: {}, env: METRICS_LABELS)
--collect-default-metrics <boolean> Collect default metrics (default: "false", env: COLLECT_DEFAULT_METRICS)
--headers [string...] Set headers that will be sent on every requests (ex: --headers X-HEADER=headerA) (default: {}, env: HEADERS)
--final-blocks-only <boolean> Only process blocks that have pass finality, to prevent any reorg and undo signal by staying further away from the chain HEAD (default: "false", env: FINAL_BLOCKS_ONLY)
--verbose <boolean> Enable verbose logging (default: "false", env: VERBOSE)
--webhook-url <string> Webhook URL to send POST (env: WEBHOOK_URL)
--private-key <string> Ed25519 private key to sign POST data payload (env: PRIVATE_KEY)
--maximum-attempts <number> Maximum attempts to retry POST (default: 100, env: MAXIMUM_ATTEMPTS)
-h, --help display help for command
Pull from GitHub Container registry
docker pull ghcr.io/pinax-network/substreams-sink-webhook:latest
Run with .env file
docker run -it --rm --env-file .env ghcr.io/pinax-network/substreams-sink-webhook:latest run
Build from source
docker build -t substreams-sink-webhook .
--final-blocks-only--production-mode.env)--params or -psubstreams-sinkcursor.lock only after successful POST
FAQs
Substreams Sink Webhook
We found that substreams-sink-webhook demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.