npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@neuraiproject/neurai-depin-msg

v2.1.3

Published

Build and serialize DePIN encrypted messages for Neurai blockchain

Readme

@neuraiproject/neurai-depin-msg

Build, encrypt, sign, and serialize DePIN messages compatible with Neurai Core.

This library produces the hex payload for the Neurai RPC method depinsubmitmsg. It runs fully client-side (browser / local scripts) and does not require a backend.

What you get

Given:

  • A plaintext message
  • Your sender address + private key
  • The compressed public keys of all recipients

It returns:

  • hex: a serialized CDepinMessage ready to submit via depinsubmitmsg
  • messageHash: the message hash as typically displayed by Neurai Core

Install

npm install @neuraiproject/neurai-depin-msg

Usage (Browser)

Include the bundled build (IIFE). It exposes a global neuraiDepinMsg object.

<script src="./dist/neurai-depin-msg.min.js"></script>
<script>
  async function build() {
    const res = await neuraiDepinMsg.buildDepinMessage({
      token: 'MYTOKEN',
      senderAddress: 'NxxxxYourAddress',
      senderPubKey: '02abcdef... (66 hex chars)',
      privateKey: 'L... (WIF) OR 64-hex private key',
      timestamp: Math.floor(Date.now() / 1000),
      message: 'Hello from the browser!',
      recipientPubKeys: [
        '02deadbeef... (recipient 1 compressed pubkey)',
        '03cafebabe... (recipient 2 compressed pubkey)'
      ],
      messageType: 'group'
    });

    console.log('depinsubmitmsg hex:', res.hex);
    console.log('messageHash:', res.messageHash);
  }

  build();
</script>

Submit it to your node:

neurai-cli depinsubmitmsg "<HEX_FROM_LIBRARY>"

Usage (Node.js)

The published build is browser-style (IIFE) and attaches to globalThis.neuraiDepinMsg. Node must have WebCrypto available.

// Node 18+ usually has WebCrypto; if not, enable it explicitly:
import { webcrypto } from 'node:crypto';
if (!globalThis.crypto?.subtle) globalThis.crypto = webcrypto;

// This executes the IIFE bundle and sets globalThis.neuraiDepinMsg
import '@neuraiproject/neurai-depin-msg/dist/neurai-depin-msg.js';

const { buildDepinMessage } = globalThis.neuraiDepinMsg;

const res = await buildDepinMessage({
  token: 'MYTOKEN',
  senderAddress: 'NxxxxYourAddress',
  senderPubKey: '02abcdef...(66 hex chars)',
  privateKey: 'L... (WIF) OR 64-hex private key',
  timestamp: Math.floor(Date.now() / 1000),
  message: 'Hello from Node!',
  recipientPubKeys: ['02deadbeef...'],
  messageType: 'private'
});

console.log(res.hex);

API

neuraiDepinMsg.buildDepinMessage(params)

The browser/IIFE global is neuraiDepinMsg.

Builds a complete serialized CDepinMessage (as hex) suitable for depinsubmitmsg.

Parameters

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | token | string | yes | Token/asset name for the DePIN channel | | senderAddress | string | yes | Sender Neurai address (string as used by Core RPC) | | senderPubKey | string | yes | Sender compressed public key as hex (66 chars / 33 bytes) | | privateKey | string | yes | Sender private key as WIF or 64-hex (32 bytes) | | timestamp | number | yes | Unix time (seconds) | | message | string | yes | Plaintext message (UTF-8) | | recipientPubKeys | string[] | yes | Recipient compressed pubkeys as hex (66 chars each). The sender pubkey is automatically added if missing so you can decrypt your own messages. | | messageType | "private" \| "group" | yes | Message type: "private" allows only one recipient plus the sender, "group" allows multiple recipients. |

neuraiDepinMsg.decryptDepinReceiveEncryptedPayload(encryptedPayloadHex, recipientPrivateKey)

Decrypts the encrypted_payload_hex returned by Neurai Core RPC depinreceivemsg.

  • encryptedPayloadHex: hex string for the serialized CECIESEncryptedMessage.
  • recipientPrivateKey: recipient private key as WIF or 64-hex.

Returns string | null (it returns null if the message is not for that key or authentication fails).

Notes:

  • Public keys must be compressed (start with 02 or 03).
  • This library does not discover recipients for a token; it only encrypts for the pubkeys you provide.

Returns

| Property | Type | Description | |----------|------|-------------| | hex | string | Hex-encoded serialized CDepinMessage | | messageHash | string | Double-SHA256 signing hash displayed in the typical Core-style (byte-reversed) | | messageHashBytes | string | Raw 32-byte digest as hex (not reversed) | | encryptedSize | number | Size of the serialized CECIESEncryptedMessage in bytes | | recipientCount | number | Number of recipients (including sender if auto-added) | | messageType | "private" \| "group" | The message type that was specified in the parameters. |

How it works (Core-compatible)

Encryption (Hybrid ECIES with AES-256-GCM)

This matches Neurai Core's CECIESEncryptedMessage format (v2.0+):

  • Ephemeral keypair is generated per message.
  • Message encryption:
    • AES-256-GCM encrypts plaintext with a derived AES key (no padding).
    • Payload is stored as [Nonce(12) || ciphertext || AuthTag(16)].
  • Per-recipient key wrapping:
    • ECDH derives a shared secret from ephemeral privkey + recipient pubkey.
    • A per-recipient encKey is derived and used to AES-256-GCM encrypt the 32-byte AES key.
    • Recipient package is [Nonce(12) || encryptedAESKey(32) || AuthTag(16)] (60 bytes).

Serialization

All fields are serialized using Bitcoin-style rules:

  • CompactSize prefixes for vectors/strings
  • Little-endian integers

Message structure:

[token (string)]
[senderAddress (string)]
[timestamp (int64)]
[messageType (uint8)]       // 0x01 = private, 0x02 = group
[encryptedPayload (vector)]
[signature (vector)]

Signing

The signature hash is:

doubleSHA256( serialize(token) || serialize(senderAddress) || int64(timestamp) || uint8(messageType) || vector(encryptedPayloadBytes) )

messageHash is the display-friendly byte-reversed form (similar to how Core prints uint256).

Demo

Open demo.html in a browser (a local server is recommended):

python3 -m http.server 8080
# Open http://localhost:8080/demo.html

Development

npm run build:dev   # dist/neurai-depin-msg.js
npm run build       # dist/neurai-depin-msg.min.js

License

MIT