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:
- Build the ECIES payload (encrypted for recipients).
- Build
CDepinMessagewith token, sender address, timestamp, andencryptedPayload. - Hash and sign the message with the sender's private key.
- 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:
- Calls
depinreceivemsg(token, address, lastTimestamp). - Iterates over results and attempts decryption with its private key.
- Ignores messages that fail AES-GCM authentication.
- Tracks the max
timestampto 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.