Socket
Socket
Sign inDemoInstall

@celo/utils

Package Overview
Dependencies
Maintainers
0
Versions
144
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@celo/utils - npm Package Compare versions

Comparing version 6.0.1 to 7.0.0-beta.0

2

lib/ecdh.d.ts

@@ -5,3 +5,3 @@ /// <reference types="node" />

export declare function ensureCompressed(publicKey: string): string;
export declare function ensureUncompressed(publicKey: string): any;
export declare function ensureUncompressed(publicKey: string): Uint8Array;
export declare function trimUncompressedPrefix(publicKey: string): string;

@@ -5,7 +5,5 @@ "use strict";

const address_1 = require("@celo/base/lib/address");
const crypto_1 = require("crypto");
const secp256k1_1 = require("@noble/curves/secp256k1");
function computeSharedSecret(privateKey, publicKey) {
const ecdh = (0, crypto_1.createECDH)('secp256k1');
ecdh.setPrivateKey(Buffer.from((0, address_1.trimLeading0x)(privateKey), 'hex'));
return ecdh.computeSecret(Buffer.from(ensureCompressed(publicKey), 'hex'));
return Buffer.from(secp256k1_1.secp256k1.getSharedSecret(Buffer.from((0, address_1.trimLeading0x)(privateKey), 'hex'), Buffer.from(ensureCompressed(publicKey), 'hex')));
}

@@ -22,8 +20,3 @@ exports.computeSharedSecret = computeSharedSecret;

function ensureCompressed(publicKey) {
// NOTE: elliptic is disabled elsewhere in this library to prevent
// accidental signing of truncated messages.
// tslint:disable-next-line:import-blacklist
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
return ec.keyFromPublic(ensureUncompressedPrefix(publicKey), 'hex').getPublic(true, 'hex');
return Buffer.from(secp256k1_1.secp256k1.getSharedSecret(BigInt(1), Buffer.from(publicKey, 'hex'))).toString('hex');
}

@@ -33,11 +26,3 @@ exports.ensureCompressed = ensureCompressed;

const noLeading0x = (0, address_1.trimLeading0x)(publicKey);
// NOTE: elliptic is disabled elsewhere in this library to prevent
// accidental signing of truncated messages.
// tslint:disable-next-line:import-blacklist
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const uncompressed = ec
.keyFromPublic(ensureUncompressedPrefix(noLeading0x), 'hex')
.getPublic(false, 'hex');
return uncompressed;
return secp256k1_1.secp256k1.getSharedSecret(BigInt(1), Buffer.from(noLeading0x, 'hex'), false);
}

@@ -53,9 +38,2 @@ exports.ensureUncompressed = ensureUncompressed;

