---
# System prepended metadata

title: Using Trinsic + Kwil

---

# 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;
}
```