Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@cardano-foundation/ledgerjs-hw-app-cardano

Package Overview
Dependencies
Maintainers
3
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cardano-foundation/ledgerjs-hw-app-cardano - npm Package Compare versions

Comparing version 2.1.0 to 2.2.0

172

lib/cardano.js

@@ -10,2 +10,4 @@ "use strict";

exports.serializeAddressParams = serializeAddressParams;
exports.serializeOutputBasicParams = serializeOutputBasicParams;
exports.serializeOutputBasicParamsBefore_2_2 = serializeOutputBasicParamsBefore_2_2;
exports.serializePoolInitialParams = serializePoolInitialParams;

@@ -16,3 +18,3 @@ exports.serializePoolOwnerParams = serializePoolOwnerParams;

exports.serializeGetExtendedPublicKeyParams = serializeGetExtendedPublicKeyParams;
exports["default"] = exports.TxErrors = exports.GetKeyErrors = exports.CertificateTypes = exports.AddressTypeNibbles = void 0;
exports["default"] = exports.TxErrors = exports.GetKeyErrors = exports.SignTxIncluded = exports.CertificateTypes = exports.AddressTypeNibbles = void 0;

@@ -47,4 +49,13 @@ var _utils = _interopRequireWildcard(require("./utils"));

exports.CertificateTypes = CertificateTypes;
var SignTxIncluded = Object.freeze({
SIGN_TX_INCLUDED_NO: 1,
SIGN_TX_INCLUDED_YES: 2
});
exports.SignTxIncluded = SignTxIncluded;
var KEY_HASH_LENGTH = 28;
var TX_HASH_LENGTH = 32;
var TOKEN_POLICY_LENGTH = 28;
var TOKEN_NAME_LENGTH = 32;
var ASSET_GROUPS_MAX = 1000;
var TOKENS_IN_GROUP_MAX = 1000;
var POOL_REGISTRATION_OWNERS_MAX = 1000;

@@ -64,2 +75,5 @@ var POOL_REGISTRATION_RELAYS_MAX = 1000;

OUTPUT_INVALID_AMOUNT: "invalid amount in an output",
OUTPUT_INVALID_TOKEN_BUNDLE: "invalid multiasset token bundle in an output",
OUTPUT_INVALID_TOKEN_POLICY: "invalid multiasset token policy",
OUTPUT_INVALID_ASSET_NAME: "invalid asset name in the token bundle in an output",
OUTPUT_INVALID_ADDRESS: "invalid address in an output",

@@ -89,2 +103,3 @@ OUTPUT_WITH_PATH: "outputs given by path are not allowed for stake pool registration transactions",

CERTIFICATE_POOL_INVALID_MARGIN: "invalid margin in a pool registration certificate",
CERTIFICATE_POOL_INVALID_MARGIN_DENOMINATOR: "pool margin denominator must be a value between 1 and 10^15",
CERTIFICATE_POOL_INVALID_REWARD_ACCOUNT: "invalid reward account in a pool registration certificate",

@@ -109,3 +124,4 @@ CERTIFICATE_POOL_OWNERS_NOT_ARRAY: "owners not an array in a pool registration certificate",

WITHDRAWALS_FORBIDDEN: "no withdrawals allowed for transactions registering stake pools",
METADATA_INVALID: "invalid metadata"
METADATA_INVALID: "invalid metadata",
VALIDITY_INTERVAL_START_INVALID: "invalid validity interval start"
};

@@ -234,3 +250,3 @@ exports.TxErrors = TxErrors;