exports.trimUncompressedPrefix = trimUncompressedPrefix;
function ensureUncompressedPrefix(publicKey) {
const noLeading0x = (0, address_1.trimLeading0x)(publicKey);
if (noLeading0x.length === 128) {
return `04${noLeading0x}`;
}
return noLeading0x;
}
//# sourceMappingURL=ecdh.js.map
/// <reference types="node" />
import { PrivKey } from '@noble/curves/abstract/utils';
import { PubKey } from '@noble/curves/abstract/weierstrass';
export declare const IV_LENGTH = 16;
/**
* NIST 8000-56C Rev 1 One Step KDF with the following parameters:
* - H(x) is SHA-256(x)
* - Fixed info is null
*
* TODO:
* - Implement proper ceiling on reps.
*
* @param {Buffer} px Input keying material to derive key from.
* @param {number} kdLen Length of output in bytes
* @returns {Buffer} Output keying material of length kdLen bytes.
*/
export declare const ConcatKDF: (px: Buffer, kdLen: number) => Buffer;
/**
* AES-128 CTR encrypt
* @param {Buffer} encryptionKey
* @param {Buffer} iv
* @param {Buffer} plaintext
* @returns {Buffer} ciphertext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} iv
* @param {Uint8Array} plaintext
* @returns {Uint8Array} ciphertext
*/
export declare function AES128Encrypt(encryptionKey: Buffer, iv: Buffer, plaintext: Buffer): Buffer;
export declare function AES128Encrypt(encryptionKey: Uint8Array, iv: Uint8Array, plaintext: Uint8Array): Uint8Array;
/**
* AES-128 CTR encrypt with message authentication
* @param {Buffer} encryptionKey
* @param {Buffer} macKey
* @param {Buffer} plaintext
* @returns {Buffer} ciphertext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} macKey
*
* @param {Uint8Array} plaintext
* @returns {Uint8Array} ciphertext
*/
export declare function AES128EncryptAndHMAC(encryptionKey: Buffer, macKey: Buffer, plaintext: Buffer): Buffer;
export declare function AES128EncryptAndHMAC(encryptionKey: Uint8Array, macKey: Uint8Array, plaintext: Uint8Array): Uint8Array;
/**
* AES-128 CTR decrypt
* @param {Buffer} encryptionKey
* @param {Buffer} iv
* @param {Buffer} ciphertext
* @returns {Buffer} plaintext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} iv
* @param {Uint8Array} ciphertext
* @returns {Uint8Array} plaintext
*/
export declare function AES128Decrypt(encryptionKey: Buffer, iv: Buffer, ciphertext: Buffer): Buffer;
export declare function AES128Decrypt(encryptionKey: Uint8Array, iv: Uint8Array, ciphertext: Uint8Array): Uint8Array;
/**
* AES-128 CTR decrypt with message authentication
* @param {Buffer} encryptionKey
* @param {Buffer} macKey
* @param {Buffer} ciphertext
* @returns {Buffer} plaintext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} macKey
* @param {Uint8Array} ciphertext
* @returns {Uint8Array} plaintext
*/
export declare function AES128DecryptAndHMAC(encryptionKey: Buffer, macKey: Buffer, ciphertext: Buffer): Buffer;
export declare function AES128DecryptAndHMAC(encryptionKey: Uint8Array, macKey: Uint8Array, ciphertext: Uint8Array): Uint8Array;
/**
* ECIES encrypt
* @param {Buffer} pubKeyTo Ethereum pub key, 64 bytes.
* @param {Buffer} plaintext Plaintext to be encrypted.
* @param {Uint8Array} plaintext Plaintext to be encrypted.
* @returns {Buffer} Encrypted message, serialized, 113+ bytes
*/
export declare function Encrypt(pubKeyTo: Buffer, plaintext: Buffer): Buffer;
export declare function Encrypt(pubKeyTo: PubKey, plaintext: Uint8Array): Buffer;
/**

@@ -48,3 +64,3 @@ * ECIES decrypt

*/
export declare function Decrypt(privKey: Buffer, encrypted: Buffer): Buffer;
export declare function Decrypt(privKey: PrivKey, encrypted: Buffer): Uint8Array;
export declare const ECIES: {

@@ -51,0 +67,0 @@ Encrypt: typeof Encrypt;

@@ -9,4 +9,9 @@ /**

Object.defineProperty(exports, "__esModule", { value: true });
exports.ECIES = exports.Decrypt = exports.Encrypt = exports.AES128DecryptAndHMAC = exports.AES128Decrypt = exports.AES128EncryptAndHMAC = exports.AES128Encrypt = exports.IV_LENGTH = void 0;
const crypto_1 = require("crypto");
exports.ECIES = exports.Decrypt = exports.Encrypt = exports.AES128DecryptAndHMAC = exports.AES128Decrypt = exports.AES128EncryptAndHMAC = exports.AES128Encrypt = exports.ConcatKDF = exports.IV_LENGTH = void 0;
const aes_1 = require("@noble/ciphers/aes");
const utils_1 = require("@noble/ciphers/utils");
const secp256k1_1 = require("@noble/curves/secp256k1");
const hmac_1 = require("@noble/hashes/hmac");
const sha256_1 = require("@noble/hashes/sha256");
const utils_2 = require("@noble/hashes/utils");
exports.IV_LENGTH = 16;

@@ -46,3 +51,3 @@ /**

for (let i = 0; i <= reps; i++) {
const hash = (0, crypto_1.createHash)('sha256');
const hash = sha256_1.sha256.create();
hash.update(counter);

@@ -55,14 +60,14 @@ hash.update(px);

};
exports.ConcatKDF = ConcatKDF;
/**
* AES-128 CTR encrypt
* @param {Buffer} encryptionKey
* @param {Buffer} iv
* @param {Buffer} plaintext
* @returns {Buffer} ciphertext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} iv
* @param {Uint8Array} plaintext
* @returns {Uint8Array} ciphertext
*/
function AES128Encrypt(encryptionKey, iv, plaintext) {
const cipher = (0, crypto_1.createCipheriv)('aes-128-ctr', encryptionKey, iv);
const firstChunk = cipher.update(plaintext);
const secondChunk = cipher.final();
return Buffer.concat([iv, firstChunk, secondChunk]);
const aes = (0, aes_1.ctr)(encryptionKey, iv);
const message = aes.encrypt(plaintext);
return (0, utils_1.u8)(Buffer.concat([iv, message]));
}

@@ -72,12 +77,13 @@ exports.AES128Encrypt = AES128Encrypt;

* AES-128 CTR encrypt with message authentication
* @param {Buffer} encryptionKey
* @param {Buffer} macKey
* @param {Buffer} plaintext
* @returns {Buffer} ciphertext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} macKey
*
* @param {Uint8Array} plaintext
* @returns {Uint8Array} ciphertext
*/
function AES128EncryptAndHMAC(encryptionKey, macKey, plaintext) {
const iv = (0, crypto_1.randomBytes)(exports.IV_LENGTH);
const iv = (0, utils_2.randomBytes)(exports.IV_LENGTH);
const dataToMac = AES128Encrypt(encryptionKey, iv, plaintext);
const mac = (0, crypto_1.createHmac)('sha256', macKey).update(dataToMac).digest();
return Buffer.concat([dataToMac, mac]);
const mac = (0, hmac_1.hmac)(sha256_1.sha256, macKey, dataToMac);
return (0, utils_1.u8)(Buffer.concat([dataToMac, mac]));
}

