Weeknotes: Table Studio launch, encrypting Tableland data with Lit Protocol, DePIN corner with Gensyn, and designing for people's actions

The official Tableland Studio launch, Tableland encryption with Lit Protocol for private data, Gensyn + the DePIN compute space, and thinking about what people do while designing products.

Begin transmission…

ICYMI: The Studio officially launched!

Over the past ~6 months, we've been heads down building a way for developers to easily onboard to Tableland & build onchain datasets & applications with SQL via a web app & CLI. Let's dive into some of the Tableland Studio’s core features:

  • Discover: The new landing shows you featured projects (like @HideoutLabs), new projects, trending tables, & a smoother way to navigate to your Studio teams/projects.

  • Collaborate: Create teams & projects to manage your tables—and invite others to inspect the table deployment & data.

  • Multichain: Deploy a table across any supported chains (@Filecoin, Ethereum, Optimism, Arbitrum, & Polygon).

  • Data & log inspection: You can take any table on the network—even if it wasn't created within the Studio—and check out its table data & all mutating SQL statements.

We published a blog about these features in more detail and an overview of the tech stack—and...it was built on Tableland! We've also open sourced the code and are open to contributions!

Check it out here: https://mirror.xyz/tableland.eth/368AbMTUPkZ3F3FAhZSP5xxDDQh1Qm2Gc5D3X-WFkbs

Table encryption with Lit Protocol

by Dan Buchholz

Data in Tableland is open by default, so anyone can read table data. If you want private data, you can implement your own encryption scheme—or use a decentralized like Lit Protocol to encrypt the data.

Lit is a decentralized threshold encryption network (key management) for signing and encrypting data. The premise is that instead of a single entity holding the entire private key, each node within the network holds a unique private key share. To obtain the final signature or decrypted content, a pre-defined threshold for the number of nodes is required for combining signatures or decryption shares. In other words, if your threshold is 2/3 of 100 nodes, you'd need to gather decryption or signature shares from at least 67 nodes.

Naturally, this is a perfect fit for encrypting and decrypting Tableland data! Let's walk through a simple example of how to use Lit to encrypt data before writing to Tableland, and then decrypting that data upon table reads. Note that Lit has its own built-in access control system that could be used in tandem with Tableland's access control, too.

Lit protocol setup with NodeJS

The following code uses the @lit-protocol/lit-node-client package, the siwe package, and the Tableland SDK. With frontend clients, the Lit SDK has built-in methods to create what's called an AuthSig; it's required if you need to decrypt any encrypted data. But, on the backend, you have to generate your own—the following shows how to do this by passing a Lit client and ethers signer. Note the chain used in this example is Ethereum Sepolia.

