Waku + Codex
Powering secure Waku communications and decentralized Codex storage with TACo
Using Codex, Waku, and TACo together gives developers a powerful, fully decentralized stack for building secure, censorship-resistant applications. Waku enables real-time, peer-to-peer communication without relying on centralized servers, while Codex provides verifiable, durable storage for any type of content. TACo adds a layer of programmable access control and encryption, allowing developers to define precise conditions for data access.
Waku overview
Waku's communication protocols provide gas-free message transport and routing – supporting in-browser light clients, and ensuring protocol-level metadata privacy and end-user anonymity. Ephemeral, real-time messaging with minimal persistence brings efficient data/message transmission within adopting applications. Like TACo, Waku's underlying network makes no compromises with respect to permissionlessness, trust-minimization and decentralization.
For more on Waku's JavaScript SDK, check out their documentation.
Codex overview
Codex is a decentralized data storage protocol designed to provide strong censorship resistance and durability guarantees. It aims to address the shortcomings of centralized cloud storage—such as censorship, lack of data ownership, security breaches, and high costs. By leveraging a decentralized network of storage providers, Codex ensures data is stored reliably and remains accessible without relying on centralized entities.
For further information Codex, follow their documentation or API specification.
Use case ideas
The combination of communication (Waku), storage (Codex), and Access Control (TACo) layers enable a wide range of use cases, powering practical and fully decentralized solutions such as:
Collaboration Apps. Decentralized alternative to Google Docs or Office 365, offering fine-grained access control. Documents and version history are stored using Codex, while Waku protocol enables real-time synchronization and user notifications. TACo handles access control for all shared content.
Voting and Governance. An organization that shares proposals and collects votes in real time with verifiable, tamper-resistant outcomes. While TACo keeps votes anonymous until results are revealed thanks to its access control conditions, Waku distributes ballots and proposals in real time to eligible voters, and results are publicly and verifiably stored by Codex.
Data markets. A decentralized marketplace where researchers or companies can exchange sensitive datasets securely and without intermediaries. Codex serves as a powerful tool to host these datasets in a decentralized network, Waku facilitates peer-to-peer negotiation of data exchanges, and TACo enforces conditional access (e.g., after payment or approval).
Social networks. Social platforms -such as forums, media-sharing apps, and microblogging sites) can benefit from decentralized storage of posts, profiles, images, and videos using Codex. Waku is well-suited for notifications, user updates and real-time chat, while TACo provides access control to posts and social data.
Example application
Cyphershare is a secure file sharing decentralized application that leverages Codex for storage, Waku for peer-to-peer communication, and TACo for end-to-end encryption and access control. By using Cyphershare, users can securely share files by encrypting them in the browser before upload, ensuring that only authorized recipients -those meeting predefined TACo conditions such as holding a specific token balance or within a time-limited access windows- can decrypt and access the content.
The running application can be found here: CypherShare
Integration steps
This section walks through a minimum viable integration to get developers started. For more powerful extensions and advanced condition logic, check out the Access Control section.
1. Required imports
// Waku SDK components for decentralized messaging
import { createLightNode, createEncoder, createDecoder, waitForRemotePeer } from '@waku/sdk'
// TACo components for conditional encryption
import { initialize, encrypt, decrypt, conditions, domains, ThresholdMessageKit } from '@nucypher/taco';
// Authentication provider for TACo
import { EIP4361AuthProvider, USER_ADDRESS_PARAM_DEFAULT } from '@nucypher/taco-auth';
// Ethereum interaction library
import { ethers } from 'ethers';
2. Create and set up a Waku light node
const lightNode = await createLightNode({
defaultBootstrap: false,
networkConfig: {
clusterId: 42,
shards: [0]
},
});
await lightNode.start();
// Define your application's content topic: /<application-name>/<version>/<content-type>/<encoding>
const CONTENT_TOPIC = `/fileshare/1/room-${roomId}/proto`;
// Create Waku's encoder and decoder
const encoder = createEncoder({ contentTopic: CONTENT_TOPIC });
const decoder = createDecoder(CONTENT_TOPIC);
3. Send and receive Waku messages
// Function that handles the received message
const messageHandler = (wakuMessage: DecodedMessage) => {
}
// Subscribe to content topic
const subscription = await lightNode.filter.subscribe(
[decoder],
messageHandler
);
// Send a message
const serializedMessage = FileMessage.encode(protoMessage).finish();
await node.lightPush.send(
encoder,
{ payload: serializedMessage }
)
4. Download and upload files from Codex
Upload a file to Codex:
const url = `/api/codex/v1/data`;
const xhr = new XMLHttpRequest();
// The file to be uploaded
const file = ... [File]
xhr.setRequestHeader('Content-Type', file.type);
xhr.setRequestHeader(
'Content-Disposition',
`attachment; filename='${file.name}'`
);
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
// Extract the CID from the response
const cid =
typeof response === 'object'
? response.id ||
response.cid ||
(response.data && (response.data.id || response.data.cid))
: response;
}
}
xhr.send(file);
Download a file from Codex:
// CID is the Codex file ID.
const cid = ...
const downloadUrl = `/api/codex/v1/data/${cid}/network/stream`;
const response = await fetch(downloadUrl, {
method: 'GET',
headers: {
Accept: '*/*',
...(this.authHeaders || {}),
},
mode: 'cors',
credentials: 'include',
});
const data = await response.blob();
5. Encryption and decryption with TACo
Initialize TACo:
await initialize()
Define access conditions:
const condition = new conditions.base.rpc.RpcCondition({
chain: chainId,
method: "eth_getBalance",
parameters: [":userAddress", "latest"],
returnValueTest: {
comparator: ">",
value: 0,
},
});
Encrypt files:
const ritualId = 6 // This is a testnet-specific ritual ID
// Read file as ArrayBuffer
const arrayBuffer = await file.arrayBuffer();
const data = new Uint8Array(arrayBuffer);
const messageKit = await encrypt(
provider,
domain,
data,
condition,
ritualId,
encryptorSigner // ethers.Signer
);
const bytesToUpload = messageKit.toBytes();
Decrypt files:
const messageKit = ThresholdMessageKit.fromBytes(encryptedBytes);
const authProvider = new EIP4361AuthProvider(provider, signer);
const conditionContext =
conditions.context.ConditionContext.fromMessageKit(messageKit);
conditionContext.addAuthProvider(
USER_ADDRESS_PARAM_DEFAULT,
authProvider
);
const result = await decrypt(
provider,
domain,
messageKit,
conditionContext
);
Using Waku + Codex + TACo in production
Waku is currently used to enable private communication in applications such as RAILGUN and Status. Research and development continue with their decentralized DoS protection protocol being trialed on testnet.
Codex is currently operating a public, non-incentivized testnet that is open to developers and contributors.
Regarding TACo, the parameters specified in this guide are for testing and hacking only. For real-world use cases, the production version of TACo is required – i.e. a funded Mainnet ritualID
which connects the encrypt/decrypt API to a cohort of independently operated nodes, and corresponds to a DKG public key generated by independent parties.
Ready to use TACo in production? Check out the Mainnet Access section for everything you need.
Last updated