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

@tableland/sdk

v7.0.0

Published

A database client and helpers for the Tableland network

Downloads

3,040

Readme

@tableland/sdk

Review Test License: MIT AND Apache-2.0 Version standard-readme compliant

Tableland JavaScript SDK—the essential tool for building web3 apps with Tableland databases.

Table of Contents

Background

The @tableland/sdk library provides an easy-to-use interface for integrating Tableland databases into your web3 applications, unlocking decentralized data-driven development with SQL queries (creates, writes, reads) and access control.

Install

You can install via npm:

npm i @tableland/sdk

Or yarn:

yarn add @tableland/sdk

Usage

Full library documentation is available on our docs site.

Database

A Database is used to create, write, and read data. To connect to a Database, you first must import and instantiate it. There are two key considerations:

  • If you are only reading data, you do not need a signer, which is an abstraction of an EVM account and used for sending on-chain transactions—database reads are off-chain.
  • If you are creating or writing to tables, you do need a signer since database mutations require an EVM account to send transactions.

If you need to set up a signer, libraries like ethers help provide a way to create one by leveraging a connection with a provider. From there, all database creates, writes, and reads go through a single prepare method.

Connecting

As noted, creating a table instantiates a Database and must connect to it with a signer; this is also true for any table writes. The ethers library is used in the example below to create a signer, which comes as part of the @tableland/sdk but can also be installed separately.

import { Database } from "@tableland/sdk";
import { providers } from "ethers";

// Connect to a chain provider, such as a browser wallet
const provider = new providers.Web3Provider(window.ethereum);
// Request permission to connect to a users accounts
await provider.send("eth_requestAccounts", []);

// Create a signer from the connected browser wallet
const signer = provider.getSigner();
// Create a database connection; the signer passes the connected
// chain and is used for signing create table transactions
const db = new Database({ signer });

For certain applications, it's possible that developers will want to manage connections from a local wallet and not a browser wallet. You'll want to create a provider connection using a custom provider URL or the default ethers provider for the specified chain.

import { Database } from "@tableland/sdk";
import { Wallet, getDefaultProvider } from "ethers";

// Define your private key (but replace with your own)
const privateKey = PRIVATE_KEY; // It's recommended to use `dotenv` and a place this in a `.env` file
// Create the wallet (an extension of a signer)
const wallet = new Wallet(privateKey);
// Connect to a provider (e.g., Alchemy, etc.)—you should pass your own
// provider URL to `getDefaultProvider()` (avoid the throttled default)
// For example: `https://eth-mainnet.alchemyapi.io/v2/${YOUR_API_KEY}`
const provider = getDefaultProvider("homestead"); // Defaults to Ethereum mainnet
// Create a signer by attaching the wallet to the provider
const signer = wallet.connect(provider);
// Connect to the database
const db = new Database({ signer });

For read-only connections, a signer is not required. This Database connection can be used to make multichain queries across any of the chains in which Tableland is deployed to. Note that in the signer-connected Database above, read queries are still possible.

import { Database } from "@tableland/sdk";

// Create a database connection; since there is no signer,
// table reads are possible but creates/writes are not
const db = new Database();

If no signer is provided and you try to create or write to tables, the Database will default to prompting a browser wallet connection.

Create, write, & read

To create a table, you pass a CREATE TABLE statement to the prepare method and then execute it.

// This is the table's `prefix`--a custom table value prefixed as part of the table's name
const prefix = "my_sdk_table";

const { meta: create } = await db
  .prepare(`CREATE TABLE ${prefix} (id integer primary key, val text);`)
  .run();

// The table's `name` is in the format `{prefix}_{chainId}_{tableId}`
const { name } = create.txn; // e.g., my_sdk_table_80002_311

Once the table is created, you can then insert, update, and/or delete data with prepared statements. Parameter binding is a useful feature such that you can pass parameters in bind that replace the ? placeholders in this example.