import { Database, helpers } from "@tableland/sdk"; import { Wallet, getDefaultProvider, utils } from "ethers"; import { LitNodeClient, uint8arrayFromString } from "@lit-protocol/lit-node-client"; import { SiweMessage } from "siwe"; const createAuthSig = async (client, wallet) => { // Arbitrary domain, origin, and statement for the Siwe message const domain = "localhost"; const origin = "<http://localhost>"; const statement = "Tableland encryption"; const expirationTime = new Date(Date.now() + 60 * 60 * 1000).toISOString(); const nonce = client.getLatestBlockhash(); // From the Lit client const chainId = await wallet.getChainId(); const address = await wallet.getAddress() const siweMessage = new SiweMessage({ domain, address, statement, uri: origin, version: "1", chainId, nonce, expirationTime, }); const messageToSign = siweMessage.prepareMessage(); const signature = await signer.signMessage(messageToSign); const recoveredAddress = utils.verifyMessage(messageToSign, signature); if (recoveredAddress !== address) { throw new Error("recovered address does not match wallet address"); } // Create an `AuthSig` for Lit const authSig = { sig: signature, derivedVia: "web3.eth.personal.sign", signedMessage: messageToSign, address: recoveredAddress, }; return authSig; };

This method can then be called to generate a SIWE message under the hood, which is required in an AuthSig that's later used for decryption.

Now, you can create a table, insert encrypted data, and decrypt it:

// Set up a signer/provider; replace with your own private key & API key const privateKey = "your_private_key_string"; const provider = getDefaultProvider( "https://eth-sepolia.g.alchemy.com/v2/your_alchemy_api_key" ); const wallet = new Wallet(privateKey); const signer = wallet.connect(provider); // Set up database and Lit client const db = new Database({ signer }); const client = new LitNodeClient({ debug: false }); await client.connect();

We can create a table as we normally do:

const tablePrefix = "lit_encrypt"; const createStmt = `CREATE TABLE ${tablePrefix} (id integer primary key, msg text, hash text)`; const { meta: create } = await db.prepare(createStmt).run(); const tableName = create.txn?.names[0] ?? ""; const tableId = create.txn?.tableIds[0] ?? ""; await create.txn?.wait();

We'll use Lit to encrypt the data before we write it. The encryption requires you to specify flexible access controls on who/how someone can decrypt the data. We'll keep our example simple: if you're the Tableland table owner, you can decrypt things.

// Generate an auth signature const authSig = await createAuthSig(client, signer); // Set up Lit access controls; use Tableland `getContractAddress` method const tablelandContract = helpers.getContractAddress(chainId); const accessControlConditions: AccsDefaultParams[] = [ { contractAddress: tablelandContract, chain: "sepolia", // Hard coding the Lit chain name standardContractType: "ERC721", method: "ownerOf", parameters: [tableId], returnValueTest: { comparator: "=", value: await signer.getAddress(), }, }, ]; // Now, we can encrypt the data before inserting const dataToEncrypt = "this is a secret message"; const { ciphertext, dataToEncryptHash } = await client.encrypt({ authSig, accessControlConditions, dataToEncrypt: uint8arrayFromString(dataToEncrypt), // Pass string as uint8 array chain: "sepolia", });

Lastly, we can write the encrypted data to the table, and then read the decrypted data with the authSig we created:

const { meta: write } = await db .prepare(`INSERT INTO ${tableName} (msg, hash) VALUES (?, ?)`) .bind(ciphertext, dataToEncryptHash) .run(); await write.txn?.wait(); // Read from the table const readStmt = `SELECT msg, hash FROM ${tableName}`; const { results } = await db .prepare(readStmt) .all<{ msg: string; hash: string }>(); // Decrypt the data read from the table for (const row of results) { const { msg, hash } = row; console.log("msg: ", msg); console.log("hash: ", hash); const { decryptedData } = await client.decrypt({ accessControlConditions, ciphertext: msg, dataToEncryptHash: hash, authSig, chain, }); const decrypted = Buffer.from(decryptedData.buffer).toString(); console.log("decrypted: ", decrypted); }

This will log the following; the first line is the encrypted message and hash that's stored in the table, and the second line is the decrypted message.

msg: rSIFVX0rCtKT6OMkWQD1TqKazrNg4B9nigsHUC/7dYkfjfW8erAZgNOHbO697gRoIVaL5Ry8GtsTsTjMyFLDMnNy6W9rmgCzgn5ALzBIUkog0VaI/NMdkCB44lUBr6EIsMdJ/2JhU8oIyLLXNv5mk+MD hash: 3f98b95c16476f0b2fc37e8e664a11312966b635f60537f1f5ed75216fa0c060 decrypted: this is a secret message

And that's a wrap! Tableland plus Lit encryption is quite a powerful setup because it lets you build a broader set up applications where table data should not be fully readable.

DePIN Corner: Gensyn

by Marla Natoli

There is a ton of anticipation in the AI community this week leading up to Nividia’s conference, and access to compute is a major necessity to ensure AI can thrive. That’s where Gensyn comes in. The Gensyn network refers to itself as the “machine learning compute protocol,” with a vision to unite the world’s compute, enabling any device in the world to contribute GPUs, thereby drastically decreasing the cost of access to compute.

Ben Fielding, co-founder and CEO of Gensyn, took the stage at various events across EthDenver, including our co-hosted Proof of Data Summit, where he spoke about Gensyn’s focus on building secure, cost effective access to compute for ML. When asked about exciting opportunities in web3, he referenced solving the data later, including a solution for provable data availability, which is precisely what we’re focused on at Textile.

The data availability solution we’re designing ensures fast access to data as well as longer-term archives with simplified retrievability from Filecoin. For a network like Gensyn, it would mean fast access to proofs available for a short period (programmable to specific needs, such as hours or days) to enable completion of a job and to handle disputes. This proof data could then be persisted over the long term, retrievable by network participants as needed for things like dispute resolution.

If you’re interested in learning more about our data availability solutions, feel free to set up some time with us here or join our Discord and get in touch

What people think and do

by Jim Kosem

Users. Participants. People. The fact is that you always have to be thinking about them when you’re designing and building software. How to understand what potential users might be thinking is key to building software. Everyone knows this. There are many ways into people’s thoughts, but the key is coming in at them from a lot of angles. I’ve spent the past week looking at and designing surveys, and even more time looking for how we can get the right participants to be asking things.

I’ve also spent a lot of time pouring over analytics, that is the numbers that show what your users are doing. How many people are clicking what? Which thing are they not doing that you thought they would? What are they not even seeing or likely not understanding? Both of these are things that one typically doesn’t think of a designer doing, but I think it’s key. To design you have to have something for someone to design for, and you have to have and use all the available tools in your belt to try to do that.


End transmission…

Want to dive deeper, ask questions, or just nerd out with us? Jump into our Telegram or Discord—including weekly research office hours or developer office hours. And if you’d like to discuss any of these topics in more detail, comment on the issue over in GitHub!

Are you enjoying Weeknotes? We’d love your feedback—if you fill out a quick survey, we’ll be sure to reach out directly with community initiatives in the future!: Fill out the form here

Textile Blog & Newsletter logo
Subscribe to Textile Blog & Newsletter and never miss a post.
  • Loading comments...