/cashu-ts

A TypeScript library for building Cashu wallets

Primary LanguageTypeScriptMIT LicenseMIT

Cashu TS

GitHub Workflow Status GitHub issues GitHub package.json version npm npm type definitions npm bundle size code coverage

⚠️ Don't be reckless: This project is in early development, it does however work with real sats! Always use amounts you don't mind losing.

Cashu TS is a JavaScript library for Cashu wallets written in Typescript.

Wallet Features:

  • connect to mint (load keys)
  • request minting tokens
  • minting tokens
  • sending tokens (get encoded token for chosen value)
  • receiving tokens
  • melting tokens
  • check if tokens are spent
  • ...

Implemented NUTs:

Supported token formats:

  • v1 read
  • v2 read (deprecated)
  • v3 read/write
  • v4 read/write

Usage

Go to the docs for detailed usage, or have a look at the integration tests for examples on how to implement a wallet.

Install

npm i @cashu/cashu-ts

Examples

Mint tokens

import { CashuMint, CashuWallet, MintQuoteState } from '@cashu/cashu-ts';
const mintUrl = 'http://localhost:3338'; // the mint URL
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint);
await wallet.loadMint(); // persist wallet.keys and wallet.keysets to avoid calling loadMint() in the future
const mintQuote = await wallet.createMintQuote(64);
// pay the invoice here before you continue...
const mintQuoteChecked = await wallet.checkMintQuote(mintQuote.quote);
if (mintQuoteChecked.state == MintQuoteState.PAID) {
	const { proofs } = await wallet.mintProofs(64, mintQuote.quote);
}

Melt tokens

import { CashuMint, CashuWallet } from '@cashu/cashu-ts';
const mintUrl = 'http://localhost:3338'; // the mint URL
const mint = new CashuMint(mintUrl);
const wallet = new CashuWallet(mint); // load the keysets of the mint

const invoice = 'lnbc......'; // Lightning invoice to pay
const meltQuote = await wallet.createMeltQuote(invoice);
const amountToSend = meltQuote.amount + meltQuote.fee_reserve;

// CashuWallet.send performs coin selection and swaps the proofs with the mint
// if no appropriate amount can be selected offline. We must include potential
// ecash fees that the mint might require to melt the resulting proofsToSend later.
const { keep: proofsToKeep, send: proofsToSend } = await wallet.send(amountToSend, proofs, {
	includeFees: true
});
// store proofsToKeep in wallet ..

const meltResponse = await wallet.meltProofs(meltQuote, proofsToSend);
// store meltResponse.change in wallet ..

Create a token and receive it

// we assume that `wallet` already minted `proofs`, as above
const { keep, send } = await wallet.send(32, proofs);
const token = getEncodedTokenV4({ token: [{ mint: mintUrl, proofs: send }] });
console.log(token);

const wallet2 = new CashuWallet(mint); // receiving wallet
const receiveProofs = await wallet2.receive(token);

Contribute

Contributions are very welcome.

If you want to contribute, please open an Issue or a PR. If you open a PR, please do so from the development branch as the base branch.