For the complete documentation index, see llms.txt. This page is also available as Markdown.

Quickstart — Node.js (Testnet)

Encrypt and decrypt data with TACo in a Node.js environment — no browser or wallet extension required.

This guide walks through a complete encrypt → decrypt flow in Node.js. Unlike the browser quickstart, there's no MetaMask or window.ethereum — we use private keys and JsonRpcProvider directly.

A full working example lives in the taco-web repo: examples/taco/nodejs

1

Install dependencies

npm install @nucypher/taco @nucypher/taco-auth ethers@5.7.2
2

Configure provider, domain, and ritual ID

You'll need three things:

Parameter
Value
Notes

RPC URL

A Polygon Amoy RPC endpoint

This reads DKG coordination contracts — it's not your application's chain. Any public Amoy RPC works.

Ritual ID

27 (for LYNX testnet)

See the testnet page for other environments.

Private keys

Two test wallets

One for the encryptor, one for the consumer. Any Ethereum wallets — no testnet funds required.

import { ethers } from 'ethers';
import { domains } from '@nucypher/taco';

// This provider reads DKG coordination contracts on Polygon Amoy.
// It is NOT your application's RPC — it's infrastructure.
const provider = new ethers.providers.JsonRpcProvider(
  'https://polygon-amoy.drpc.org'
);

const domain = domains.DEVNET;  // "lynx"
const ritualId = 27;
3

Encrypt data

import { conditions, encrypt, initialize } from '@nucypher/taco';
import { ethers } from 'ethers';

await initialize();

// Any condition works — here's a simple balance check
const hasBalance = new conditions.base.rpc.RpcCondition({
  chain: 80002,  // Polygon Amoy — the chain where this condition is evaluated (can be any supported chain)
  method: 'eth_getBalance',
  parameters: [':userAddress', 'latest'],
  returnValueTest: {
    comparator: '>=',
    value: 0,
  },
});

const encryptorSigner = new ethers.Wallet('<ENCRYPTOR_PRIVATE_KEY>');

const messageKit = await encrypt(
  provider,
  domain,
  'my secret message',
  hasBalance,
  ritualId,
  encryptorSigner,
);

// Serialize for storage or transmission
const encryptedBytes = messageKit.toBytes();
4

Decrypt data

import {
  ThresholdMessageKit,
  conditions,
  decrypt,
  initialize,
} from '@nucypher/taco';
import {
  EIP4361AuthProvider,
  USER_ADDRESS_PARAM_DEFAULT,
} from '@nucypher/taco-auth';
import { ethers } from 'ethers';

await initialize();

// Deserialize
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);

const consumerSigner = new ethers.Wallet('<CONSUMER_PRIVATE_KEY>');

// Build condition context
const conditionContext =
  conditions.context.ConditionContext.fromMessageKit(messageKit);

// In Node.js, EIP4361AuthProvider needs explicit SIWE parameters
// (in the browser, these come from the page origin)
const authProvider = new EIP4361AuthProvider(
  provider,
  consumerSigner,
  { domain: 'localhost', uri: 'http://localhost:3000' },
);
conditionContext.addAuthProvider(USER_ADDRESS_PARAM_DEFAULT, authProvider);

const decryptedBytes = await decrypt(
  provider,
  domain,
  messageKit,
  conditionContext,
);

const decryptedMessage = new TextDecoder().decode(decryptedBytes);
console.log(decryptedMessage); // "my secret message"

Key differences from browser usage

Browser:

const provider = new ethers.providers.Web3Provider(window.ethereum);

Node.js:

const provider = new ethers.providers.JsonRpcProvider('https://polygon-amoy.drpc.org');

Next steps

Last updated