Skip to main content

Send/Receive

This section describes how depinsubmitmsg and depinreceivemsg work, with technical details and signing examples for HTML and Python clients.

depinsubmitmsg: client-side signing and submission

The pool accepts pre-encrypted and signed messages. The client typically:

  1. Build the ECIES payload (encrypted for recipients).
  2. Build CDepinMessage with token, sender address, timestamp, and encryptedPayload.
  3. Hash and sign the message with the sender's private key.
  4. Serialize and submit via depinsubmitmsg.

Message hash (for signature):

hash = DSHA256(
token || senderAddress || timestamp(8 bytes LE) || encryptedPayload
)

Signature format:

  • ECDSA over secp256k1
  • DER-encoded signature bytes

depinreceivemsg: client-side decryption

depinreceivemsg returns encrypted payloads only. The client:

  1. Calls depinreceivemsg(token, address, lastTimestamp).
  2. Iterates over results and attempts decryption with its private key.
  3. Ignores messages that fail AES-GCM authentication.
  4. Tracks the max timestamp to avoid reprocessing.

HTML example (browser client)

This example shows how to sign the hash before calling depinsubmitmsg. Encryption is omitted for clarity.

<script type="module">
import { sha256 } from "https://cdn.skypack.dev/@noble/hashes/sha256";
import { sign } from "https://cdn.skypack.dev/@noble/secp256k1";

const encoder = new TextEncoder();

function dsha256(bytes) {
return sha256(sha256(bytes));
}

function concatBytes(...parts) {
const len = parts.reduce((sum, p) => sum + p.length, 0);
const out = new Uint8Array(len);
let offset = 0;
for (const p of parts) {
out.set(p, offset);
offset += p.length;
}
return out;
}

// token, senderAddress, timestamp, encryptedPayload are placeholders
const token = "TOKEN";
const senderAddress = "Nsender...";
const timestampLE = new DataView(new ArrayBuffer(8));
timestampLE.setBigInt64(0, BigInt(Math.floor(Date.now() / 1000)), true);
const timestampBytes = new Uint8Array(timestampLE.buffer);
const encryptedPayload = new Uint8Array([/* serialized ECIES payload */]);

const hash = dsha256(
concatBytes(
encoder.encode(token),
encoder.encode(senderAddress),
timestampBytes,
encryptedPayload
)
);

const privkey = "YOUR_PRIVATE_KEY_HEX";
const signature = await sign(hash, privkey, { der: true });

// Serialize CDepinMessage, hex-encode, then call depinsubmitmsg via JSON-RPC.
</script>

Python example (backend client)

This example signs the message hash using secp256k1 (via coincurve).

from hashlib import sha256
from coincurve import PrivateKey

def dsha256(data: bytes) -> bytes:
return sha256(sha256(data).digest()).digest()

def build_hash(token: bytes, sender: bytes, timestamp_le: bytes, encrypted_payload: bytes) -> bytes:
return dsha256(token + sender + timestamp_le + encrypted_payload)

# token, sender, timestamp_le, encrypted_payload are placeholders
token = b"TOKEN"
sender = b"Nsender..."
timestamp_le = (int(1700000000)).to_bytes(8, "little", signed=True)
encrypted_payload = b"\x02\xab..." # serialized ECIES payload

msg_hash = build_hash(token, sender, timestamp_le, encrypted_payload)

privkey = PrivateKey.from_hex("YOUR_PRIVATE_KEY_HEX")
signature_der = privkey.sign(msg_hash, hasher=None)

# Serialize CDepinMessage, hex-encode, then call depinsubmitmsg via JSON-RPC.