Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(idos-sdk-js): internal AGs docs update #413

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 47 additions & 159 deletions packages/idos-sdk-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,38 +331,11 @@ An Access Grant means: I, `owner` (the user), have given you, `grantee` (the dAp

By acquiring an Access Grant, a dApp ensures that it'll have a copy of the user's data (either a credential or an attribute) until the UNIX timestamp on `lockedUntil` has passed. This is especially relevant to be able to fulfill compliance obligations.

This is achieved by combining two mechanisms:

- On idOS, by asking the user to share a credential/attribute, which creates a copy of its current state, encrypted to the `receiverPublicKey` you provide. The id of this copy is what's called `dataId`.
- On the blockchain you're using, by creating an Access Grant entry in a Smart Contract on the chain you're using.

The combination of doing these two operations is bundled in `idos.grants.create`, and that's the intended API for common usage. Here's an example of what that looks like:

```js
// These don't necessarily have to come from a server, but it's the typical setup.
const {
encryptionPublicKey,
lockTimeSpanSeconds,
grantee,
} = await yourBackendService.getInfo();

const { grant: { dataId } } = await idos.grants.create(
"credentials",
credentials[0].id,
grantee,
Math.floor(Date.now() / 1000) + lockTimeSpanSeconds,
encryptionPublicKey,
);
```

> 💡 Tip
>
> See a working example [idos-example-dapp](https://github.com/idos-network/idos-sdk-js/tree/main/examples/idos-example-dapp)

To avoid any doubts, let's go over the Access Grant fields:

- `owner`: on EVM chains this is a wallet address the user controls, and on NEAR this is a full access public key from an account the user controls.
- `grantee`: on EVM chains this is the dApp's grantee address (like explained in the previous section), and on NEAR this is a full access public key.
- `ownerUserId`: the grant owner idOS id.
- `granteeAddress`: on EVM chains this is the dApp's grantee address (like explained in the previous section), and on NEAR this is a full access public key.
- `dataId`: the `id` of the record copy (either a credential or an attribute) that is going to be shared.
- `lockedUntil`: the earliest UNIX timestamp when the contract will allow the Access Grant to be revoked. Any timestamp in the past, notably "0", means it's revocable at any time.

Expand All @@ -386,35 +359,6 @@ const entries = await idos.enclave.filterCredentials(credentials, {

In this example, `entries` will be a list of credentials where the `"credentialSubject.identification_document_country"` is `"DE"` and `"credentialSubject.identification_document_type"` is not `"passport"`.

You can also use `idos.grants.shareMatchingEntry`, a helper function that:
- Gets all the user's credentials
- Can filter by public fields
- Calls `idos.enclave.filterCredentials`
- Calls `idos.grants.create` with the first matching credential

Here's an example similar to the previous one, but that also filters a couple of public fields:

```js
await idos.grants.shareMatchingEntry(
"credentials",
{
credential_level: "basic",
credential_type: "kyc",
},
{
pick: {
"credentialSubject.identification_document_country": "DE"
},
omit: {
"credentialSubject.identification_document_type": "passport",
},
},
grantee,
Math.floor(Date.now() / 1000) + lockTimeSpanSeconds, // timelock
encryptionPublicKey,
);
```

### Checking Access Grant contents

By now, we have used the idOS to secure a copy of the data we need to operate.
Expand All @@ -425,17 +369,13 @@ Here's an example of how you could achieve that with [`📁 idos-sdk-server-dapp

```js
import { idOSGrantee } from "@idos-network/grantee-sdk-js";
import { ethers } from "ethers";

const granteeSigner = new ethers.Wallet(
process.env.EVM_GRANTEE_PRIVATE_KEY,
new ethers.JsonRpcProvider(process.env.EVM_NODE_URL),
);

const idosGrantee = await idOSGrantee.init({
chainType: "EVM",
granteeSigner,
granteeSignerPrivateKey: process.env.EVM_GRANTEE_PRIVATE_KEY,
encryptionSecret: process.env.ENCRYPTION_SECRET_KEY,
nodeUrl: process.env.EVM_IDOS_NODE_URL,
dbId: process.env.EVM_IDOS_DB_ID,
});

// This assumes we got `dataId` (from a request body, a script argument, etc).
Expand All @@ -457,13 +397,7 @@ Here's a diagram comparing the two cases side-by-side:

<img src="https://raw.githubusercontent.com/idos-network/idos-sdk-js/main/packages/idos-sdk-js/assets/readme-ag-vs-dag.png" />

This is accomplished by getting the user's signature a specific message, generated with the contract's `insert_grant_by_signature_message` method, that can then be used to call the contract's `insert_grant_by_signature` method.

The message building function is exposed as `idos.grants.messageForCreateBySignature`. Submitting the resulting message and its user signature is exposed as `idosGrantee.createBySignature`.

> ⚠️ Notice
>
> This is not implemented for NEAR yet. If you want to use dAGs today, you'll have to call the right contract directly.
This is accomplished by sharing the user's credential using `shareCredentialByGrant` which is described in detail in this [example](#creating-an-access-grant).

## Quick reference

Expand Down Expand Up @@ -527,7 +461,7 @@ const { userId } = await idos.setSigner(CHAIN_TYPE, signer);
const credentials = await idos.data.list("credentials");

//Get all credentials that match a condition
const credentials = await idos.data.list("credentials", { issuer: "Fractal ID" };
const credentials = await idos.data.list("credentials", { issuer: "Fractal ID" });

// Get the credential details
const { id } = credentials.find(c => c.credential_type === "basic");
Expand All @@ -552,109 +486,63 @@ await idos.data.delete("attributes", id);

### Access Grant creation / revocation / list

Here's some example code of creating, revoking and listing Access Grants.

### Creating an Access Grant
Sharing a credential will create an Access Grant for the passed grantee.
We're using some variables from `createCredentialByGrant` example. so make sure to check it out at [issuer-sdk-js's README](https://github.com/idos-network/idos-sdk-js/tree/main/packages/idos-sdk-js#readme)
```js
// Decide on the credential you want to create an Access Grant for
const credentialId = credentials[0].id;

// Share a credential by creating an access grant
const { grant } = await idos.grants.create(
"credential",
credentialId,
grantee,
timelock,
receiverPublicKey
);
/*
* Server side.
*/

// Revoke an access grant
await idos.grants.revoke(
"credentials",
credentialId,
grantee,
dataId,
timelock
);
import { shareCredentialByGrant } from "@idos-network/issuer-sdk-js";
import issuerConfig from "./issuer-config.js";

// List all grants that match a criteria
await idos.grants.list({
owner,
dataId,
grantee,
});
await shareCredentialByGrant(issuerConfig, {
...credentialPayload,
granteeAddress: "GRANTEE_WALLET_ADDRESS",
recepientEncryptionPublicKey: new Uint8Array([ /* grantee public encryption key (in bytes) */]),
lockedUntil: Math.floor(Date.now() / 1000) + LOCKED_UNTIL_SECONDS,
originalCredentialId: credentialPayload.id,
publicNotes: "", // make sure to pass an empty string
})

// Share a credential that matches the filtering criteria.
await idos.grants.shareMatchingEntry(
"credentials",
{
credential_level: "basic",
credential_type: "kyc",
},
{
pick: {
"credentialSubject.identification_document_country": "DE",
},
omit: {},
},
grantee,
0, // timelock
"zleIscgvb3usjyVqR4OweNM2oXwmzADJVO3g7byuGk8=", // receiverPublicKey
);
```

### Creating a dAG on EVM
#### Revoke an Existing Access Grant

```js
/*
* Client side.
*/
// Get the grantId of the grant you want to revoke
const grantId = grants[0].id;

// Create a share (duplicate) in the idOS and get its id:
const { id: dataId } = await idos.data.share(tableName, recordId, receiverPublicKey);
// Revoke the grant
await idos.grants.revokeGrant(grantId);
```

// Get a message that needs to be signed by the user:
const message = await idos.grants.messageForCreateBySignature({
owner,
grantee,
dataId,
lockedUntil
});

// The dApp should ask the user to sign this message:
const { signature } = await wallet.signMessage({ message, recipient, nonce });
#### List All Grants You Granted to Other Grantees

/*
* Server side.
*
* ⚠️ Notice: Not implemented for NEAR yet.
*/
import { idOSGrantee } from "@idos-network/grantee-sdk-js";
import { ethers } from "ethers";
```js
await idos.grants.getGrantsOwned();
```

const granteeSigner = new ethers.Wallet(
process.env.EVM_GRANTEE_PRIVATE_KEY,
new ethers.JsonRpcProvider(process.env.EVM_NODE_URL),
);
#### List All Grants Granted to You by Grantors

// Initialize the idOSGrantee
const idosGrantee = await idOSGrantee.init({
chainType: "EVM",
granteeSigner,
encryptionSecret: process.env.ENCRYPTION_SECRET_KEY
});
```js
const page = 1; // Page number for pagination
const size = 10; // Number of grants per page

// Create the dAG
await idosGrantee.createBySignature({
// These values need to be the same you used to generate the signed message
owner,
grantee,
dataId,
lockedUntil,
// This is the signature you got from the user.
signature,
})
await idos.grants.getGrantsGranted(page, size);
```

#### Check if a Grant is Still Locked

```js
// Check if a grant is still locked (i.e., the locked until date has not passed yet)
await idos.grants.hasLockedGrants(grantId);
```



## Developing the SDK locally

Create an `.env.development.local` file in the root folder of the SDK package and add the needed environment variables (you can reference `.env` for the variable names).
Expand Down
Loading