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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@demox-labs/miden-sdk

v0.0.5

Published

Polygon Miden Wasm SDK

Downloads

80

Readme

@demox-labs/miden-sdk

The @demox-labs/miden-sdk is a toolkit designed for interacting with the Miden virtual machine. It offers essential tools and functionalities for developers aiming to integrate or utilize Miden VM capabilities in their applications.

Installation

To install the package via npm, run the following command:

npm i @demox-labs/miden-sdk

For yarn:

yarn add @demox-labs/miden-sdk

Usage

import { WebClient } from "@demox-labs/miden-sdk";

const webClient = new WebClient();
await webClient.create_client();

// Use WebClient to create accounts, notes, transactions, etc.
// This will create a mutable, off-chain account and store it in IndexedDB
const accountId = await webClient.new_wallet("OffChain", true);

Examples

The WebClient

The WebClient is your gateway to creating and interacting with anything miden vm related. Example:

// Creates a new WebClient instance which can then be configured after
const webClient = new WebClient();

// Creates the internal client of a previously instantiated WebClient.
// Can provide `node_url` as an optional parameter. Defaults to "http://18.203.155.106:57291" which is the URL
// of the remote miden node.
await webClient.create_client();

Example specifying a specific node URL:

const webClient = new WebClient();

let remote_node_url = "http://18.203.155.106:57291"
await webClient.create_client(remote_node_url);

Accounts

You can use the WebClient to create and retrieve account information.

const webClient = new WebClient();
await webClient.create_client();

/**
 * Creates a new wallet account.
 * 
 * @param storage_mode String. Either "OffChain" or "OnChain".
 * @param mutable Boolean. Whether the wallet code is mutable or not
 * 
 * Returns: Wallet Id
 */
const walletId = await webClient.new_wallet("OffChain", true);

/**
 * Creates a new faucet account.
 * 
 * @param storage_mode String. Either "OffChain" or "OnChain".
 * @param non_fungible Boolean. Whether the faucet is non_fungible or not. NOTE: Non-fungible faucets are not supported yet
 * @param token_symbol String. Token symbol of the token the faucet creates
 * @param decimals String. Decimal precision of token.
 * @param max_supply String. Maximum token supply
 */ 
const faucetId = await webClient.new_faucet("OffChain", true, "TOK", 6, 1_000_000)

/**
 * Returns all accounts. Both wallets and faucets. Returns the following object per account
 * {
 *   id: string
 *   nonce: string
 *   vault_root: string
 *   storage_root: string
 *   code_root: string
 * }/
const accounts = await webClient.get_accounts()
console.log(accounts[0].id) // Prints account id of first account retrieved as hex value

// Gets a single account by id
const account = await webClient.get_account("0x9258fec00ad6d9bc");

// Imports an account. This example adds a simple button to an HTML page, creates a listener for an account file selection, serializes that file into bytes, then calls the client to import it. 
<label for="accountFileInput" class="custom-file-upload">
    Choose Account File
</label>
<input type="file" id="accountFileInput" style="display: none;">
document.getElementById('accountFileInput').addEventListener('change', function(event) {
    const file = event.target.files[0];
    if (file) {
        const reader = new FileReader();

        reader.onload = async function(e) {
            let webClient = await createMidenWebClient();
            const arrayBuffer = e.target.result;
            const byteArray = new Uint8Array(arrayBuffer);

            await webClient.importAccount(accountAsBytes);
        };

        reader.readAsArrayBuffer(file);
    }
});

Transactions

You can use the WebClient to facilitate transactions between accounts.

Let's mint some tokens for our wallet from our faucet:

const webClient = new WebClient();
await webClient.create_client();
const walletId = await webClient.new_wallet("OffChain", true);
const faucetId = await webClient.new_faucet("OffChain", true, "TOK", 6, 1_000_000);

// Syncs web client with node state.
await webClient.sync_state();
// Caches faucet account auth. A workaround to allow for synchronicity in the transaction flow.
await webClient.fetch_and_cache_account_auth_by_pub_key(faucetId);

/**
 * Mints 10_000 tokens for the previously created wallet via a Private Note and returns a transaction the following result object:
 * {
 *   transaction_id: string
 *   created_note_ids: string[]
 * }
 */
