
Security News
Vite Releases Technical Preview of Rolldown-Vite, a Rust-Based Bundler
Vite releases Rolldown-Vite, a Rust-based bundler preview offering faster builds and lower memory usage as a drop-in replacement for Vite.
@lighthouse-web3/kavach
Advanced tools
Encryption SDK: Build your trustless, decentralized and fault resistance Application using distributed key shades with threshold cryptography
Kavach is an encryption SDK that allows you to build your trustless, decentralized and fault-tolerant Applications using distributed key shards with threshold cryptography
Just use your favorite package manager to add `lighthouse-kavach to your project:
yarn add @lighthouse-web3/kavach
npm i @lighthouse-web3/kavach
This method generates randomized key shards
Name | Type | Default | Description |
---|---|---|---|
threshold | number(optional) | 3 | minimum amount of key required to recover master key |
keyCount | number(optional) | 5 | number of shades to be generated (Note: must be greater than or equal to threshold) |
Name | Type | Description |
---|---|---|
masterKey | string | 32 byte string or key |
keyShards | {key:string,index:string}[] | key shards |
import { generate } from "@lighthouse-web3/kavach";
async function main() {
const { masterKey, keyShards } = await generate();
console.log(`masterKey: ${masterKey}`);
console.log(`keyShards:`, keyShards);
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
This method recovers the master key from the shards generated
Name | Type | Description |
---|---|---|
keyShard | {key:string,index:string}[] | minimum amount of key required to recover master key |
Name | Type | Description |
---|---|---|
masterKey | string | 32 byte string or key |
error | ErrorValue | null |
import { generate, recoverKey } from "@lighthouse-web3/kavach";
async function main() {
const { masterKey, keyShards } = await generate();
const { masterKey: recoveredKey } = await recoverKey(keyShards);
console.log(masterKey === recoveredKey); //true
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
shard existing Key into shards
Name | Type | Default | Description |
---|---|---|---|
key | string | 32 byte string or key | |
threshold | number(optional) | 3 | minimum amount of key required to recover master key |
keyCount | number(optional) | 5 | number of shades to be generated (Note: must be greater than or equal to threshold) |
Name | Type | Description |
---|---|---|
isShardable | boolean | return true is the key could be sharded |
keyShards | keyShard[] | shards |
import { shardKey, recoverKey } from "@lighthouse-web3/kavach";
async function main() {
// known key customly generated or from ether random wallet privateKey
// Note: Not all keys are shardable
const knownKey =
"554f886019b74852ab679258eb3cddf72f12f84dd6a946f8afc4283e48cc9467";
const { isShardable, keyShards } = await shardKey(knownKey);
console.log(isShardable); // true
//recover keys from shards
const { masterKey } = await recoverKey(keyShards);
//check if the key recovered was recovered
console.log(masterKey === knownKey); //true
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Backup key to lighthouse's Node
Name | Type | Default | Description |
---|---|---|---|
address | string | address of the owner of the key | |
cid | string | unique id or file CID | |
auth_token | string | signed Message gotten from getAuthMessage/JWT | |
keyShards | Array<{key:string; index:string}> | An array of 5 key shards/ element | |
shareTo | Array< address >(Optional) | [] | An array of address |
Name | Type | Description |
---|---|---|
isSuccess | boolean | return true is saved |
error | ErrorValue | Errors |
import { getAuthMessage, saveShards, generate } from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
const signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
const { masterKey, keyShards } = await generate();
const authMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await saveShards(
signer.address,
"QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH",
signedMessage,
keyShards
);
console.log(error === null); // true;
console.log(isSuccess === true); //true;
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
recover key shards to lighthouse's Node
Name | Type | Default | Description |
---|---|---|---|
address | string | address of the owner of the key | |
cid | string | unique id or file CID | |
auth_token | string | signed Message gotten from getAuthMessage/JWT | |
keyCount | number(optional) | 3 | number of nodes to ping for shards (Note: must be less than or equal to 5) |
dynamicData | object<{[conditionID .parameterName ]: value} >(Optional) | {} | This is used to pass additional or dynamic data like a signature during key recovery with AccessControl |
Name | Type | Description |
---|---|---|
keyShards | Array<{key:string; index:string}> | key shards recovered fromm nodes |
error | ErrorValue | Errors |
import {
getAuthMessage,
saveShards,
generate,
recoverShards,
} from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
const signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
const { masterKey, keyShards } = await generate();
let authMessage = await getAuthMessage(signer.address);
let signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await saveShards(
signer.address,
"QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH",
signedMessage,
keyShards
);
console.log(error === null); // true;
console.log(isSuccess === true); //true;
authMessage = await getAuthMessage(signer.address);
signedMessage = await signer.signMessage(authMessage.message);
//retrieve 3 keys
const { error, shards } = await recoverShards(
signer.address,
cid,
signedMessage,
3
);
console.log(error == null); //true;
console.log(shards.length === 3); // true;
const { masterKey: recoveredKey } = await recoverKey(shards);
console.log(masterKey === recoveredKey); //true
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Share file Key to address
Name | Type | Default | Description |
---|---|---|---|
address | string | address of the owner of the key | |
cid | string | unique id or file CID | |
auth_token | string | signed Message gotten from getAuthMessage/ JWT | |
shareTo | Array< address >(Optional) | [] | An array of address to share file key shards to |
Name | Type | Description |
---|---|---|
isSuccess | boolean | return true if successful |
error | ErrorValue | Errors |
import {
recoverShards,
getAuthMessage,
saveShards,
AuthMessage,
shareToAddress,
generate,
} from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
let signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
let signer2 = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c99"
);
const cid = "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwAV";
const { masterKey, keyShards } = await generate();
//save file
{
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await saveShards(
signer.address,
cid,
signedMessage,
keyShards
);
console.log(error == null); //true;
console.log(isSuccess == true); //true;
}
//share file key to address address
{
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await shareToAddress(
signer.address,
cid,
signedMessage,
[signer2.address]
);
console.log(error == null); // true;
console.log(isSuccess == true); //true;
}
//recover shared from address shared to
{
const authMessage: AuthMessage = await getAuthMessage(signer2.address);
const signedMessage = await signer2.signMessage(authMessage.message);
//retrieve 3 keys
const { error, shards } = await recoverShards(
signer2.address,
cid,
signedMessage,
3
);
console.log(error == null); //true;
console.log(shards.length === 3); // true;
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
revoke access to addresses with direct access
Name | Type | Default | Description |
---|---|---|---|
address | string | address of the owner of the key | |
cid | string | unique id or file CID | |
auth_token | string | signed Message gotten from getAuthMessage /JWT | |
revokeTo | Array< address >(Optional) | [] | An array of address to remove for Direct access |
Name | Type | Description |
---|---|---|
isSuccess | boolean | return true if successful |
error | ErrorValue | Errors |
import {
recoverShards,
getAuthMessage,
saveShards,
AuthMessage,
revokeAccess,
generate,
} from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
let signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
let signer2 = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c99"
);
const cid = "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwVV";
const { masterKey, keyShards } = await generate();
//save file
{
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await saveShards(
signer.address,
cid,
signedMessage,
keyShards,
[
"0x95CF5354519a6ad2bD7e53fe7763201dfB24bFE4",
"0xb46D27B3BfC07D27702EBddbe197Fc9276b70581",
signer2.address,
]
);
console.log(error == null); //true;
console.log(isSuccess == true); //true;
}
//recover shared from address shared to
{
const authMessage: AuthMessage = await getAuthMessage(signer2.address);
const signedMessage = await signer2.signMessage(authMessage.message);
//retrieve 3 keys
const { error, shards } = await recoverShards(
signer2.address,
cid,
signedMessage,
3
);
console.log(error == null); //true;
console.log(shards.length === 3); // true;
}
//revoke access to direct shared address
{
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await revokeAccess(
signer.address,
cid,
signedMessage,
[signer2.address]
);
console.log(error == null); // true;
console.log(isSuccess == true); //true;
}
//recover shared from address shared to
{
const authMessage: AuthMessage = await getAuthMessage(signer2.address);
const signedMessage = await signer2.signMessage(authMessage.message);
//retrieve 3 keys
const { error, shards } = await recoverShards(
signer2.address,
cid,
signedMessage,
3
);
console.log(error); // { message: "you don't have access", data: {} };
console.log(shards.length === 0); // true ;
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Add more granular access Conditions based on on-Chain Data, this supports custom EVM contracts, block timestamps and so on. with support for over 15 Ethereum Virtual Machine (EVM) based networks and based Solana RPC calls
Solana
Name | Type | Description |
---|---|---|
address | string | Address of the owner of the key |
cid | string | Unique id or file CID |
auth_token | string | Signed Message gotten from getAuthMessage /JWT |
conditions | Array< Condition > | This Array contains a list of conditions to be tested on chain |
aggregator | string | This is a template string that structures how the conditions should be computed |
chainType | string | This defaults to EVM and can be set to Solana for Solana conditions |
keyShards? | Array<{key:string; index:string}> | This Field is optional, you can use it to set, overWrite or rotate key shards |
decryptionType? | string | This value can be set to ACCESS_CONDITIONS to first time shard is added, WARNING: This sets Owner to address zero(0x0000000000000000000000000000) |
Name | Type | Description |
---|---|---|
isSuccess | boolean | return true if successful |
error | ErrorValue | Errors |
import {
recoverShards,
getAuthMessage,
saveShards,
AuthMessage,
accessControl,
generate,
} from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
let signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
let signer2 = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c99"
);
const cid = "QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwVM";
//save file
{
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { masterKey, keyShards } = await generate();
const { error, isSuccess } = await saveShards(
signer.address,
cid,
signedMessage,
keyShards
);
console.log(error == null); //true;
console.log(isSuccess == true); //true;
}
// add access control to cid direct shared address
{
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { error, isSuccess } = await accessControl(
signer.address,
cid,
signedMessage,
[
{
id: 3,
chain: "Polygon",
method: "getBlockNumber",
standardContractType: "",
returnValueTest: { comparator: ">=", value: "0" },
},
{
id: 2,
chain: "Optimism",
method: "getBalance",
standardContractType: "",
returnValueTest: { comparator: ">=", value: "0" },
},
{
id: 1,
chain: "FantomTest",
method: "balanceOf",
standardContractType: "ERC20",
contractAddress: "0xF0Bc72fA04aea04d04b1fA80B359Adb566E1c8B1",
returnValueTest: { comparator: ">=", value: "0" },
parameters: [":userAddress"],
},
],
"([2] and [1]) or [3]"
);
console.log(error == null);
console.log(isSuccess == true);
}
// recover shared from an address that matches the above condition
// that is
// has a balance equal to or greater than Zero on the Optimism mainnet and has a token balance greater than equal to zero of the token 0xF0Bc72fA04aea04d04b1fA80B359Adb566E1c8B1 on fantom's testnet
// or if block height is greater than zero
{
const authMessage: AuthMessage = await getAuthMessage(signer2.address);
const signedMessage = await signer2.signMessage(authMessage.message);
console.log(signer2.address);
//retrieve 3 keys
const { error, shards } = await recoverShards(
signer2.address,
cid,
signedMessage,
3,
dynamicData
);
console.log(error == null); //true;
console.log(shards.length === 3); // true;
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Get Consensus Message to Sign
Name | Type | Default | Description |
---|---|---|---|
address | string | address of the owner of the key |
Name | Type | Description |
---|---|---|
message | string | return consensus message |
error | ErrorValue | Errors |
import { getAuthMessage, AuthMessage } from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
let signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
// get consensus message
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
console.log(typeof authMessage.message == "string"); //true;
console.log(authMessage.error == null); //true;
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Get Consensus Message to Sign
Name | Type | Default | Description |
---|---|---|---|
address | string | address of the owner of the key | |
payload | string | signed consensus message or refresh Token | |
useAsRefreshToken | boolean | false | If payload is refreshToken this should be set to true |
Name | Type | Description |
---|---|---|
JWT | string | return JWT |
refreshToken | string | |
error | ErrorValue | Errors |
import { getAuthMessage, AuthMessage, getJWT } from "@lighthouse-web3/kavach";
import { ethers } from "ethers";
async function main() {
let signer = new ethers.Wallet(
"0x8218aa5dbf4dbec243142286b93e26af521b3e91219583595a06a7765abc9c8b"
);
// get consensus message
const authMessage: AuthMessage = await getAuthMessage(signer.address);
const signedMessage = await signer.signMessage(authMessage.message);
const { JWT, error } = await getJWT(signer.address, signedMessage);
console.log(typeof JWT == "string"); //true;
console.log(error == null); //true;
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Transfer Ownership of a Resource
Name | Type | Default | Description |
---|---|---|---|
address | string | Address of the current owner of the resource | |
cid | string | Content ID (CID) of the resource | |
newOwner | string | Address of the new owner for the resource | |
auth_token | string | Authentication payload or token | |
resetSharedTo | boolean | true | Reset shared permissions when ownership changes |
Name | Type | Description |
---|---|---|
result | string | Result of the ownership transfer |
error | Error | Any error that occurs |
import { transferOwnership } from "@lighthouse-web3/kavach";
// Example usage of transferOwnership function
async function main() {
const currentOwner = "0x1234567890abcdef";
const resourceId = "QmXyZAbCdEfGhIjK";
const newOwner = "0x9876543210fedcba";
const authPayload = "your-authentication-token";
const { result, error } = await transferOwnership(
currentOwner,
resourceId,
newOwner,
authPayload
);
if (error) {
console.error("Error:", error);
} else {
console.log("Ownership transfer result:", result);
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
FAQs
Encryption SDK: Build your trustless, decentralized and fault resistance Application using distributed key shades with threshold cryptography
The npm package @lighthouse-web3/kavach receives a total of 1,175 weekly downloads. As such, @lighthouse-web3/kavach popularity was classified as popular.
We found that @lighthouse-web3/kavach demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Vite releases Rolldown-Vite, a Rust-based bundler preview offering faster builds and lower memory usage as a drop-in replacement for Vite.
Research
Security News
A malicious npm typosquat uses remote commands to silently delete entire project directories after a single mistyped install.
Research
Security News
Malicious PyPI package semantic-types steals Solana private keys via transitive dependency installs using monkey patching and blockchain exfiltration.