function validateTransaction(networkId, protocolMagic, inputs, outputs, feeStr, ttlStr, certificates, withdrawals, metadataHashHex) {
function validateTransaction(networkId, protocolMagic, inputs, outputs, feeStr, ttlStr, certificates, withdrawals, metadataHashHex, validityIntervalStartStr) {
_utils.Precondition.checkIsArray(certificates, TxErrors.CERTIFICATES_NOT_ARRAY);

@@ -276,16 +292,53 @@

var output = _step5.value;
// we try to serialize the data, an error is thrown if ada amount or address params are invalid
serializeOutputBasicParams(output, protocolMagic, networkId);
_utils.Precondition.checkIsValidAmount(output.amountStr, TxErrors.OUTPUT_INVALID_AMOUNT);
if (output.spendingPath) {
_utils.Precondition.check(!isSigningPoolRegistrationAsOwner, TxErrors.OUTPUT_WITH_PATH);
}
if (output.addressHex) {
_utils.Precondition.checkIsHexString(output.addressHex, TxErrors.OUTPUT_INVALID_ADDRESS);
if (output.tokenBundle) {
_utils.Precondition.checkIsArray(output.tokenBundle, TxErrors.OUTPUT_INVALID_TOKEN_BUNDLE);
_utils.Precondition.check(output.addressHex.length <= 128 * 2, TxErrors.OUTPUT_INVALID_ADDRESS);
} else if (output.spendingPath) {
_utils.Precondition.check(!isSigningPoolRegistrationAsOwner, TxErrors.OUTPUT_WITH_PATH); // we try to serialize the data, an error is thrown if output params are invalid
_utils.Precondition.check(output.tokenBundle.length <= ASSET_GROUPS_MAX);
var _iterator7 = _createForOfIteratorHelper(output.tokenBundle),
_step7;
serializeAddressParams(output.addressTypeNibble, output.addressTypeNibble === AddressTypeNibbles.BYRON ? protocolMagic : networkId, output.spendingPath, output.stakingPath, output.stakingKeyHashHex, output.stakingBlockchainPointer);
} else {
throw new Error(TxErrors.OUTPUT_UNKNOWN_TYPE);
try {
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
var assetGroup = _step7.value;
_utils.Precondition.checkIsHexString(assetGroup.policyIdHex, TxErrors.OUTPUT_INVALID_TOKEN_POLICY);
_utils.Precondition.check(assetGroup.policyIdHex.length === TOKEN_POLICY_LENGTH * 2, TxErrors.OUTPUT_INVALID_TOKEN_POLICY);
_utils.Precondition.checkIsArray(assetGroup.tokens);
_utils.Precondition.check(assetGroup.tokens.length <= TOKENS_IN_GROUP_MAX);
var _iterator8 = _createForOfIteratorHelper(assetGroup.tokens),
_step8;
try {
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
var token = _step8.value;
_utils.Precondition.checkIsHexString(token.assetNameHex, TxErrors.OUTPUT_INVALID_ASSET_NAME);
_utils.Precondition.check(token.assetNameHex.length <= TOKEN_NAME_LENGTH * 2, TxErrors.OUTPUT_INVALID_ASSET_NAME);
_utils.Precondition.checkIsUint64Str(token.amountStr);
}
} catch (err) {
_iterator8.e(err);
} finally {
_iterator8.f();
}
}
} catch (err) {
_iterator7.e(err);
} finally {
_iterator7.f();
}
}

@@ -300,12 +353,10 @@ } // fee

_utils.Precondition.checkIsValidAmount(feeStr, TxErrors.FEE_INVALID); // ttl
_utils.Precondition.checkIsValidAdaAmount(feeStr, TxErrors.FEE_INVALID); // ttl
var ttl = _utils["default"].safe_parseInt(ttlStr);
if (ttlStr != null) {
_utils.Precondition.checkIsPositiveUint64Str(ttlStr, TxErrors.TTL_INVALID);
} // certificates
_utils.Precondition.checkIsUint64(ttl, TxErrors.TTL_INVALID);
_utils.Precondition.check(ttl > 0, TxErrors.TTL_INVALID); // certificates
validateCertificates(certificates); // withdrawals

@@ -326,3 +377,3 @@

_utils.Precondition.checkIsValidAmount(withdrawal.amountStr);
_utils.Precondition.checkIsValidAdaAmount(withdrawal.amountStr);

@@ -338,6 +389,11 @@ _utils.Precondition.checkIsValidPath(withdrawal.path);

if (metadataHashHex !== null && metadataHashHex !== undefined) {
if (metadataHashHex != null) {
_utils.Precondition.checkIsHexString(metadataHashHex, TxErrors.METADATA_INVALID);
_utils.Precondition.check(metadataHashHex.length == 32 * 2, TxErrors.METADATA_INVALID);
} // validity interval start
if (validityIntervalStartStr != null) {
_utils.Precondition.checkIsPositiveUint64Str(validityIntervalStartStr, TxErrors.VALIDITY_INTERVAL_START_INVALID);
}

@@ -421,2 +477,44 @@ }

