{"id":22998458,"url":"https://github.com/tablelandnetwork/js-tableland","last_synced_at":"2025-08-23T03:11:55.989Z","repository":{"id":37052067,"uuid":"433993797","full_name":"tablelandnetwork/js-tableland","owner":"tablelandnetwork","description":"Development has moved to https://github.com/tablelandnetwork/tableland-js/","archived":false,"fork":false,"pushed_at":"2023-10-16T15:44:27.000Z","size":5646,"stargazers_count":36,"open_issues_count":9,"forks_count":6,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-02-25T11:01:34.305Z","etag":null,"topics":["dapps","database","ethereum","filecoin","javascript","polygon","typescript","web3"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tablelandnetwork.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2021-12-01T21:40:46.000Z","updated_at":"2024-01-14T16:47:40.000Z","dependencies_parsed_at":"2022-06-25T04:45:17.425Z","dependency_job_id":null,"html_url":"https://github.com/tablelandnetwork/js-tableland","commit_stats":null,"previous_names":["textileio/js-tableland"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tablelandnetwork%2Fjs-tableland","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tablelandnetwork%2Fjs-tableland/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tablelandnetwork%2Fjs-tableland/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tablelandnetwork%2Fjs-tableland/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tablelandnetwork","download_url":"https://codeload.github.com/tablelandnetwork/js-tableland/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229786993,"owners_count":18124014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dapps","database","ethereum","filecoin","javascript","polygon","typescript","web3"],"created_at":"2024-12-15T06:13:29.393Z","updated_at":"2024-12-15T06:13:29.992Z","avatar_url":"https://github.com/tablelandnetwork.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @tableland/sdk\n\n**NOTICE**: Development has moved to: https://github.com/tablelandnetwork/tableland-js/\n\n[![Review](https://github.com/tablelandnetwork/js-tableland/actions/workflows/review.yml/badge.svg)](https://github.com/tablelandnetwork/js-tableland/actions/workflows/review.yml)\n[![Test](https://github.com/tablelandnetwork/js-tableland/actions/workflows/test.yml/badge.svg)](https://github.com/tablelandnetwork/js-tableland/actions/workflows/test.yml)\n[![Publish](https://github.com/tablelandnetwork/js-tableland/actions/workflows/publish.yml/badge.svg)](https://github.com/tablelandnetwork/js-tableland/actions/workflows/publish.yml)\n[![License](https://img.shields.io/github/license/tablelandnetwork/js-tableland.svg)](./LICENSE)\n[![Version](https://img.shields.io/github/package-json/v/tablelandnetwork/js-tableland.svg)](./package.json)\n[![Release](https://img.shields.io/github/release/tablelandnetwork/js-tableland.svg)](https://github.com/tablelandnetwork/js-tableland/releases/latest)\n[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg)](https://github.com/RichardLitt/standard-readme)\n\n\u003e Tableland JavaScript SDK—the essential tool for building web3 apps with Tableland databases.\n\n## Table of Contents\n\n- [Background](#background)\n- [Install](#install)\n- [Usage](#usage)\n  - [Database](#database)\n  - [Validator](#validator)\n  - [Registry](#registry)\n  - [Build Tools](#build-tools)\n- [Development](#development)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Background\n\nThe `@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.\n\n## Install\n\nYou can install via npm/yarn:\n\n```bash\nnpm i @tableland/sdk\n# yarn add @tableland/sdk\n```\n\nOr directly via GitHub:\n\n```bash\nnpm i tablelandnetwork/js-tableland\n```\n\n## Usage\n\nFull library documentation is [generated on GitHub](https://tablelandnetwork.github.io/js-tableland/), and\ngeneral docs, examples, and more are [available on our docs site](https://docs.tableland.xyz/sdk/).\n\n### Database\n\nA `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:\n\n- 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.\n- If you are _creating or writing to_ tables, you **do** need a signer since database mutations require an EVM account to send transactions.\n\nIf you need to set up a signer, libraries like [`ethers`](https://docs.ethers.org/v5/) 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.\n\n#### Connecting\n\nAs 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.\n\n```ts\nimport { Database } from \"@tableland/sdk\";\nimport { providers } from \"ethers\";\n\n// Connect to a chain provider, such as a browser wallet\nconst provider = new providers.Web3Provider(window.ethereum);\n// Request permission to connect to a users accounts\nawait provider.send(\"eth_requestAccounts\", []);\n\n// Create a signer from the connected browser wallet\nconst signer = provider.getSigner();\n// Create a database connection; the signer passes the connected\n// chain and is used for signing create table transactions\nconst db = new Database({ signer });\n```\n\nFor 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](https://docs.tableland.xyz/sdk/#chains).\n\n```ts\nimport { Database } from \"@tableland/sdk\";\nimport { Wallet, getDefaultProvider } from \"ethers\";\n\n// Define your private key (but replace with your own)\nconst privateKey = PRIVATE_KEY; // It's recommended to use `dotenv` and a place this in a `.env` file\n// Create the wallet (an extension of a signer)\nconst wallet = new Wallet(privateKey);\n// Connect to a provider (e.g., Alchemy, etc.)—you should pass your own\n// provider URL to `getDefaultProvider()` (avoid the throttled default)\n// For example: `https://eth-mainnet.alchemyapi.io/v2/${YOUR_API_KEY}`\nconst provider = getDefaultProvider(\"homestead\"); // Defaults to Ethereum mainnet\n// Create a signer by attaching the wallet to the provider\nconst signer = wallet.connect(provider);\n// Connect to the database\nconst db = new Database({ signer });\n```\n\nFor 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.\n\n```ts\nimport { Database } from \"@tableland/sdk\";\n\n// Create a database connection; since there is no signer,\n// table reads are possible but creates/writes are not\nconst db = new Database();\n```\n\nIf no `signer` is provided and you try to create or write to tables, the `Database` will default to prompting a browser wallet connection.\n\n#### Create, write, \u0026 read\n\nTo create a table, you pass a `CREATE TABLE` statement to the `prepare` method and then execute it.\n\n```ts\n// This is the table's `prefix`--a custom table value prefixed as part of the table's name\nconst prefix = \"my_sdk_table\";\n\nconst { meta: create } = await db\n  .prepare(`CREATE TABLE ${prefix} (id integer primary key, val text);`)\n  .run();\n\n// The table's `name` is in the format `{prefix}_{chainId}_{tableId}`\nconst { name } = create.txn; // e.g., my_sdk_table_80001_311\n```\n\nOnce 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.\n\n```ts\n// Insert a row into the table with an `INSERT INTO` statement\nconst { meta: insert } = await db\n  .prepare(`INSERT INTO ${name} (id, val) VALUES (?, ?);`)\n  .bind(0, \"Bobby Tables\")\n  .run();\n\n// Wait for transaction finality\nawait insert.txn.wait();\n```\n\nNotice 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.\n\n```ts\n// Perform a read query, requesting `all` rows from the table\nconst { results } = await db.prepare(`SELECT * FROM ${name};`).all();\n```\n\n### Validator\n\nAside 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](https://docs.tableland.xyz/gateway-api/).\n\nA 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.\n\nFor example, assuming you've already established a provider, you can connect to a `Validator` and retrieve node health info.\n\n```ts\nimport { Database, Validator, helpers } from \"@tableland/sdk\";\n\n// Get the chain ID from the ethers `provider`\nconst { chainId } = await provider.getNetwork(); // Or, statically define, e.g., `const chainId = 1`\n// Passing the `signer` is optional here, but `baseUrl` is required for the `Validator`\nconst db = new Database({\n  baseUrl: helpers.getBaseUrl(chainId),\n});\n// Instantiate a validator using an existing Database instance\nconst validator = new Validator(db.config);\nconsole.log(validator);\n//  {\n//    config: {\n//      baseUrl: \"https://tableland.network/api/v1\"\n//    }\n//  }\nconst isHealthy = await validator.health();\nconsole.log(isHealthy);\n// true\n```\n\n### Registry\n\nThe 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.\n\nSince these are on-chain interactions, a signer is needed to interact with the `Registry` on a specific chain.\n\n```ts\nimport { Database, Registry, helpers } from \"@tableland/sdk\";\n\n// Creating the signer is required—use one of the examples above\nconst db = new Database({ signer });\n// Instantiate the registry using an existing Database instance\nconst registry = await new Registry(db.config); // Must have a signer\n// Get all tables owned by an address—defaults to the signer's address\nconst tables = await registry.listTables();\nconsole.log(tables);\n//  [\n//    {\n//      tableId: '2',\n//      chainId: 1\n//    }\n//  ]\n\n// Transfer a table to another address\nconst to = \"0x1234...\"; // A `0x` EVM address in which you're transfer table ownership to\nconst tx = await reg.safeTransferFrom({\n  to,\n  tableName: \"{name}_{prefix}_{chainId}\", // Replace with your table name\n});\n// Wait for the transaction to finalize, transferring table ownership\nawait tx.wait();\n```\n\n### Build Tools\n\nThe Tableland SDK uses an optimized WASM build of our SQL parser under the hood. Unfortunately, some build systems such as [Vite](https://vitejs.dev) 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:\n\n```ts\n// ...\noptimizeDeps: {\n  exclude: [\"@tableland/sqlparser\"];\n}\n// ...\n```\n\nSee [our own Rigs project](https://github.com/tablelandnetwork/rigs/blob/main/animation_url/vite.config.ts#L17) for an example of using this in production.\n\n## Development\n\nGet started by cloning, installing, building, and testing the project:\n\n```shell\ngit clone git@github.com:tablelandnetwork/js-tableland.git\ncd js-tableland\nnpm install\nnpm run build\nnpm test\n```\n\nTo 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:\n\n- `cd test/browser/server`\n- `npm install`\n- `cd ../../`\n- `npm run test:browser`\n\n## Contributing\n\nPRs accepted.\n\nSmall note: If editing the README, please conform to the\n[standard-readme](https://github.com/RichardLitt/standard-readme) specification.\n\n## License\n\nMIT AND Apache-2.0, © 2021-2022 Tableland Network Contributors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftablelandnetwork%2Fjs-tableland","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftablelandnetwork%2Fjs-tableland","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftablelandnetwork%2Fjs-tableland/lists"}