// Insert a row into the table with an `INSERT INTO` statement
const { meta: insert } = await db
  .prepare(`INSERT INTO ${name} (id, val) VALUES (?, ?);`)
  .bind(0, "Bobby Tables")
  .run();

// Wait for transaction finality
await insert.txn.wait();

Notice the insert.txn.wait() usage above. Table creates and writes are on-chain actions, so a transaction must be "finalized" before the data is made available via a SELECT query. Once the data is settled, it can be read.

// Perform a read query, requesting `all` rows from the table
const { results } = await db.prepare(`SELECT * FROM ${name};`).all();

Validator

Aside from the core Database, developers can also choose to connect directly to a Tableland Validator node. Connecting to a validator is useful when you'd like to directly access other table or validator information as exposed by a Tableland Gateway API.

A validator is instantiated using a Database. The Database does not need a signer, but it does need a baseUrl to be defined, which helps to explicitly define which chain is being used. The exported helpers has a useful getBaseUrl method that forms the baseUrl based on a passed chain ID number.

For example, assuming you've already established a provider, you can connect to a Validator and retrieve node health info.

import { Database, Validator, helpers } from "@tableland/sdk";

// Get the chain ID from the ethers `provider`
const { chainId } = await provider.getNetwork(); // Or, statically define, e.g., `const chainId = 1`
// Passing the `signer` is optional here, but `baseUrl` is required for the `Validator`
const db = new Database({
  baseUrl: helpers.getBaseUrl(chainId),
});
// Instantiate a validator using an existing Database instance
const validator = new Validator(db.config);
console.log(validator);
//  {
//    config: {
//      baseUrl: "https://tableland.network/api/v1"
//    }
//  }
const isHealthy = await validator.health();
console.log(isHealthy);
// true

Registry

The SDK is in-part a JavaScript abstraction of the core Tableland registry smart contract. Developers can choose to interact directly with the Registry API for table creates and writes, if desired. It also offers a couple of additional features, such as listing all tables owned by an address or transferring table ownership altogether.

Since these are on-chain interactions, a signer is needed to interact with the Registry on a specific chain.

import { Database, Registry, helpers } from "@tableland/sdk";

// Creating the signer is required—use one of the examples above
const db = new Database({ signer });
// Instantiate the registry using an existing Database instance
const registry = await new Registry(db.config); // Must have a signer
// Get all tables owned by an address—defaults to the signer's address
const tables = await registry.listTables();
console.log(tables);
//  [
//    {
//      tableId: '2',
//      chainId: 1
//    }
//  ]

// Transfer a table to another address
const to = "0x1234..."; // A `0x` EVM address in which you're transfer table ownership to
const tx = await reg.safeTransferFrom({
  to,
  tableName: "{name}_{prefix}_{chainId}", // Replace with your table name
});
// Wait for the transaction to finalize, transferring table ownership
await tx.wait();

Build Tools

The Tableland SDK uses an optimized WASM build of our SQL parser under the hood. Unfortunately, some build systems such as Vite require an adjustment to their configuration to support this feature. To temporarily work around this issue, simply add @tableland/sqlparser to the excluded list under optimizeDeps in your vite.config.ts file:

// ...
optimizeDeps: {
  exclude: ["@tableland/sqlparser"];
}
// ...

See our own Rigs project for an example of using this in production.

Development

Get started by cloning, installing, building, and testing the project:

git clone [email protected]:tablelandnetwork/js-tableland.git
cd js-tableland
npm install
npm run build
npm test

To run tests in a few of the common browser environments we are using Playwright. Once your code changes are finished you can run the brower tests by doing:

  • cd test/browser/server
  • npm install
  • cd ../../
  • npm run test:browser

Contributing

PRs accepted.

Small note: If editing the README, please conform to the standard-readme specification.

License

MIT AND Apache-2.0, © 2021-2023 Tableland Network Contributors