@@ -87,12 +93,10 @@ exports.AES128EncryptAndHMAC = AES128EncryptAndHMAC;

* AES-128 CTR decrypt
* @param {Buffer} encryptionKey
* @param {Buffer} iv
* @param {Buffer} ciphertext
* @returns {Buffer} plaintext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} iv
* @param {Uint8Array} ciphertext
* @returns {Uint8Array} plaintext
*/
function AES128Decrypt(encryptionKey, iv, ciphertext) {
const cipher = (0, crypto_1.createDecipheriv)('aes-128-ctr', encryptionKey, iv);
const firstChunk = cipher.update(ciphertext);
const secondChunk = cipher.final();
return Buffer.concat([firstChunk, secondChunk]);
const aes = (0, aes_1.ctr)(encryptionKey, iv);
return aes.decrypt(ciphertext);
}

@@ -102,14 +106,14 @@ exports.AES128Decrypt = AES128Decrypt;

* AES-128 CTR decrypt with message authentication
* @param {Buffer} encryptionKey
* @param {Buffer} macKey
* @param {Buffer} ciphertext
* @returns {Buffer} plaintext
* @param {Uint8Array} encryptionKey
* @param {Uint8Array} macKey
* @param {Uint8Array} ciphertext
* @returns {Uint8Array} plaintext
*/
function AES128DecryptAndHMAC(encryptionKey, macKey, ciphertext) {
const iv = ciphertext.slice(0, exports.IV_LENGTH);
const message = ciphertext.slice(exports.IV_LENGTH, ciphertext.length - 32);
const mac = ciphertext.slice(ciphertext.length - 32, ciphertext.length);
const message = ciphertext.slice(exports.IV_LENGTH, ciphertext.length - sha256_1.sha256.outputLen);
const mac = ciphertext.slice(ciphertext.length - sha256_1.sha256.outputLen, ciphertext.length);
const dataToMac = Buffer.concat([iv, message]);
const computedMac = (0, crypto_1.createHmac)('sha256', macKey).update(dataToMac).digest();
if (!mac.equals(computedMac)) {
const computedMac = (0, hmac_1.hmac)(sha256_1.sha256, macKey, dataToMac);
if (!Buffer.from(mac).equals(Buffer.from(computedMac))) {
throw new Error('MAC mismatch');

@@ -120,24 +124,29 @@ }

exports.AES128DecryptAndHMAC = AES128DecryptAndHMAC;
const UNCOMPRESSED_KEY_LENGTH = 65;
/**
* ECIES encrypt
* @param {Buffer} pubKeyTo Ethereum pub key, 64 bytes.
* @param {Buffer} plaintext Plaintext to be encrypted.
* @param {Uint8Array} plaintext Plaintext to be encrypted.
* @returns {Buffer} Encrypted message, serialized, 113+ bytes
*/
function Encrypt(pubKeyTo, plaintext) {
// NOTE: elliptic is disabled elsewhere in this library to prevent
// accidental signing of truncated messages.
// tslint:disable-next-line:import-blacklist
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const ephemPrivKey = ec.keyFromPrivate((0, crypto_1.randomBytes)(32));
const ephemPubKey = ephemPrivKey.getPublic(false, 'hex');
const ephemPubKeyEncoded = Buffer.from(ephemPubKey, 'hex');
const px = ephemPrivKey.derive(ec.keyFromPublic(Buffer.concat([Buffer.from([0x04]), pubKeyTo])).getPublic());
const hash = ConcatKDF(px.toArrayLike(Buffer), 32);
const encryptionKey = hash.slice(0, 16);
const macKey = (0, crypto_1.createHash)('sha256').update(hash.slice(16)).digest();
const message = AES128EncryptAndHMAC(encryptionKey, macKey, plaintext);
const ephemPrivKey = secp256k1_1.secp256k1.utils.randomPrivateKey();
const ephemPubKey = Buffer.from(secp256k1_1.secp256k1.getPublicKey(ephemPrivKey, false));
const ephemPubKeyEncoded = Buffer.from(ephemPubKey);
if (typeof pubKeyTo === 'string') {
pubKeyTo = secp256k1_1.secp256k1.ProjectivePoint.fromHex(pubKeyTo).toRawBytes();
}
const pubKeyToEncoded = Buffer.concat([Buffer.from([0x04]), pubKeyTo]);
const px = secp256k1_1.secp256k1.getSharedSecret(ephemPrivKey, pubKeyToEncoded).slice(1);
// NOTE:
// Can't swap to proper hkdf implementation because then there's ALWAYS a mac mismatch
// for OLD comments. Maybe we should use a comment version?
//
// const hash = hkdf(sha256, px, undefined, undefined, 32)
const hash = (0, exports.ConcatKDF)(Buffer.from(px), 32);
const encryptionKey = hash.subarray(0, 16);
const macKey = sha256_1.sha256.create().update(hash.subarray(16)).digest();
const message = AES128EncryptAndHMAC(Buffer.from(encryptionKey), macKey, plaintext);
const serializedCiphertext = Buffer.concat([
ephemPubKeyEncoded, // 65 bytes
ephemPubKeyEncoded, // {UNCOMPRESSED_KEY_LENGTH} bytes
message, // iv + ciphertext + mac (min 48 bytes)

@@ -156,16 +165,15 @@ ]);

// Read iv, ephemPubKey, mac, ciphertext from encrypted message
const ephemPubKeyEncoded = encrypted.slice(0, 65);
const symmetricEncrypted = encrypted.slice(65);
// NOTE: elliptic is disabled elsewhere in this library to prevent
// accidental signing of truncated messages.
// tslint:disable-next-line:import-blacklist
const EC = require('elliptic').ec;
const ec = new EC('secp256k1');
const ephemPubKey = ec.keyFromPublic(ephemPubKeyEncoded).getPublic();
const px = ec.keyFromPrivate(privKey).derive(ephemPubKey);
const hash = ConcatKDF(px.toBuffer(), 32);
const ephemPubKeyEncoded = (0, utils_1.u8)(encrypted).slice(0, UNCOMPRESSED_KEY_LENGTH);
const symmetricEncrypted = (0, utils_1.u8)(encrypted).slice(UNCOMPRESSED_KEY_LENGTH);
const px = secp256k1_1.secp256k1.getSharedSecret(privKey, ephemPubKeyEncoded).slice(1);
// NOTE:
// Can't swap to proper hkdf implementation because then there's ALWAYS a mac mismatch
// for OLD comments. Maybe we should use a comment version?
//
// const hash = hkdf(sha256, px, undefined, undefined, 32)
const hash = (0, exports.ConcatKDF)(Buffer.from(px), 32);
// km, ke
const encryptionKey = hash.slice(0, 16);
const macKey = (0, crypto_1.createHash)('sha256').update(hash.slice(16)).digest();
return AES128DecryptAndHMAC(encryptionKey, macKey, symmetricEncrypted);
const encryptionKey = hash.subarray(0, 16);
const macKey = sha256_1.sha256.create().update(hash.subarray(16)).digest();
return AES128DecryptAndHMAC(Buffer.from(encryptionKey), macKey, symmetricEncrypted);
}

@@ -172,0 +180,0 @@ exports.Decrypt = Decrypt;

@@ -32,3 +32,3 @@ "use strict";

const bignumber_js_1 = __importDefault(require("bignumber.js"));
const rlp = __importStar(require("rlp"));
const rlp = __importStar(require("@ethereumjs/rlp"));
// This file contains utilities that help with istanbul-specific block information.

@@ -50,10 +50,10 @@ // See https://github.com/celo-org/celo-blockchain/blob/master/core/types/istanbul.go

const buffer = Buffer.from(data.replace(/^0x/, ''), 'hex');
const decode = rlp.decode('0x' + buffer.slice(ISTANBUL_EXTRA_VANITY_BYTES).toString('hex'));
const decode = rlp.decode('0x' + buffer.subarray(ISTANBUL_EXTRA_VANITY_BYTES).toString('hex'));
return {
addedValidators: decode[0].map((addr) => (0, util_1.toChecksumAddress)((0, util_1.bufferToHex)(addr))),
addedValidatorsPublicKeys: decode[1].map((key) => '0x' + key.toString('hex')),
removedValidators: bigNumberFromBuffer(decode[2]),
seal: '0x' + decode[3].toString('hex'),
aggregatedSeal: sealFromBuffers(decode[4]),
parentAggregatedSeal: sealFromBuffers(decode[5]),
addedValidators: decode.at(0).map((addr) => (0, util_1.toChecksumAddress)((0, util_1.bufferToHex)(Buffer.from(addr)))),
addedValidatorsPublicKeys: decode.at(1).map((key) => '0x' + Buffer.from(key).toString('hex')),
removedValidators: bigNumberFromBuffer(Buffer.from(decode.at(2))),
seal: '0x' + Buffer.from(decode.at(3)).toString('hex'),
aggregatedSeal: sealFromBuffers(decode.at(4).map(Buffer.from)),
parentAggregatedSeal: sealFromBuffers(decode.at(5).map(Buffer.from)),
};

@@ -60,0 +60,0 @@ }

@@ -31,6 +31,5 @@ "use strict";

const address_1 = require("@celo/base/lib/address");
const util_1 = require("@ethereumjs/util");
const sha3_1 = require("@noble/hashes/sha3");
const utils_1 = require("@noble/hashes/utils");
const bignumber_js_1 = require("bignumber.js");
const keccak_1 = require("ethereum-cryptography/keccak");
const utils_1 = require("ethereum-cryptography/utils");
const t = __importStar(require("io-ts"));

@@ -112,7 +111,7 @@ const web3_eth_abi_1 = __importDefault(require("web3-eth-abi"));

function generateTypedDataHash(typedData) {
return (0, keccak_1.keccak256)(Buffer.concat([
return Buffer.from((0, sha3_1.keccak_256)(Buffer.concat([
Buffer.from('1901', 'hex'),
structHash('EIP712Domain', typedData.domain, typedData.types),
structHash(typedData.primaryType, typedData.message, typedData.types),
]));
])));
}

@@ -165,3 +164,3 @@ exports.generateTypedDataHash = generateTypedDataHash;

function typeHash(primaryType, types) {
return (0, keccak_1.keccak256)((0, utils_1.utf8ToBytes)(encodeType(primaryType, types)));
return Buffer.from((0, sha3_1.keccak_256)((0, utils_1.utf8ToBytes)(encodeType(primaryType, types))));
}

@@ -182,3 +181,3 @@ exports.typeHash = typeHash;

// https://github.com/ethereumjs/ethereumjs-util/blob/7e3be1d97b4e11fbc4924836b8c444e644f643ac/index.js#L155-L183
return (0, keccak_1.keccak256)(Buffer.from(value, 'utf8'));
return Buffer.from((0, sha3_1.keccak_256)(Buffer.from(value, 'utf8')));
}

