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

@ledgerhq/coin-algorand

Package Overview
Dependencies
Maintainers
0
Versions
283
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ledgerhq/coin-algorand - npm Package Compare versions

Comparing version 0.5.7-nightly.2 to 0.5.7

7

lib-es/api/algodv2.d.ts
/// <reference types="node" />
import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
import { AlgoAccount, AlgoTransactionParams } from "./algodv2.types";
export declare const getAccount: (address: string) => Promise<AlgoAccount>;
export declare const getTransactionParams: () => Promise<AlgoTransactionParams>;
export declare const broadcastTransaction: (payload: Buffer) => Promise<string>;
export declare const getAccount: (network: NetworkRequestCall) => (address: string) => Promise<AlgoAccount>;
export declare const getTransactionParams: (network: NetworkRequestCall) => () => Promise<AlgoTransactionParams>;
export declare const broadcastTransaction: (network: NetworkRequestCall) => (payload: Buffer) => Promise<string>;
//# sourceMappingURL=algodv2.d.ts.map

@@ -10,3 +10,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import network from "@ledgerhq/live-network";
import { getEnv } from "@ledgerhq/live-env";

@@ -17,4 +16,5 @@ import { BigNumber } from "bignumber.js";

const fullUrl = (route) => `${NODE_URL}${route}`;
export const getAccount = (address) => __awaiter(void 0, void 0, void 0, function* () {
export const getAccount = (network) => (address) => __awaiter(void 0, void 0, void 0, function* () {
const { data } = yield network({
method: "GET",
url: fullUrl(`/accounts/${address}`),

@@ -39,5 +39,6 @@ });

});
export const getTransactionParams = () => __awaiter(void 0, void 0, void 0, function* () {
export const getTransactionParams = (network) => () => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const { data } = yield network({
method: "GET",
url: fullUrl(`/transactions/params`),

@@ -54,3 +55,3 @@ });

});
export const broadcastTransaction = (payload) => __awaiter(void 0, void 0, void 0, function* () {
export const broadcastTransaction = (network) => (payload) => __awaiter(void 0, void 0, void 0, function* () {
const { data } = yield network({

@@ -57,0 +58,0 @@ method: "POST",

@@ -10,2 +10,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import network from "@ledgerhq/live-network/network";
import { broadcastTransaction, getAccount, getTransactionParams } from "./algodv2";

@@ -16,7 +17,7 @@ import { getAccountTransactions } from "./indexer";

export default {
getAccount: (address) => __awaiter(void 0, void 0, void 0, function* () { return getAccount(address); }),
getTransactionParams: () => __awaiter(void 0, void 0, void 0, function* () { return getTransactionParams(); }),
broadcastTransaction: (payload) => __awaiter(void 0, void 0, void 0, function* () { return broadcastTransaction(payload); }),
getAccountTransactions: (address, startAt) => __awaiter(void 0, void 0, void 0, function* () { return getAccountTransactions(address, startAt); }),
getAccount: (address) => __awaiter(void 0, void 0, void 0, function* () { return getAccount(network)(address); }),
getTransactionParams: () => __awaiter(void 0, void 0, void 0, function* () { return getTransactionParams(network)(); }),
broadcastTransaction: (payload) => __awaiter(void 0, void 0, void 0, function* () { return broadcastTransaction(network)(payload); }),
getAccountTransactions: (address, startAt) => __awaiter(void 0, void 0, void 0, function* () { return getAccountTransactions(network)(address, startAt); }),
};
//# sourceMappingURL=index.js.map

@@ -0,3 +1,4 @@

import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
import { AlgoTransaction } from "./indexer.types";
export declare const getAccountTransactions: (address: string, startAt?: number) => Promise<AlgoTransaction[]>;
export declare const getAccountTransactions: (network: NetworkRequestCall) => (address: string, startAt?: number) => Promise<AlgoTransaction[]>;
//# sourceMappingURL=indexer.d.ts.map

@@ -10,3 +10,2 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

};
import network from "@ledgerhq/live-network";
import { getEnv } from "@ledgerhq/live-env";

@@ -18,3 +17,3 @@ import { BigNumber } from "bignumber.js";

const fullUrl = (route) => `${INDEXER_URL}${route}?limit=${LIMIT}`;
export const getAccountTransactions = (address, startAt) => __awaiter(void 0, void 0, void 0, function* () {
export const getAccountTransactions = (network) => (address, startAt) => __awaiter(void 0, void 0, void 0, function* () {
const url = fullUrl(`/accounts/${address}/transactions`);

@@ -33,2 +32,3 @@ let nextToken;

const { data } = yield network({
method: "GET",
url: nextUrl,

@@ -48,3 +48,2 @@ });

if (tx["tx-type"] === "pay") {
// If "tx-type" is "pay", we know we received a "payment-transaction"
const info = tx["payment-transaction"];

@@ -60,11 +59,10 @@ const paymentInfo = {

else if (tx["tx-type"] === "axfer") {
// If "tx-type" is "axfer", we know we received a "asset-transfer-transaction"
const info = tx["asset-transfer-transaction"];
const assetTransferInfo = {
assetAmount: new BigNumber(info.amount),
assetId: info["asset-id"].toString(),
assetId: info["asset-id"],
assetRecipientAddress: info.receiver,
assetSenderAddress: tx.sender,
assetSenderAddress: info.sender,
assetCloseAmount: info["close-amount"] === undefined ? undefined : new BigNumber(info["close-amount"]),
assetCloseToAddress: info["close-to"],
assetCloseToAddress: tx["close-to"],
};

@@ -75,3 +73,3 @@ details = assetTransferInfo;

id: tx.id,
timestamp: tx["round-time"].toString(),
timestamp: tx["round-time"],
round: tx["confirmed-round"],

@@ -78,0 +76,0 @@ senderAddress: tx.sender,

/// <reference types="node" />
import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
import { AlgoAccount, AlgoTransactionParams } from "./algodv2.types";
export declare const getAccount: (address: string) => Promise<AlgoAccount>;
export declare const getTransactionParams: () => Promise<AlgoTransactionParams>;
export declare const broadcastTransaction: (payload: Buffer) => Promise<string>;
export declare const getAccount: (network: NetworkRequestCall) => (address: string) => Promise<AlgoAccount>;
export declare const getTransactionParams: (network: NetworkRequestCall) => () => Promise<AlgoTransactionParams>;
export declare const broadcastTransaction: (network: NetworkRequestCall) => (payload: Buffer) => Promise<string>;
//# sourceMappingURL=algodv2.d.ts.map

@@ -11,8 +11,4 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.broadcastTransaction = exports.getTransactionParams = exports.getAccount = void 0;
const live_network_1 = __importDefault(require("@ledgerhq/live-network"));
const live_env_1 = require("@ledgerhq/live-env");

@@ -23,4 +19,5 @@ const bignumber_js_1 = require("bignumber.js");

const fullUrl = (route) => `${NODE_URL}${route}`;
const getAccount = (address) => __awaiter(void 0, void 0, void 0, function* () {
const { data } = yield (0, live_network_1.default)({
const getAccount = (network) => (address) => __awaiter(void 0, void 0, void 0, function* () {
const { data } = yield network({
method: "GET",
url: fullUrl(`/accounts/${address}`),

@@ -46,5 +43,6 @@ });

exports.getAccount = getAccount;
const getTransactionParams = () => __awaiter(void 0, void 0, void 0, function* () {
const getTransactionParams = (network) => () => __awaiter(void 0, void 0, void 0, function* () {
var _a;
const { data } = yield (0, live_network_1.default)({
const { data } = yield network({
method: "GET",
url: fullUrl(`/transactions/params`),

@@ -62,4 +60,4 @@ });

exports.getTransactionParams = getTransactionParams;
const broadcastTransaction = (payload) => __awaiter(void 0, void 0, void 0, function* () {
const { data } = yield (0, live_network_1.default)({
const broadcastTransaction = (network) => (payload) => __awaiter(void 0, void 0, void 0, function* () {
const { data } = yield network({
method: "POST",

@@ -66,0 +64,0 @@ url: fullUrl(`/transactions`),

@@ -25,3 +25,7 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const network_1 = __importDefault(require("@ledgerhq/live-network/network"));
const algodv2_1 = require("./algodv2");

@@ -32,7 +36,7 @@ const indexer_1 = require("./indexer");

exports.default = {
getAccount: (address) => __awaiter(void 0, void 0, void 0, function* () { return (0, algodv2_1.getAccount)(address); }),
getTransactionParams: () => __awaiter(void 0, void 0, void 0, function* () { return (0, algodv2_1.getTransactionParams)(); }),
broadcastTransaction: (payload) => __awaiter(void 0, void 0, void 0, function* () { return (0, algodv2_1.broadcastTransaction)(payload); }),
getAccountTransactions: (address, startAt) => __awaiter(void 0, void 0, void 0, function* () { return (0, indexer_1.getAccountTransactions)(address, startAt); }),
getAccount: (address) => __awaiter(void 0, void 0, void 0, function* () { return (0, algodv2_1.getAccount)(network_1.default)(address); }),
getTransactionParams: () => __awaiter(void 0, void 0, void 0, function* () { return (0, algodv2_1.getTransactionParams)(network_1.default)(); }),
broadcastTransaction: (payload) => __awaiter(void 0, void 0, void 0, function* () { return (0, algodv2_1.broadcastTransaction)(network_1.default)(payload); }),
getAccountTransactions: (address, startAt) => __awaiter(void 0, void 0, void 0, function* () { return (0, indexer_1.getAccountTransactions)(network_1.default)(address, startAt); }),
};
//# sourceMappingURL=index.js.map

@@ -0,3 +1,4 @@

import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
import { AlgoTransaction } from "./indexer.types";
export declare const getAccountTransactions: (address: string, startAt?: number) => Promise<AlgoTransaction[]>;
export declare const getAccountTransactions: (network: NetworkRequestCall) => (address: string, startAt?: number) => Promise<AlgoTransaction[]>;
//# sourceMappingURL=indexer.d.ts.map

@@ -11,8 +11,4 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAccountTransactions = void 0;
const live_network_1 = __importDefault(require("@ledgerhq/live-network"));
const live_env_1 = require("@ledgerhq/live-env");

@@ -24,3 +20,3 @@ const bignumber_js_1 = require("bignumber.js");

const fullUrl = (route) => `${INDEXER_URL}${route}?limit=${LIMIT}`;
const getAccountTransactions = (address, startAt) => __awaiter(void 0, void 0, void 0, function* () {
const getAccountTransactions = (network) => (address, startAt) => __awaiter(void 0, void 0, void 0, function* () {
const url = fullUrl(`/accounts/${address}/transactions`);

@@ -38,3 +34,4 @@ let nextToken;

}
const { data } = yield (0, live_network_1.default)({
const { data } = yield network({
method: "GET",
url: nextUrl,

@@ -55,3 +52,2 @@ });

if (tx["tx-type"] === "pay") {
// If "tx-type" is "pay", we know we received a "payment-transaction"
const info = tx["payment-transaction"];

@@ -67,11 +63,10 @@ const paymentInfo = {

else if (tx["tx-type"] === "axfer") {
// If "tx-type" is "axfer", we know we received a "asset-transfer-transaction"
const info = tx["asset-transfer-transaction"];
const assetTransferInfo = {
assetAmount: new bignumber_js_1.BigNumber(info.amount),
assetId: info["asset-id"].toString(),
assetId: info["asset-id"],
assetRecipientAddress: info.receiver,
assetSenderAddress: tx.sender,
assetSenderAddress: info.sender,
assetCloseAmount: info["close-amount"] === undefined ? undefined : new bignumber_js_1.BigNumber(info["close-amount"]),
assetCloseToAddress: info["close-to"],
assetCloseToAddress: tx["close-to"],
};

@@ -82,3 +77,3 @@ details = assetTransferInfo;

id: tx.id,
timestamp: tx["round-time"].toString(),
timestamp: tx["round-time"],
round: tx["confirmed-round"],

@@ -85,0 +80,0 @@ senderAddress: tx.sender,

{
"name": "@ledgerhq/coin-algorand",
"version": "0.5.7-nightly.2",
"version": "0.5.7",
"description": "Ledger Algorand Coin integration",

@@ -55,11 +55,11 @@ "keywords": [

"rxjs": "^7.8.1",
"@ledgerhq/coin-framework": "^0.18.2-nightly.2",
"@ledgerhq/cryptoassets": "^13.6.0-nightly.1",
"@ledgerhq/coin-framework": "^0.18.2",
"@ledgerhq/cryptoassets": "^13.6.0",
"@ledgerhq/devices": "^8.4.4",
"@ledgerhq/errors": "^6.19.1",
"@ledgerhq/live-env": "^2.4.0-nightly.0",
"@ledgerhq/live-network": "^2.0.2-nightly.0",
"@ledgerhq/live-env": "^2.3.0",
"@ledgerhq/live-network": "^2.0.1",
"@ledgerhq/live-promise": "^0.1.0",
"@ledgerhq/types-cryptoassets": "^7.16.0-nightly.0",
"@ledgerhq/types-live": "^6.52.0-nightly.2"
"@ledgerhq/types-cryptoassets": "^7.16.0",
"@ledgerhq/types-live": "^6.52.0"
},

@@ -66,0 +66,0 @@ "devDependencies": {

@@ -1,2 +0,2 @@

import network from "@ledgerhq/live-network";
import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
import { getEnv } from "@ledgerhq/live-env";

@@ -16,76 +16,57 @@ import { BigNumber } from "bignumber.js";

type ExplorerAccount = {
assets: {
"asset-id": number;
amount: number;
}[];
round: number;
address: string;
amount: number;
"pending-rewards": number;
};
export const getAccount =
(network: NetworkRequestCall) =>
async (address: string): Promise<AlgoAccount> => {
const { data } = await network({
method: "GET",
url: fullUrl(`/accounts/${address}`),
});
export const getAccount = async (address: string): Promise<AlgoAccount> => {
const { data } = await network<ExplorerAccount>({
url: fullUrl(`/accounts/${address}`),
});
const assets: AlgoAsset[] = data.assets
? // FIXME: what is the type of `a`?
data.assets.map((a: any): AlgoAsset => {
return {
assetId: a["asset-id"].toString(),
balance: new BigNumber(a.amount),
};
})
: [];
const assets: AlgoAsset[] = data.assets
? // FIXME: what is the type of `a`?
data.assets.map((a): AlgoAsset => {
return {
assetId: a["asset-id"].toString(),
balance: new BigNumber(a.amount),
};
})
: [];
return {
round: data.round,
address: data.address,
balance: new BigNumber(data.amount),
pendingRewards: new BigNumber(data["pending-rewards"]),
assets,
return {
round: data.round,
address: data.address,
balance: new BigNumber(data.amount),
pendingRewards: new BigNumber(data["pending-rewards"]),
assets,
};
};
};
type ExplorerTransactioParams = {
"consensus-version": string;
fee: number;
"genesis-hash": string;
"genesis-id": string;
"first-round"?: number;
"last-round": number;
"min-fee": number;
};
export const getTransactionParams =
(network: NetworkRequestCall) => async (): Promise<AlgoTransactionParams> => {
const { data } = await network({
method: "GET",
url: fullUrl(`/transactions/params`),
});
export const getTransactionParams = async (): Promise<AlgoTransactionParams> => {
const { data } = await network<ExplorerTransactioParams>({
url: fullUrl(`/transactions/params`),
});
return {
fee: data["fee"],
minFee: data["min-fee"],
firstRound: data["first-round"] ?? 0,
lastRound: data["last-round"],
genesisID: data["genesis-id"],
genesisHash: data["genesis-hash"],
return {
fee: data["fee"],
minFee: data["min-fee"],
firstRound: data["first-round"] ?? 0,
lastRound: data["last-round"],
genesisID: data["genesis-id"],
genesisHash: data["genesis-hash"],
};
};
};
type ExplorerBroadcastReturn = { txId: string };
export const broadcastTransaction =
(network: NetworkRequestCall) =>
async (payload: Buffer): Promise<string> => {
const { data }: { data: AlgoTransactionBroadcastResponse } = await network({
method: "POST",
url: fullUrl(`/transactions`),
data: payload,
headers: { "Content-Type": "application/x-binary" },
});
export const broadcastTransaction = async (payload: Buffer): Promise<string> => {
const { data }: { data: AlgoTransactionBroadcastResponse } = await network<
ExplorerBroadcastReturn,
Buffer
>({
method: "POST",
url: fullUrl(`/transactions`),
data: payload,
headers: { "Content-Type": "application/x-binary" },
});
return data.txId;
};
return data.txId;
};

@@ -0,1 +1,2 @@

import network from "@ledgerhq/live-network/network";
import { AlgoAccount, AlgoTransactionParams } from "./algodv2.types";

@@ -12,10 +13,11 @@

export default {
getAccount: async (address: string): Promise<AlgoAccount> => getAccount(address),
getAccount: async (address: string): Promise<AlgoAccount> => getAccount(network)(address),
getTransactionParams: async (): Promise<AlgoTransactionParams> => getTransactionParams(),
getTransactionParams: async (): Promise<AlgoTransactionParams> => getTransactionParams(network)(),
broadcastTransaction: async (payload: Buffer): Promise<string> => broadcastTransaction(payload),
broadcastTransaction: async (payload: Buffer): Promise<string> =>
broadcastTransaction(network)(payload),
getAccountTransactions: async (address: string, startAt?: number): Promise<AlgoTransaction[]> =>
getAccountTransactions(address, startAt),
getAccountTransactions(network)(address, startAt),
};

@@ -1,2 +0,2 @@

import network from "@ledgerhq/live-network";
import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
import { getEnv } from "@ledgerhq/live-env";

@@ -18,114 +18,38 @@ import { BigNumber } from "bignumber.js";

type ExplorerTransactions = {
"current-round": number;
"next-token": string;
transactions: ExplorerTransaction[];
};
export const getAccountTransactions =
(network: NetworkRequestCall) =>
async (address: string, startAt?: number): Promise<AlgoTransaction[]> => {
const url = fullUrl(`/accounts/${address}/transactions`);
type ExplorerTransaction = {
"application-transaction"?: {
accounts: string[];
"application-args": string[];
"application-id": number;
"foreign-apps": unknown[];
"foreign-assets": number[];
"global-state-schema": {
"num-byte-slice": number;
"num-uint": number;
};
"local-state-schema": {
"num-byte-slice": number;
"num-uint": number;
};
"on-completion": string;
};
"asset-transfer-transaction"?: {
amount: number;
"asset-id": number;
"close-amount": number;
"close-to"?: string;
receiver: string;
};
"close-rewards": number;
"closing-amount": number;
"confirmed-round": number;
fee: number;
"first-valid": number;
"genesis-hash": string;
"genesis-id": string;
"global-state-delta": {
key: string;
value: {
action: number;
uint: number;
bytes?: string;
};
}[];
id: string;
"intra-round-offset": number;
"last-valid": number;
"local-state-delta": {
address: string;
delta: {
key: string;
value: {
action: number;
uint: number;
};
}[];
}[];
note: string;
"payment-transaction"?: {
amount: number;
"close-amount": number;
"close-remainder-to"?: string;
receiver: string;
};
"receiver-rewards": number;
"round-time": number;
sender: string;
"sender-rewards": number;
signature: {
sig: string;
};
"tx-type": string;
};
let nextToken: string | undefined;
let newRawTxs: any[] = [];
const mergedTxs: AlgoTransaction[] = [];
do {
let nextUrl: string = url;
if (startAt) {
nextUrl = nextUrl.concat(`&min-round=${startAt}`);
}
if (nextToken) {
nextUrl = nextUrl.concat(`&next=${nextToken}`);
}
const { data }: { data: { transactions: any[] } } = await network({
method: "GET",
url: nextUrl,
});
export const getAccountTransactions = async (
address: string,
startAt?: number,
): Promise<AlgoTransaction[]> => {
const url = fullUrl(`/accounts/${address}/transactions`);
// FIXME: what is the correct type? Properly type response from api above (data)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
nextToken = data["next-token"];
newRawTxs = data.transactions;
newRawTxs.map(parseRawTransaction).forEach(tx => mergedTxs.push(tx));
} while (newRawTxs.length >= LIMIT);
let nextToken: string | undefined;
let newRawTxs: any[] = [];
const mergedTxs: AlgoTransaction[] = [];
do {
let nextUrl: string = url;
if (startAt) {
nextUrl = nextUrl.concat(`&min-round=${startAt}`);
}
if (nextToken) {
nextUrl = nextUrl.concat(`&next=${nextToken}`);
}
const { data }: { data: { transactions: any[] } } = await network<ExplorerTransactions>({
url: nextUrl,
});
return mergedTxs;
};
// FIXME: what is the correct type? Properly type response from api above (data)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
nextToken = data["next-token"];
newRawTxs = data.transactions;
newRawTxs.map(parseRawTransaction).forEach(tx => mergedTxs.push(tx));
} while (newRawTxs.length >= LIMIT);
return mergedTxs;
};
const parseRawTransaction = (tx: ExplorerTransaction): AlgoTransaction => {
const parseRawTransaction = (tx: any): AlgoTransaction => {
let details: AlgoTransactionDetails | undefined = undefined;
if (tx["tx-type"] === "pay") {
// If "tx-type" is "pay", we know we received a "payment-transaction"
const info = tx["payment-transaction"]!;
const info = tx["payment-transaction"];
const paymentInfo: AlgoPaymentInfo = {

@@ -140,12 +64,11 @@ amount: new BigNumber(info.amount),

} else if (tx["tx-type"] === "axfer") {
// If "tx-type" is "axfer", we know we received a "asset-transfer-transaction"
const info = tx["asset-transfer-transaction"]!;
const info = tx["asset-transfer-transaction"];
const assetTransferInfo: AlgoAssetTransferInfo = {
assetAmount: new BigNumber(info.amount),
assetId: info["asset-id"].toString(),
assetId: info["asset-id"],
assetRecipientAddress: info.receiver,
assetSenderAddress: tx.sender,
assetSenderAddress: info.sender,
assetCloseAmount:
info["close-amount"] === undefined ? undefined : new BigNumber(info["close-amount"]),
assetCloseToAddress: info["close-to"],
assetCloseToAddress: tx["close-to"],
};

@@ -157,3 +80,3 @@ details = assetTransferInfo;

id: tx.id,
timestamp: tx["round-time"].toString(),
timestamp: tx["round-time"],
round: tx["confirmed-round"],

@@ -160,0 +83,0 @@ senderAddress: tx.sender,

Sorry, the diff of this file is not supported yet

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

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