const newTxnResult = await webClient.new_mint_transaction(walletId, faucetId, "Private", 10_000);
console.log(newTxnResult.created_note_ids); // Prints the list of note ids created from this transaction

// Sync state again
await webClient.sync_state();

/**
 * Gets all of your existing transactions
 * Returns string[] of transaction ids
 */
const transactions = await webClient.get_transactions()

Notes

You can use the WebClient to query for existing notes, export notes, and import notes

Here is an example of how to import a note from a file (generated, say, from the faucet at https://testnet.miden.io/ for a given account). This code exposes a simple button on an HTML page for a user to select a file. A listener is setup to capture this event, serialize the note file, and import it.

let webClient = await createMidenWebClient();
let walletAccount = await webClient.new_wallet("OffChain", true);
console.log(walletAccount); // Prints the id that can be used to plug in to the deployed Miden faucet

<label for="noteFileInput" class="custom-file-upload">
    Choose Note File
</label>
<input type="file" id="noteFileInput" style="display: none;">
document.getElementById('noteFileInput').addEventListener('change', async function(event) {
    const file = event.target.files[0];
    if (file) {
        const reader = new FileReader();

        reader.onload = async function(e) {
            let webClient = await createMidenWebClient();

            const arrayBuffer = e.target.result;
            const byteArray = new Uint8Array(arrayBuffer);

            await webClient.import_note(byteArray, true); // imports the file generated from the faucet previously
        };

        reader.readAsArrayBuffer(file);
    }
});

Example of exporting a note:

console.log("testExportNote started");

let webClient = await createMidenWebClient();

// Create a faucet and mint a mint transaction
let faucetId = await createNewFaucet(webClient, "OffChain", false, "DEN", "10", "1000000");
await syncState(webClient);
await new Promise(r => setTimeout(r, 20000)); // Artificial delays to ensure sync is processed on remote node before continuing 

await webClient.fetch_and_cache_account_auth_by_pub_key(faucetId);

let mintTransactionResult = await createNewMintTransaction(
    webClient,
    "0x9186b96f559e852f", // Insert target account id here
    faucetId,
    "Private",
    "1000"
);
await new Promise(r => setTimeout(r, 20000));
await syncState(webClient);

// Take the note created from the mint transaction, serialize it, and download it via the browser immediately
let result = await exportNote(webClient, mintTransactionResult.created_note_ids[0]);

const blob = new Blob([result], {type: 'application/octet-stream'});

// Create a URL for the Blob
const url = URL.createObjectURL(blob);

// Create a temporary anchor element
const a = document.createElement('a');
a.href = url;
a.download = 'exportNoteTest.mno'; // Specify the file name

// Append the anchor to the document
document.body.appendChild(a);

// Programmatically click the anchor to trigger the download
a.click();

// Remove the anchor from the document
document.body.removeChild(a);

// Revoke the object URL to free up resources
URL.revokeObjectURL(url);

Get All Input Notes Example:

let webClient = await createMidenWebClient();

/**
 * get_input_notes takes a filter to retrieve notes based on a specific status. The options are the following:
 * "All"
 * "Consumed"
 * "Committed"
 * "Expected"
 * "Processing"
 */
const notes = await webClient.get_input_notes("All")

API Reference

/**
 * @returns {Promise<SerializedAccountStub>}
 * 
 * Example of returned object:
 * {
 *   id: string,
 *   nonce: string,
 *   vault_root: string,
 *   storage_root: string,
 *   code_root: string
 * }
 */
get_accounts(): Promise<SerializedAccountStub>;

/**
 * @param {string} account_id
 * @returns {Promise<any>}
 */
get_account(account_id: string): Promise<any>;

/**
 * @param {any} pub_key_bytes
 * @returns {any}
 */
get_account_auth_by_pub_key(pub_key_bytes: any): any;

/**
 * @param {string} account_id
 * @returns {Promise<any>}
 */
fetch_and_cache_account_auth_by_pub_key(account_id: string): Promise<any>;

/**
 * @param {string} note_id
 * @param {string} export_type
 * @returns {Promise<any>}
 * 
 * export_type can be any of the following:
 * 
 * "Full"
 * "Partial"
 * "Id"
 */
export_note(note_id: string, export_type: string): Promise<any>;

/**
 * @param {any} account_bytes
 * @returns created account id as {Promise<string>}
 * 
 */
import_account(account_bytes: any): Promise<string>;

/**
 * @param {string} note_bytes
 * @param {boolean} verify
 * @returns {Promise<any>}
 */
import_note(note_bytes: string, verify: boolean): Promise<any>;

/**
 * @param {string} storage_type
 * @param {boolean} mutable
 * @returns {Promise<any>}
 */
new_wallet(storage_type: string, mutable: boolean): Promise<any>;

/**
 * @param {string} storage_type
 * @param {boolean} non_fungible
 * @param {string} token_symbol
 * @param {string} decimals
 * @param {string} max_supply
 * @returns {Promise<any>}
 */
new_faucet(storage_type: string, non_fungible: boolean, token_symbol: string, decimals: string, max_supply: string): Promise<any>;

/**
 * @param {string} target_account_id
 * @param {string} faucet_id
 * @param {string} note_type
 * @param {string} amount
 * @returns {Promise<NewTransactionResult>}
 * 
 * Example of a NewTransactionResult object:
 * {
 *   transaction_id: string,
 *   created_note_ids: string[]
 * }
 */
new_mint_transaction(target_account_id: string, faucet_id: string, note_type: string, amount: string): Promise<NewTransactionResult>;

/**
 * @param {string} sender_account_id
 * @param {string} target_account_id
 * @param {string} faucet_id
 * @param {string} note_type
 * @param {string} amount
 * @param {string | undefined} [recall_height]
 * @returns {Promise<NewTransactionResult>}
 * 
 * Example of a NewTransactionResult object:
 * {
 *   transaction_id: string,
 *   created_note_ids: string[]
 * }
 */
new_send_transaction(sender_account_id: string, target_account_id: string, faucet_id: string, note_type: string, amount: string, recall_height?: string): Promise<NewTransactionResult>;

/**
 * @param {string} account_id
 * @param {(string)[]} list_of_notes
 * @returns {Promise<NewTransactionResult>}
 * 
 * Example of a NewTransactionResult object:
 * {
 *   transaction_id: string,
 *   created_note_ids: string[]
 * }
 */
new_consume_transaction(account_id: string, list_of_notes: (string)[]): Promise<NewTransactionResult>;

/**
 * @param {string} sender_account_id
 * @param {string} offered_asset_faucet_id
 * @param {string} offered_asset_amount
 * @param {string} requested_asset_faucet_id
 * @param {string} requested_asset_amount
 * @param {string} note_type
 * @returns {Promise<NewSwapTransactionResult>}
 * 
 * Example of a NewSwapTransactionResult object:
 * {
 *   transaction_id: string,
 *   expected_output_note_ids: string[],
 *.  expected_partial_note_ids: string[],
 *   payback_note_tag: string,
 * }
 */
new_swap_transaction(sender_account_id: string, offered_asset_faucet_id: string, offered_asset_amount: string, requested_asset_faucet_id: string, requested_asset_amount: string, note_type: string): Promise<NewSwapTransactionResult>;

/**
 * @param {any} filter
 * @returns {Promise<any>}
 * 
 * Examples of valid filters:
 * "All"
 * "Consumed"
 * "Committed"
 * "Expected"
 * "Processing"
 */
get_input_notes(filter: any): Promise<any>;

/**
 * @param {string} note_id
 * @returns note id as {Promise<any>}
 */
get_input_note(note_id: string): Promise<any>;

/**
 * @param {any} filter
 * @returns {Promise<any>}
 */
get_output_notes(filter: any): Promise<any>;

/**
 * @param {string} note_id
 * @returns {Promise<any>}
 * 
 * Examples of valid filters:
 * "All"
 * "Consumed"
 * "Committed"
 * "Expected"
 * "Processing"
 */
get_output_note(note_id: string): Promise<any>;

/**
 * @returns block number of latest block you synced to {Promise<any>}
 */
sync_state(): Promise<any>;

/**
 * @returns list of existing transaction ids {Promise<string[]>}
 */
get_transactions(): Promise<string[]>;

/**
 * @param {string} tag
 * @returns {Promise<any>}
 */
add_tag(tag: string): Promise<any>;

/**
 */
constructor();

/**
 * @param {string | undefined} [node_url]
 * @returns {Promise<any>}
 */
create_client(node_url?: string): Promise<any>;

License

This project is licensed under the MIT License - see the LICENSE file for details.