@@ -188,3 +187,3 @@ if (valueType === 'bytes') {

// Note: keccak throws if the value cannot be converted into a Buffer,
return (0, util_1.toBuffer)((0, keccak_1.keccak256)((0, utils_1.hexToBytes)((0, address_1.trimLeading0x)(value))));
return Buffer.from((0, sha3_1.keccak_256)((0, utils_1.hexToBytes)((0, address_1.trimLeading0x)(value))));
}

@@ -200,3 +199,3 @@ // Encode structs as its hashStruct (e.g. keccak(typeHash || encodeData(struct)) ).

const memberType = (_a = match === null || match === void 0 ? void 0 : match.groups) === null || _a === void 0 ? void 0 : _a.memberType;
return (0, keccak_1.keccak256)(Buffer.concat(value.map((member) => encodeValue(memberType, member, types))));
return Buffer.from((0, sha3_1.keccak_256)(Buffer.concat(value.map((member) => encodeValue(memberType, member, types)))));
}

@@ -221,3 +220,3 @@ throw new Error(`Unrecognized or unsupported type in EIP-712 encoding: ${valueType}`);

function structHash(primaryType, data, types) {
return (0, keccak_1.keccak256)(Buffer.concat([typeHash(primaryType, types), encodeData(primaryType, data, types)]));
return Buffer.from((0, sha3_1.keccak_256)(Buffer.concat([typeHash(primaryType, types), encodeData(primaryType, data, types)])));
}