function serializeOutputBasicParams(output, protocolMagic, networkId) {
_utils.Precondition.checkIsValidAdaAmount(output.amountStr);
var outputType;
var addressBuf;
if (output.addressHex) {
outputType = _Ada.TxOutputTypeCodes.SIGN_TX_OUTPUT_TYPE_ADDRESS_BYTES;
_utils.Precondition.checkIsHexString(output.addressHex, TxErrors.OUTPUT_INVALID_ADDRESS);
_utils.Precondition.check(output.addressHex.length <= 128 * 2, TxErrors.OUTPUT_INVALID_ADDRESS);
addressBuf = Buffer.concat([_utils["default"].uint32_to_buf(output.addressHex.length / 2), _utils["default"].hex_to_buf(output.addressHex)]);
} else if (output.spendingPath) {
outputType = _Ada.TxOutputTypeCodes.SIGN_TX_OUTPUT_TYPE_ADDRESS_PARAMS;
addressBuf = serializeAddressParams(output.addressTypeNibble, output.addressTypeNibble === AddressTypeNibbles.BYRON ? protocolMagic : networkId, output.spendingPath, output.stakingPath, output.stakingKeyHashHex, output.stakingBlockchainPointer);
} else {
throw new Error(TxErrors.OUTPUT_UNKNOWN_TYPE);
}
var numassetGroups = output.tokenBundle ? output.tokenBundle.length : 0;
return Buffer.concat([_utils["default"].uint8_to_buf(outputType), addressBuf, _utils["default"].ada_amount_to_buf(output.amountStr), _utils["default"].uint32_to_buf(numassetGroups)]);
} // TODO remove after ledger app 2.2 is widespread
function serializeOutputBasicParamsBefore_2_2(output, protocolMagic, networkId) {
_utils.Precondition.checkIsValidAdaAmount(output.amountStr);
if (output.addressHex) {
_utils.Precondition.checkIsHexString(output.addressHex, TxErrors.OUTPUT_INVALID_ADDRESS);
_utils.Precondition.check(output.addressHex.length <= 128 * 2, TxErrors.OUTPUT_INVALID_ADDRESS);
return Buffer.concat([_utils["default"].ada_amount_to_buf(output.amountStr), _utils["default"].uint8_to_buf(_Ada.TxOutputTypeCodes.SIGN_TX_OUTPUT_TYPE_ADDRESS_BYTES), _utils["default"].hex_to_buf(output.addressHex)]);
} else if (output.spendingPath) {
return Buffer.concat([_utils["default"].ada_amount_to_buf(output.amountStr), _utils["default"].uint8_to_buf(_Ada.TxOutputTypeCodes.SIGN_TX_OUTPUT_TYPE_ADDRESS_PARAMS), serializeAddressParams(output.addressTypeNibble, output.addressTypeNibble === AddressTypeNibbles.BYRON ? protocolMagic : networkId, output.spendingPath, output.stakingPath, output.stakingKeyHashHex, output.stakingBlockchainPointer)]);
} else {
throw new Error(TxErrors.OUTPUT_UNKNOWN_TYPE);
}
}
function serializePoolInitialParams(params) {

@@ -431,20 +529,16 @@ _utils.Precondition.checkIsHexString(params.poolKeyHashHex, TxErrors.CERTIFICATE_POOL_INVALID_POOL_KEY_HASH);

_utils.Precondition.checkIsValidAmount(params.pledgeStr, TxErrors.CERTIFICATE_POOL_INVALID_PLEDGE);
_utils.Precondition.checkIsValidAdaAmount(params.pledgeStr, TxErrors.CERTIFICATE_POOL_INVALID_PLEDGE);
_utils.Precondition.checkIsValidAmount(params.costStr, TxErrors.CERTIFICATE_POOL_INVALID_COST);
_utils.Precondition.checkIsValidAdaAmount(params.costStr, TxErrors.CERTIFICATE_POOL_INVALID_COST);
var marginNumerator = _utils["default"].safe_parseInt(params.margin.numeratorStr);
var marginNumeratorStr = params.margin.numeratorStr;
var marginDenominatorStr = params.margin.denominatorStr;
_utils.Precondition.checkIsUint64(marginNumerator, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
_utils.Precondition.checkIsUint64Str(marginNumeratorStr, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
var marginDenominator = _utils["default"].safe_parseInt(params.margin.denominatorStr);
_utils.Precondition.checkIsValidPoolMarginDenominator(marginDenominatorStr, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN_DENOMINATOR); // given both are valid uint strings, the check below is equivalent to "marginNumerator <= marginDenominator"
_utils.Precondition.checkIsUint64(marginDenominator, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
_utils.Precondition.check(marginNumerator >= 0, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
_utils.Precondition.checkIsValidUintStr(marginNumeratorStr, marginDenominatorStr, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
_utils.Precondition.check(marginDenominator > 0, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
_utils.Precondition.check(marginNumerator <= marginDenominator, TxErrors.CERTIFICATE_POOL_INVALID_MARGIN);
_utils.Precondition.checkIsHexString(params.rewardAccountHex, TxErrors.CERTIFICATE_POOL_INVALID_REWARD_ACCOUNT);

@@ -458,4 +552,3 @@

return Buffer.concat([_utils["default"].hex_to_buf(params.poolKeyHashHex), _utils["default"].hex_to_buf(params.vrfKeyHashHex), _utils["default"].amount_to_buf(params.pledgeStr), _utils["default"].amount_to_buf(params.costStr), _utils["default"].amount_to_buf(params.margin.numeratorStr), // TODO why amount? ... we should have uint64_to_buf?
_utils["default"].amount_to_buf(params.margin.denominatorStr), _utils["default"].hex_to_buf(params.rewardAccountHex), _utils["default"].uint32_to_buf(params.poolOwners.length), _utils["default"].uint32_to_buf(params.relays.length)]);
return Buffer.concat([_utils["default"].hex_to_buf(params.poolKeyHashHex), _utils["default"].hex_to_buf(params.vrfKeyHashHex), _utils["default"].ada_amount_to_buf(params.pledgeStr), _utils["default"].ada_amount_to_buf(params.costStr), _utils["default"].uint64_to_buf(params.margin.numeratorStr), _utils["default"].uint64_to_buf(params.margin.denominatorStr), _utils["default"].hex_to_buf(params.rewardAccountHex), _utils["default"].uint32_to_buf(params.poolOwners.length), _utils["default"].uint32_to_buf(params.relays.length)]);
}

@@ -597,12 +690,9 @@

function serializePoolMetadataParams(params) {
var POOL_CERTIFICATE_METADATA_NO = 1;
var POOL_CERTIFICATE_METADATA_YES = 2;
var includeMetadataBuffer = Buffer.alloc(1);
if (params === null || params === undefined) {
// deal with null metadata
includeMetadataBuffer.writeUInt8(POOL_CERTIFICATE_METADATA_NO);
if (params != null) {
includeMetadataBuffer.writeUInt8(SignTxIncluded.SIGN_TX_INCLUDED_YES);
} else {
includeMetadataBuffer.writeUInt8(SignTxIncluded.SIGN_TX_INCLUDED_NO);
return includeMetadataBuffer;
} else {
includeMetadataBuffer.writeUInt8(POOL_CERTIFICATE_METADATA_YES);
}

@@ -644,2 +734,4 @@

serializeAddressParams: serializeAddressParams,
serializeOutputBasicParams: serializeOutputBasicParams,
serializeOutputBasicParamsBefore_2_2: serializeOutputBasicParamsBefore_2_2,
serializePoolInitialParams: serializePoolInitialParams,

@@ -646,0 +738,0 @@ serializePoolOwnerParams: serializePoolOwnerParams,

@@ -13,2 +13,3 @@ "use strict";

exports.buf_to_uint32 = buf_to_uint32;
exports.uint64_to_buf = uint64_to_buf;
exports.hex_to_buf = hex_to_buf;

@@ -21,3 +22,3 @@ exports.buf_to_hex = buf_to_hex;

exports.buf_to_amount = buf_to_amount;
exports.amount_to_buf = amount_to_buf;
exports.ada_amount_to_buf = ada_amount_to_buf;
exports.base58_encode = base58_encode;

@@ -30,4 +31,2 @@ exports.base58_decode = base58_decode;

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

@@ -43,4 +42,2 @@

var _Assert$hex_to_buf$bu;
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

@@ -56,5 +53,7 @@

var bs10 = (0, _baseX["default"])("0123456789"); // Max supply in lovelace
var bs10 = (0, _baseX["default"])("0123456789");
var MAX_UINT_64_STR = "18446744073709551615"; // Max supply in lovelace
var MAX_LOVELACE_SUPPLY_STR = ["45", "000", "000", "000", "000000"].join("");
var POOL_MARGIN_DENOMINATOR_MAX_STR = ["1", "000", "000", "000", "000", "000000"].join("");
var TESTNET_NETWORK_ID = 0x00;

@@ -86,8 +85,2 @@ var Precondition = {

// Extended checks
checkIsUint64: function checkIsUint64(data) {
var msg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
Precondition.checkIsInteger(data, msg);
Precondition.check(data >= 0, msg);
Precondition.check(data <= 18446744073709551615, msg);
},
checkIsUint32: function checkIsUint32(data) {

@@ -135,18 +128,36 @@ var msg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;

},
checkIsValidAmount: function checkIsValidAmount(amount) {
checkIsUint64Str: function checkIsUint64Str(data) {
var msg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
Precondition.checkIsString(amount, msg);
Precondition.check(/^[0-9]*$/.test(amount), msg); // Length checks
Precondition.checkIsValidUintStr(data, MAX_UINT_64_STR, msg);
},
checkIsPositiveUint64Str: function checkIsPositiveUint64Str(data) {
var msg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
Precondition.checkIsUint64Str(data, msg);
Precondition.check(data !== "0", msg);
},
checkIsValidAdaAmount: function checkIsValidAdaAmount(amount) {
var msg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
Precondition.checkIsValidUintStr(amount, MAX_LOVELACE_SUPPLY_STR, msg);
},
checkIsValidPoolMarginDenominator: function checkIsValidPoolMarginDenominator(data) {
var msg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
Precondition.checkIsValidUintStr(data, POOL_MARGIN_DENOMINATOR_MAX_STR, msg);
Precondition.check(data !== "0", msg);
},
checkIsValidUintStr: function checkIsValidUintStr(data, maxValue) {
var msg = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
Precondition.checkIsString(data, msg);
Precondition.check(/^[0-9]*$/.test(data), msg); // Length checks
Precondition.check(amount.length > 0, msg);
Precondition.check(amount.length <= MAX_LOVELACE_SUPPLY_STR.length, msg); // Leading zeros
Precondition.check(data.length > 0, msg);
Precondition.check(data.length <= maxValue.length, msg); // Leading zeros
if (amount.length > 1) {
Precondition.check(amount[0] != "0", msg);
} // less than max supply
if (data.length > 1) {
Precondition.check(data[0] != "0", msg);
} // less or equal than max value
if (amount.length === MAX_LOVELACE_SUPPLY_STR.length) {
if (data.length === maxValue.length) {
// Note: this is string comparison!
Precondition.check(amount <= MAX_LOVELACE_SUPPLY_STR, msg);
Precondition.check(data <= maxValue, msg);
}

@@ -234,2 +245,10 @@ },

function uint64_to_buf(value) {
Precondition.checkIsUint64Str(value, "invalid uint64 value");
var data = bs10.decode(value);
Assert.assert(data.length <= 8, "excessive data");
var padding = Buffer.alloc(8 - data.length);
return Buffer.concat([padding, data]);
}
function hex_to_buf(data) {

@@ -337,9 +356,5 @@ Precondition.checkIsHexString(data, "invalid hex string");

function amount_to_buf(amount) {
Precondition.checkIsValidAmount(amount, "invalid amount");
var data = bs10.decode(amount); // Amount should fit uin64_t
Assert.assert(data.length <= 8, "excessive data");
var padding = Buffer.alloc(8 - data.length);
return Buffer.concat([padding, data]);
function ada_amount_to_buf(amount) {
Precondition.checkIsValidAdaAmount(amount, "invalid amount");
return uint64_to_buf(amount);
}

@@ -413,6 +428,8 @@

var _default = (_Assert$hex_to_buf$bu = {
var _default = {
Assert: Assert,
hex_to_buf: hex_to_buf,
buf_to_hex: buf_to_hex,
// no pair for now
uint64_to_buf: uint64_to_buf,
uint32_to_buf: uint32_to_buf,

@@ -427,4 +444,3 @@ buf_to_uint32: buf_to_uint32,

str_to_path: str_to_path,
safe_parseInt: safe_parseInt,
amount_to_buf: amount_to_buf,
ada_amount_to_buf: ada_amount_to_buf,
buf_to_amount: buf_to_amount,

@@ -434,6 +450,8 @@ base58_encode: base58_encode,

bech32_encodeAddress: bech32_encodeAddress,
bech32_decodeAddress: bech32_decodeAddress
}, (0, _defineProperty2["default"])(_Assert$hex_to_buf$bu, "safe_parseInt", safe_parseInt), (0, _defineProperty2["default"])(_Assert$hex_to_buf$bu, "chunkBy", chunkBy), (0, _defineProperty2["default"])(_Assert$hex_to_buf$bu, "stripRetcodeFromResponse", stripRetcodeFromResponse), _Assert$hex_to_buf$bu);
bech32_decodeAddress: bech32_decodeAddress,
safe_parseInt: safe_parseInt,
chunkBy: chunkBy,
stripRetcodeFromResponse: stripRetcodeFromResponse
};
exports["default"] = _default;
//# sourceMappingURL=utils.js.map
{
"name": "@cardano-foundation/ledgerjs-hw-app-cardano",
"version": "2.1.0",
"version": "2.2.0",
"files": [

@@ -5,0 +5,0 @@ "lib"

Sorry, the diff of this file is too big to display

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

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