# Using Trinsic + Kwil This document proposes an approach for an identity application using [Trinsic](https://trinsic.id/) to integrate with a decentralized database on [Kwil](https://www.kwil.com/). The proposed system uses Trinsic for credential issuance and verification and Kwil for decentralized storage and management. ## Reading / Writing Credentials When a user accepts a Trinsic credential, the same service can encrypt and store the credential on Kwil. For example, using Kwil's and Trinsic's APIs: ```javascript import { TrinsicService } from "@trinsic/trinsic"; import { WebKwil, KwilSigner } from "@kwilteam/kwil-js"; async function acceptAndStoreCredential( trinsic: TrinsicService, credential: string, kwil: WebKwil, signer: KwilSigner ) { // accept credential on Trinsic const acceptCredentialResponse = await trinsic.credential().acceptCredential({ documentJson: credential, }) //** add credential encryption */ // store credential on Kwil return await kwil.execute({ dbid: "some_dbid", name: "store_credential", inputs: [{ $item_id: acceptCredentialResponse.itemId, $credential_json: acceptCredentialResponse.documentJson // or encrypted credential }] }, signer) } ``` Similarily, credentials are read from Kwil and verified with Trinsic: ```javascript import { TrinsicService } from "@trinsic/trinsic"; import { WebKwil, KwilSigner } from "@kwilteam/kwil-js"; async function retrieveAndGenerateProof( trinsic: TrinsicService, kwil: WebKwil, itemId: string ) { // retrieve credential from kwil const { data } = await kwil.call({ dbid: "some_dbid", name: "retrieve_credential", inputs: [{ $item_id: itemId }] }) const credential = data?.result[0].credential_json /** decrypt credential and do something */ // generate and return proof return await trinsic.credential().createProof({ documentJson: credential, itemId }) } ``` ## Kwil Key Management Writing data to Kwil requires a Secp256k1 key pair. The identity application can generate and custody a key for the user or use an admin key to write data on behalf of the user. ### Generate Key for User Generate a new wallet with a key that is custodied by the identity platform. The identity platform can use most key custody solutions (e.g. [AWS KMS](https://aws.amazon.com/blogs/database/make-eoa-private-keys-compatible-with-aws-kms/)). ```javascript import { Wallet } from 'ethers' import { KwilSigner } from '@kwilteam/kwil-js' function generateUserSigner(private_key: string) { const ethereumWallet = new Wallet(private_key) return new KwilSigner(ethereumWallet, ethereumWallet.address) } ``` ### Use Admin Key Use an admin private key (owned and managed by the identity application) to sign transactions on behalf of the user: ```javascript import { Wallet } from 'ethers' import { KwilSigner } from '@kwilteam/kwil-js' function generateAdminSigner() { const adminWallet = new Wallet("admin_private_key") return new KwilSigner(adminWallet, adminWallet.address) } ``` ## Launching a Multi-node Network The third component is launching a multi-node database network. - **[Tutorial Here](https://docs.kwil.com/docs/node/tutorial)** The Kwil Team can set up the network, run validators, run RPC nodes, and enable other stakeholders to run validators in the network (customers, investors, etc). The network will also need a database schema, which is defined using Kwil's [SQL smart contract language](https://docs.kwil.com/docs/kuneiform/introduction). A basic example schema is included below. ### Example Identity Schema This schema can be tested at admin.kwil.com. ```javascript database identity; // credentials stored encrypted verifiable credentials, tied to a user table credentials { item_id uuid primary key, credential_json text not null, submitted_by text not null } // regiser credential allows a user to add a credential to the database // if the credential already exists, it will error procedure store_credential ($item_id uuid, $credential_json text) public { // store credential INSERT INTO credentials (item_id, credential_json, submitted_by) VALUES ($item_id, $credential_json, @caller); } // retrieve credential gets a credential from the database procedure retrieve_credential ($item_id uuid) public view returns table(item_id uuid, credential_json text){ return SELECT item_id, credential_json FROM credentials WHERE item_id = $item_id; } // delete credential allows a user to remove a credential from the database // only the wallet that submitted the credential can remove it procedure delete_credential($item_id uuid) public { $record_owner text; // get the owner for the selected record for $owner in SELECT submitted_by FROM credentials WHERE item_id = $item_id { $record_owner := $owner.submitted_by; } // check if the person calling the action is the owner if $record_owner != @caller { error('you cannot delete a credential you do not own!'); } // delete the record DELETE FROM credentials WHERE item_id = $item_id; } ```