npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

layer4

v1.0.0

Published

Simple blockchain solutions for everyone.

Readme

Layer4 SDK

TypeScript SDK for the Layer4 blockchain API. Mint tokens, store records on-chain, and manage wallets — with full type safety and a single dependency.

Installation

npm install layer4
# or
yarn add layer4
# or
pnpm add layer4

Quick start

import { Layer4Client } from "layer4";

const client = new Layer4Client("your-api-key");

// Mint a fungible token
const { data: token } = await client.createNewToken({
    bucketId: "your-bucket-id",
    supply: 1000,
});

// Mint an NFT
const { data: nft } = await client.createNewToken({
    bucketId: "your-bucket-id",
    supply: 1,
    metadata: {
        name: "My NFT",
        description: "A unique digital collectible",
        image: "https://example.com/image.png",
    },
});

Response structure

Every method returns Promise<BaseResponse<T>>:

type BaseResponse<T> = {
    data: T;
    statusCode: number;
    success: boolean;
};

Destructure data to get the result:

const { data: token, statusCode, success } = await client.getToken({
    bucketId: "...",
    tokenId: "...",
});

Error handling

All API errors are thrown as Layer4Error:

import { Layer4Client } from "layer4";
import type { Layer4Error } from "layer4";

try {
    const { data } = await client.getToken({ bucketId: "...", tokenId: "..." });
} catch (err) {
    const error = err as Layer4Error;
    console.error(error.message);    // human-readable message
    console.error(error.statusCode); // HTTP status code (e.g. 404)
    console.error(error.error);      // error code string (e.g. "NOT_FOUND")
}

API reference

Tokens

createNewToken(params)

Mint new tokens synchronously. Waits for the transaction to settle on-chain before returning.

const { data: token } = await client.createNewToken({
    bucketId: string;          // required
    supply: string | number;   // required — use string for amounts > Number.MAX_SAFE_INTEGER
    metadata?: {               // provide metadata to create an NFT
        name: string;
        description: string;
        [key: string]: any;
    };
    image?: File;              // uploaded and referenced in metadata.image
    files?: File[];            // additional files; reference via {{fileHash:0}} in metadata
    segmentId?: string;        // defaults to the bucket's first segment
    toAddress?: string;        // recipient wallet address or user email
});

Returns BaseResponse<Token>.

createNewTokenAsync(params)

Same as createNewToken but returns immediately with a TokenRequestEntity instead of waiting for the transaction. Poll with getTokenRequest to check status.

getTokens(params)

const { data } = await client.getTokens({
    bucketId: string;
    limit?: number;
    page?: number;
    segmentId?: string;
});
// data: { tokens: Token[]; meta: Meta }

getToken(params)

const { data: token } = await client.getToken({
    bucketId: string;
    tokenId: string;
});

updateToken(params)

Update metadata or segmentId of an existing token. Does not affect supply.

await client.updateToken({
    bucketId: string;
    tokenId: string;
    metadata?: { name: string; description: string; [key: string]: any };
    segmentId?: string;
    image?: File;
    files?: File[];
    toAddress?: string;
});

updateTokenAsync(params)

Async variant of updateToken. Returns BaseResponse<TokenRequestEntity>.

burnToken(params)

Burn the entire supply of a token. The token owner must approve the burn first.

await client.burnToken({
    bucketId: string;
    tokenId: string;
    ownerAddress: string; // on-chain address of the token owner
});

burnTokenAsync(params)

Async variant of burnToken. Returns BaseResponse<TokenRequestEntity>.

getTokenMetadata(params)

const { data } = await client.getTokenMetadata({
    bucketId: string;
    tokenId: string;
});
// data: { metadata: Record<string, any> }

getTokenBalance(params)

Returns the on-chain balance of a specific token for a given wallet address.

const { data } = await client.getTokenBalance({
    bucketId: string;
    tokenId: string;
    address: string; // on-chain wallet address
});
// data: { address: string; balance: string; bucketId: string; tokenId: string }

Token supply

getSupply(params)

const { data } = await client.getSupply({ bucketId: string; tokenId: string });
// data: { supply: string }

increaseSupply(params)

Mint additional tokens and optionally send them to an address.

await client.increaseSupply({
    bucketId: string;
    tokenId: string;
    amount: string | number;
    toAddress?: string;
});

increaseSupplyAsync(params)

Async variant. Returns BaseResponse<TokenRequestEntity>.

decreaseSupply(params)

Burn a portion of the token supply. The owner must approve.

await client.decreaseSupply({
    bucketId: string;
    tokenId: string;
    amount: string | number;
    ownerAddress: string;
});

decreaseSupplyAsync(params)

Async variant. Returns BaseResponse<TokenRequestEntity>.