@@ -224,0 +223,0 @@ exports.structHash = structHash;

{
"name": "@celo/utils",
"version": "6.0.1",
"version": "7.0.0-beta.0",
"description": "Celo common utils",

@@ -10,3 +10,3 @@ "author": "Celo",

"sideEffects": false,
"homepage": "https://celo-sdk-docs.readthedocs.io/en/latest/utils",
"homepage": "https://docs.celo.org/developer/tools",
"repository": "https://github.com/celo-org/developer-tooling/tree/master/packages/sdk/utils",

@@ -26,12 +26,13 @@ "scripts": {

"dependencies": {
"@celo/base": "^6.0.1",
"@celo/base": "^6.1.0-beta.0",
"@ethereumjs/rlp": "^5.0.2",
"@ethereumjs/util": "8.0.5",
"@types/elliptic": "^6.4.9",
"@noble/ciphers": "0.4.1",
"@noble/curves": "1.3.0",
"@noble/hashes": "1.3.3",
"@types/bn.js": "^5.1.0",
"@types/node": "^18.7.16",
"bignumber.js": "^9.0.0",
"elliptic": "^6.5.4",
"ethereum-cryptography": "1.2.0",
"fp-ts": "2.1.1",
"io-ts": "2.0.1",
"rlp": "^2.2.4",
"web3-eth-abi": "1.10.4",

@@ -41,4 +42,4 @@ "web3-utils": "1.10.4"

"devDependencies": {
"@celo/typescript": "0.0.1"
"@celo/typescript": "workspace:^"
}
}

@@ -14,3 +14,3 @@ # @celo/utils

✨ [Suggest a feature](httpsi//github.com/celo-org/developer-tooling/issues/new/choose)
✨ [Suggest a feature](https://github.com/celo-org/developer-tooling/issues/new/choose)

@@ -17,0 +17,0 @@ 🧑‍💻 [Contribute!](/CONTRIBUTING.md)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc