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

@haneullabs/haneul

v2.4.0

Published

Haneul TypeScript API

Readme

Docs site

For more complete docs, visit the Haneul TypeScript SDK docs

Haneul TypeScript SDK

This is the Haneul TypeScript SDK providing utility classes and functions for applications to sign transactions and interact with the Haneul network. It supports multiple communication protocols including gRPC (recommended), GraphQL, and JSON RPC (deprecated).

Building Locally

To get started you need to install pnpm, then run the following command:

# Install all dependencies
$ pnpm install

# Run `build` for the TypeScript SDK if you're in the `sdk/haneul` project
$ pnpm run build

# Run `sdk build` for the TypeScript SDK if you're in the root of `haneul` repo
$ pnpm sdk build

All pnpm commands below are intended to be run in the root of the Haneul repo.

Type Doc

You can view the generated Type Doc for the current release of the SDK at https://sdk.haneul-labs.com/typedoc/index.html.

For the latest docs for the main branch, run pnpm doc and open the doc/index.html in your browser.

Testing

To run unit tests

pnpm --filter @haneullabs/haneul test:unit

To run E2E tests against local network

pnpm --filter @haneullabs/haneul prepare:e2e

// This will run all e2e tests
pnpm --filter @haneullabs/haneul test:e2e

// Alternatively you can choose to run only one test file
npx vitest txn-builder.test.ts

Troubleshooting:

If you see errors like ECONNRESET or "socket hang up", run node -v to make sure your node version is v18.x.x. Refer to this guide to switch node version.

Some more follow up here is if you used homebrew to install node, there could be multiple paths to node on your machine. https://stackoverflow.com/questions/52676244/node-version-not-updating-after-nvm-use-on-mac

To run E2E tests against Devnet

VITE_FAUCET_URL='https://faucet.devnet.haneul.io:443/v2/gas' VITE_FULLNODE_URL='https://fullnode.devnet.haneul.io' pnpm --filter @haneullabs/haneul exec vitest e2e

Connecting to Haneul Network

The SuiGrpcClient class provides a connection to the Haneul network via gRPC and is the recommended client for all operations. The default URLs to connect with the gRPC server are:

  • local: http://127.0.0.1:9000
  • Devnet: https://fullnode.devnet.haneul.io:443
  • Testnet: https://fullnode.testnet.haneul.io:443
  • Mainnet: https://fullnode.mainnet.haneul.io:443
import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

// create a client connected to devnet
const client = new SuiGrpcClient({
	network: 'devnet',
	baseUrl: 'https://fullnode.devnet.haneul.io:443',
});

// get coins owned by an address using the Core API
await client.getCoins({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
});

For local development, you can run cargo run --bin --with-faucet --force-regenesis to spin up a local network with a local validator, a fullnode, and a faucet server. Refer to this guide for more information.

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

// create a client connected to localnet
const client = new SuiGrpcClient({
	network: 'localnet',
	baseUrl: 'http://127.0.0.1:9000',
});

// get coins owned by an address using the Core API
await client.getCoins({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
});

You can also construct your own SuiGrpcClient connections with the URL for your own fullnode:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

// create a client connected to your own fullnode
const client = new SuiGrpcClient({
	network: 'devnet',
	baseUrl: 'https://your-fullnode.example.com:443',
});

// get coins owned by an address using the Core API
await client.getCoins({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
});

Getting coins from the faucet

You can request haneul from the faucet when running against devnet or localnet. For testnet, visit faucet.haneul.io.

import { getFaucetHost, requestSuiFromFaucetV2 } from '@haneullabs/haneul/faucet';

await requestSuiFromFaucetV2({
	host: getFaucetHost('devnet'),
	recipient: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
});

Writing APIs

For a primer for building transactions, refer to this guide.