Token requests

Used to track the status of async token operations.

getTokenRequests(params)

const { data } = await client.getTokenRequests({
    bucketId: string;
    limit?: number;
    page?: number;
});
// data: { tokenRequests: TokenRequestEntity[]; meta: Meta }

getTokenRequest(params)

const { data: request } = await client.getTokenRequest({
    bucketId: string;
    tokenRequestId: string;
});
// request.status: "PENDING" | "CONFIRMED" | "FAILED" | ...

Records

Store arbitrary data on-chain inside a bucket.

createRecord(params)

Create a record synchronously. Waits for on-chain confirmation.

const { data: record } = await client.createRecord({
    bucketId: string;
    data: string | Record<string, any>; // payload to store
    contentType?: string;  // e.g. "application/json", "text/plain"
    segmentId?: string;
    encrypt?: boolean;     // encrypt before storing
    files?: File[];
});

createRecordAsync(params)

Async variant. Returns BaseResponse<RecordRequestEntity>.

getRecords(params)

const { data } = await client.getRecords({
    bucketId: string;
    limit?: number;
    page?: number;
    segmentId?: string;
    decrypt?: boolean;
});
// data: { records: RecordEntity[]; meta: Meta }

getRecord(params)

const { data: record } = await client.getRecord({
    bucketId: string;
    recordId: string;
    decrypt?: boolean;
});

Record requests

Used to track the status of async record operations.

getRecordRequests(params)

const { data } = await client.getRecordRequests({
    bucketId: string;
    limit?: number;
    page?: number;
});
// data: { recordRequests: RecordRequestEntity[]; meta: Meta }

getRecordRequest(params)

const { data: request } = await client.getRecordRequest({
    bucketId: string;
    recordRequestId: string;
    decrypt?: boolean;
});

Wallets

createWallets(data)

Create one or more wallets for workspace users.

const { data } = await client.createWallets({
    users: string[]; // list of user identifiers (e.g. email addresses), max 100
});
// data: { wallets: WalletEntity[] }

getWallets(params?)

const { data } = await client.getWallets({
    limit?: number;
    page?: number;
    status?: WalletStatus[];
});
// data: { wallets: WalletEntity[]; meta: Meta }

getWallet(params)

const { data: wallet } = await client.getWallet({
    walletId: string;
    status?: WalletStatus[];
});

updateWallet(params)

await client.updateWallet({
    walletId: string;
    status: WalletStatus;  // "ACTIVE" | "INACTIVE" | "PENDING" | "DECLINED"
    name?: string;
});

removeWallet(params)

await client.removeWallet({ walletId: string });

Async operations

Several write operations (token minting, burning, supply changes, record creation) have both synchronous and async variants:

| Sync | Async | |---|---| | createNewToken | createNewTokenAsync | | updateToken | updateTokenAsync | | burnToken | burnTokenAsync | | increaseSupply | increaseSupplyAsync | | decreaseSupply | decreaseSupplyAsync | | createRecord | createRecordAsync |

Sync variants block until the transaction settles on-chain and return the final entity.

Async variants return immediately with a TokenRequestEntity or RecordRequestEntity. Use the corresponding get*Request method to poll for the result:

// Start async mint
const { data: request } = await client.createNewTokenAsync({
    bucketId: "...",
    supply: 500,
});

// Poll until confirmed
let status = request.status;
while (status === "PENDING") {
    await new Promise((r) => setTimeout(r, 2000));
    const { data } = await client.getTokenRequest({
        bucketId: "...",
        tokenRequestId: request.id,
    });
    status = data.status;
}

Supported chains

import { Chain } from "layer4";

Chain.POLYGON
Chain.ARBITRUM_ONE
Chain.ARBITRUM_NOVA
Chain.BINANCE_SMART_CHAIN
Chain.FANTOM

// Testnets
Chain.POLYGON_AMOY
Chain.ARBITRUM_SEPOLIA
Chain.BINANCE_SMART_CHAIN_TESTNET
Chain.FANTOM_TESTNET
Chain.SONIC_TESTNET

TypeScript

All types are exported from the package root:

import type {
    // Core
    BaseResponse,
    Layer4Client,

    // Tokens
    Token,
    TokenMetadata,
    TokenSupply,
    TokenBalanceResponse,
    TokenMetadataResponse,
    TokenRequestEntity,
    TokenRequestStatus,
    TokenRequestType,

    // Records
    RecordEntity,
    RecordRequestEntity,
    RecordRequestStatus,
    RecordRequestType,

    // Wallets
    WalletEntity,
    WalletStatus,

    // Pagination
    Meta,

    // Enums
    Chain,
} from "layer4";

License

MIT