Time Lock Encryption using Lighthouse Access Control
In this tutorial, we delve into the innovative concept of Time-Lock Encryption on the InterPlanetary File System (IPFS) using Lighthouse Access Control. IPFS, often referred to as the distributed web, offers a decentralized protocol to make the web faster, p2p, and more open. On the other hand, Lighthouse.Storage is a Web3 decentralized storage solution, offering perpetual storage to store your data securely long-term.
The amalgamation of these two technologies brings forth an exciting feature – the ability to encrypt files and set conditions for their decryption based on specific blockchain parameters. One of the innovative concept it enables is "Time-Lock Encryption."
What exactly does this mean? Think of it as a time capsule. You can securely store a piece of information, and set a condition that this information will only be accessible after a particular block number on the blockchain like ethereum has been reached. Such a feature has a myriad of applications, from securing early-stage project details to establishing wills or contracts that are meant to be executed in the future.
Whether you're a blockchain enthusiast, a developer looking to integrate time-lock features, or someone curious about decentralized storage and its potential, this guide is tailored for you.
Let's embark on this journey and unlock the potential of Time-Lock Encryption on IPFS using Lighthouse Storage.
Note: Ensure you have Node.js installed. If not, download it here
Install Lighthouse SDK and Create Wallet:
Install the SDK globally:
npm install -g @lighthouse-web3/sdk
Create a new Lighthouse wallet, which will provide you with a Public Key and a Private Key. Ensure you safely store this information:
lighthouse-web3 create-wallet
Obtain Lighthouse API Key:
Generate a new API key:
lighthouse-web3 api-key --new
You will be presented with an API key. Store this securely and avoid sharing it.
Environment Setup for Your Project:
Create a new directory for your project:
mkdir lighthouse-encryption && cd lighthouse-encryption
Initialize a new Node.js project:
npm init -y
Install required local dependencies:
npm install dotenv ethers
Within your project directory, create a .env file.
Inside .env, add your Lighthouse API key and private key:
API_KEY=Your_Lighthouse_API_Key
PRIVATE_KEY=Your_Private_Key
Always ensure your .env file is added to .gitignore to prevent exposing your credentials, especially if you're using a version control system.
Set up a script, upload.js, in your project directory. Add the following code:
import * as dotenv from 'dotenv';
dotenv.config();
import { ethers } from "ethers";
import lighthouse from '@lighthouse-web3/sdk';
const signAuthMessage = async (publicKey, privateKey) => {
const provider = new ethers.JsonRpcProvider();
const signer = new ethers.Wallet(privateKey, provider);
const messageRequested = (await lighthouse.getAuthMessage(publicKey)).data.message;
const signedMessage = await signer.signMessage(messageRequested);
return signedMessage;
}
const deployEncrypted = async () => {
const path = "Absolute/path/to/your/file.txt"; // Update this path
const apiKey = process.env.API_KEY;
const publicKey = "Your_Public_Key"; // Update this
const privateKey = process.env.PRIVATE_KEY;
const signedMessage = await signAuthMessage(publicKey, privateKey);
const response = await lighthouse.uploadEncrypted(
path,
apiKey,
publicKey,
signedMessage
);
console.log(response);
}
deployEncrypted();
Run the script:
node upload.js
Expected Response:
{
data: [
{
Name: 'test.txt',
Hash: 'ENCRYPTED_CID',
Size: '58'
}
]
}
Create a script, access-control.js, with the following:
import * as dotenv from 'dotenv';
dotenv.config();
import { ethers } from "ethers";
import lighthouse from '@lighthouse-web3/sdk';
const signAuthMessage = async (publicKey, privateKey) => {
const provider = new ethers.JsonRpcProvider();
const signer = new ethers.Wallet(privateKey, provider);
const messageRequested = (await lighthouse.getAuthMessage(publicKey)).data.message;
const signedMessage = await signer.signMessage(messageRequested);
return signedMessage;
}
const accessControl = async () => {
try{
const cid = "Your_File_CID";
// Update this with the CID from the previous step
const publicKey = "Your_Public_Key"; // Update this
const privateKey = process.env.PRIVATE_KEY;
const conditions = [
{
id: 1,
chain: "Optimism",
method: "getBlockNumber",
standardContractType: "",
returnValueTest: { comparator: ">", value: "Your_Block_Number" }, // Update this value as per your requirements
},
];
// Aggregator is what kind of operation to apply to access conditions
// Suppose there are two conditions then you can apply ([1] and [2]), ([1] or [2]), !([1] and [2]).
const aggregator = "([1])";
const signedMessage = await signAuthMessage(publicKey, privateKey);
const response = await lighthouse.applyAccessCondition(
publicKey,
cid,
signedMessage,
conditions,
aggregator
);
console.log(response);
}
accessControl();
Execute the script:
node access-control.js
Expected Response:
{
data: {
cid: 'ENCRYPTED_CID',
status: 'Success'
}
}
Note:
Formulate another script, get-conditions.js, as:
import lighthouse from '@lighthouse-web3/sdk';
const accessConditions = async() => {
const cid = "Your_File_CID"; // Update this
const response = await lighthouse.getAccessConditions(cid);
console.log("Condition:", response.data.conditions);
console.log("Response:", response)
}
accessConditions();
Run the script:
node get-conditions.js
Expected Response:
Condition: [
{
id: 1,
chain: 'Optimism',
method: 'getBlockNumber',
standardContractType: '',
returnValueTest: { comparator: '>', value: 'Your_Block_Number' }
}
]
Response: {
data: {
aggregator: '[1]',
conditions: [ [Object] ],
conditionsSolana: [],
sharedTo: [],
owner: 'Your_Public_Key',
cid: 'ENCRYPTED_CID'
}
}
Once you've uploaded a file and set an access control condition, before attempting to download or decrypt it, you might want to check if you have the necessary permissions (or if the conditions have been met). This step will guide you on how to do just that:
Prepare Your Script:
Create a new script named verify-access.js in your project directory. Insert the following code:
import * as dotenv from 'dotenv';
dotenv.config();
import { ethers } from "ethers";
import lighthouse from '@lighthouse-web3/sdk';
const signAuthMessage = async (publicKey, privateKey) => {
const provider = new ethers.JsonRpcProvider();
const signer = new ethers.Wallet(privateKey, provider);
const messageRequested = (await lighthouse.getAuthMessage(publicKey)).data.message;
const signedMessage = await signer.signMessage(messageRequested);
return signedMessage;
}
const getFileEncryptionKey = async () => {
try {
const cid = 'ENCRYPTED_CID'; // Replace with your CID
const publicKey = 'Receiver_side_public_key'; // Replace with your public key
const privateKey = process.env.RECEIVER_SIDE_PRIVATE_KEY;
const signedMessage = await signAuthMessage(publicKey, privateKey);
const keyResponse = await lighthouse.fetchEncryptionKey(
cid,
publicKey,
signedMessage
);
// Print the direct response
console.log(keyResponse);
} catch (error) {
console.log("Error:", error.message);
}
}
getFileEncryptionKey();
Run the Script:
Execute the verify-access.js script:
node verify-access.js
Expected Response (When you have access):
{
data: {
key: 'KEY'
}
}
Expected Response (When you do not have access):
{ message: "you don't have access", data: {} }
By following this tutorial, you've encrypted a file on Lighthouse Storage and set a time-lock condition using the Optimism blockchain's block number. Before sharing or deploying any code, always remember to secure your private and API keys.
To know more join our discord and get in touch with our team. Follow Lighthouse on X.
Our Blogs
Read our latest blog
Nandit Mehra
Encryption and Access Control for Web3 using Lighthouse
Lighthouse
How To Migrate Your Files To Lighthouse
Nandit Mehra
Decentralized storage for the Ocean Protocol
Ravish Sharma
Creating a Pay-to-View Model Using Lighthouse Storage
Aryaman Raj
Getting Started with Lighthouse Python SDK
Aryaman Raj
A Comprehensive Guide to Publishing and Updating Content with Lighthouse IPNS
Aryaman Raj, Nandit Mehra
Time Lock Encryption using Lighthouse Access Control
Aryaman Raj
Secure File Sharing using Lighthouse SDK: A Step-by-Step Guide
Aryaman Raj
Passkey Demo App with WebAuthn and Ethereum
Ishika Rathi
Web3 Storage: IPFS and Filecoin Guide
Ishika Rathi
Understanding How web3 storage Operates
Ishika Rathi
Lighthouse: Secure Web3 Storage for Your AI Data
Ishika Rathi
Decentralized Storage: A Smarter, Safer, and Cheaper Way to Manage Your Data
Ishika Rathi
Unveiling the Mechanics of Perpetual Storage
Ishika Rathi
Navigating Permanent Storage: Harnessing the Power of Filecoin and IPFS
Ishika Rathi
Decentralized Excellence: Elevating Data Storage with Lighthouse
Ishika Rathi
Revolutionizing Permanence in Data Storage
Ishika Rathi
Eternalizing Data: A Permanent storage
Ishika Rathi
Exploring Web3 Advancements in Storage Solutions
Ishika Rathi
NFT Storage Strategies
Ishika Rathi
On-Chain Encryption: Security Unveiled
BananaCircle
Web2 Storage Challenges Versus Web3 Solutions Ft. Lighthouse
Nandit Mehra
Discover How the Endowment Pool Makes Your Data Immortal
Nandit Mehra
What is FHE and how Lighthouse plans to use it
Nandit Mehra
AI Meets Blockchain: Beyond the Hype & Into the Future
Nandit Mehra
August at Lighthouse: Milestones & Innovations
Nandit Mehra
September at Lighthouse: Milestones & Innovations
Nandit Mehra
October at Lighthouse: Milestones & Innovations
Nandit Mehra
November at Lighthouse: Milestones & Innovations
Nandit Mehra
The Role of Blockchain in AI & Data Storage: A Decentralized Future for Technology
Nandit Mehra
Lighthouse Monthly Update – January 2025