Transfer Object

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';
import { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';
import { Transaction } from '@haneullabs/haneul/transactions';

// Generate a new Ed25519 Keypair
const keypair = new Ed25519Keypair();
const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const tx = new Transaction();
tx.transferObjects(
	['0xe19739da1a701eadc21683c5b127e62b553e833e8a15a4f292f4f48b4afea3f2'],
	'0x1d20dcdb2bca4f508ea9613994683eb4e76e9c4ed371169677c1be02aaf0b12a',
);
const result = await client.signAndExecuteTransaction({
	signer: keypair,
	transaction: tx,
});
console.log({ result });

Transfer Haneul

To transfer 1000 GEUNHWA to another address:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';
import { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';
import { Transaction } from '@haneullabs/haneul/transactions';

// Generate a new Ed25519 Keypair
const keypair = new Ed25519Keypair();
const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const tx = new Transaction();
const [coin] = tx.splitCoins(tx.gas, [1000]);
tx.transferObjects([coin], keypair.getPublicKey().toSuiAddress());
const result = await client.signAndExecuteTransaction({
	signer: keypair,
	transaction: tx,
});
console.log({ result });

Merge coins

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';
import { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';
import { Transaction } from '@haneullabs/haneul/transactions';

// Generate a new Ed25519 Keypair
const keypair = new Ed25519Keypair();
const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const tx = new Transaction();
tx.mergeCoins('0xe19739da1a701eadc21683c5b127e62b553e833e8a15a4f292f4f48b4afea3f2', [
	'0x127a8975134a4824d9288722c4ee4fc824cd22502ab4ad9f6617f3ba19229c1b',
]);
const result = await client.signAndExecuteTransaction({
	signer: keypair,
	transaction: tx,
});
console.log({ result });

Move Call

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';
import { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';
import { Transaction } from '@haneullabs/haneul/transactions';

// Generate a new Ed25519 Keypair
const keypair = new Ed25519Keypair();
const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const packageObjectId = '0x...';
const tx = new Transaction();
tx.moveCall({
	target: `${packageObjectId}::nft::mint`,
	arguments: [tx.pure.string('Example NFT')],
});
const result = await client.signAndExecuteTransaction({
	signer: keypair,
	transaction: tx,
});
console.log({ result });

Publish Modules

To publish a package:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';
import { Ed25519Keypair } from '@haneullabs/haneul/keypairs/ed25519';
import { Transaction } from '@haneullabs/haneul/transactions';
import { execSync } from 'child_process';

// Generate a new Ed25519 Keypair
const keypair = new Ed25519Keypair();
const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const { modules, dependencies } = JSON.parse(
	execSync(`${cliPath} move build --dump-bytecode-as-base64 --path ${packagePath}`, {
		encoding: 'utf-8',
	}),
);
const tx = new Transaction();
const [upgradeCap] = tx.publish({
	modules,
	dependencies,
});
tx.transferObjects([upgradeCap], keypair.toSuiAddress());
const result = await client.signAndExecuteTransaction({
	signer: keypair,
	transaction: tx,
});
console.log({ result });

Reading APIs

Get Owned Objects

Fetch objects owned by the address 0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const objects = await client.getOwnedObjects({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
});

Get Object

Fetch object details for the object with id 0xe19739da1a701eadc21683c5b127e62b553e833e8a15a4f292f4f48b4afea3f2

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const object = await client.getObject({
	id: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
	// fetch the object content field
	options: { showContent: true },
});

// You can also fetch multiple objects in one batch request
const objects = await client.multiGetObjects({
	ids: [
		'0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
		'0x9ad3de788483877fe348aef7f6ba3e52b9cfee5f52de0694d36b16a6b50c1429',
	],
	// only fetch the object type
	options: { showType: true },
});

Get Transaction

Fetch transaction details from transaction digests:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const txn = await client.getTransactionBlock({
	digest: '9XFneskU8tW7UxQf7tE5qFRfcN4FadtC2Z3HAZkgeETd=',
	// only fetch the effects field
	options: {
		showEffects: true,
		showInput: false,
		showEvents: false,
		showObjectChanges: false,
		showBalanceChanges: false,
	},
});

// You can also fetch multiple transactions in one batch request
const txns = await client.multiGetTransactionBlocks({
	digests: [
		'9XFneskU8tW7UxQf7tE5qFRfcN4FadtC2Z3HAZkgeETd=',
		'17mn5W1CczLwitHCO9OIUbqirNrQ0cuKdyxaNe16SAME=',
	],
	// fetch both the input transaction data as well as effects
	options: { showInput: true, showEffects: true },
});

Get Checkpoints

Get latest 100 Checkpoints in descending order and print Transaction Digests for each one of them.

client.getCheckpoints({ descendingOrder: true }).then(function (checkpointPage: CheckpointPage) {
	console.log(checkpointPage);

	checkpointPage.data.forEach((checkpoint) => {
		console.log('---------------------------------------------------------------');
		console.log(
			' -----------   Transactions for Checkpoint:  ',
			checkpoint.sequenceNumber,
			' -------- ',
		);
		console.log('---------------------------------------------------------------');
		checkpoint.transactions.forEach((tx) => {
			console.log(tx);
		});
		console.log('***************************************************************');
	});
});

Get Checkpoint 1994010 and print details.

client.getCheckpoint({ id: '1994010' }).then(function (checkpoint: Checkpoint) {
	console.log('Checkpoint Sequence Num ', checkpoint.sequenceNumber);
	console.log('Checkpoint timestampMs ', checkpoint.timestampMs);
	console.log('Checkpoint # of Transactions ', checkpoint.transactions.length);
});

Get Coins

Fetch coins of type 0x65b0553a591d7b13376e03a408e112c706dc0909a79080c810b93b06f922c458::usdc::USDC owned by an address:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const coins = await client.getCoins({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
	coinType: '0x65b0553a591d7b13376e03a408e112c706dc0909a79080c810b93b06f922c458::usdc::USDC',
});

Fetch all coin objects owned by an address:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const allCoins = await client.getAllCoins({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
});

Fetch the total coin balance for a coin type, owned by an address:

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

// If coin type is not specified, it defaults to 0x2::haneul::HANEUL
const coinBalance = await client.getBalance({
	owner: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231',
	coinType: '0x65b0553a591d7b13376e03a408e112c706dc0909a79080c810b93b06f922c458::usdc::USDC',
});

Events API

Querying events created by transactions sent by account 0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231

import { SuiGrpcClient } from '@haneullabs/haneul/grpc';

const client = new SuiGrpcClient({
	network: 'testnet',
	baseUrl: 'https://fullnode.testnet.haneul.io:443',
});

const events = await client.queryEvents({
	query: { Sender: '0xcc2bd176a478baea9a0de7a24cd927661cc6e860d5bacecb9a138ef20dbab231' },
	limit: 2,
});