From b6d1a37f2dd82b8b9692f8a12cf6df300fa01339 Mon Sep 17 00:00:00 2001 From: dudleyneedham Date: Wed, 14 May 2025 10:14:28 +0200 Subject: [PATCH 1/3] feat: adding the draft dids from chris --- docs/sdk/04_dids.md | 441 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) diff --git a/docs/sdk/04_dids.md b/docs/sdk/04_dids.md index fff66ad47..b6b7b3105 100644 --- a/docs/sdk/04_dids.md +++ b/docs/sdk/04_dids.md @@ -2,3 +2,444 @@ id: dids title: DID --- + +A Decentralized Identifier (DID) is a string uniquely identifying each KILT user. +A DID may represent any entity, such as a person, an organization, or a machine. +You can store information about a DID on the KILT chain, which is useful for different use cases. + +The `Kilt.DidHelpers` namespace of the KILT SDK provides the methods to create, update, and delete DIDs on the KILT blockchain. + +:::info Light DIDs + +Older versions of the KILT SDK supported creating "light DIDs," usable offline with no connection with the KILT blockchain. + +This is no longer recommended, but [you can use pre-version 1.0 of the SDK to create them](/docs/0.3/sdk/cookbook/dids/light-did-creation) if you need to. + +::: + +## Create + +:::info + +Use the `createDid` method from the `DidHelpers` class to create a DID on the chain. + +[Read more in the API documentation](https://kiltprotocol.github.io/sdk-js/functions/sdk_js_src.DidHelpers.createDid.html). + +::: + + + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +The KILT SDK provides the `createDid` method from the `DidHelpers` class to create a DID on the chain. +It takes the following parameters: + +- `api`: The connection to the KILT blockchain. +- `signers`: An array of keys used for verification methods in the DID Document. For creating a DID, you only need the key for the authentication verification method. +- `submitter`: The account used to submit the transaction to the blockchain. + + :::caution + + The submitter account must have enough funds to cover the required storage deposit. + + ::: + +- `fromPublicKey`: The public key that features as the DID's initial authentication method and determines the DID identifier. + +The method returns a `TransactionHandler` type, which includes two methods: + +- `submit`: Submits a transaction for inclusion in a block on the blockchain. + + :::info + + The `submit()` method by default, waits for the block to be finalized. + [You can override this behavior](https://kiltprotocol.github.io/sdk-js/interfaces/types_src.TransactionHandlers.html) by passing `false` to the `awaitFinalized` named parameter of the `submit` object. + + ::: + +## Derivation paths + +The code example below derives different types of keys from a single account using derivation paths. + +A derivation path is a way to derive a new key from a parent key and is a sequence of indices separated by a delimiter. +The most common delimiter is `/` (forward slash). + +KILT uses the same derivation paths as the underlying Polkadot libraries, using hard key derivation. + +#### Hard derivation + +A hard derivation path does not allow someone to do either of these. +Even if you know a derived private key, it's not possible to figure out the private key of the root address, and it's impossible to prove that the first account is linked with the second. + +A `//` (double slash) indicates a hard derivation path. +For example, `deal rice sunny now boss cluster team use wreck electric wing deliver//0` is a hard derivation path. + +To create another account using the same seed, change the number at the end of the string. For example, `/1`, `/2`, and `/3` create different derived accounts. + +Using derivation paths simplifies key management, ensuring that a single mnemonic seed serves as the basis for multiple keys associated with a DID. +This method improves efficiency while maintaining security. +However, it's essential to handle and store private keys securely to prevent unauthorized access and ensure the overall integrity and privacy of the decentralized identity system. + +Below is an example code snippet illustrating the key pair generation for a KILT DID: + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +:::info +This example doesn't show how to store the keys. +It is recommended to store the keys in a secure manner, e.g. only storing the private keys encrypted on disk. +The mnemonic seed phrase can be used to regenerate the keys, so it is recommended to also store the mnemonic in a secure manner and create a backup of it. +::: + +## Update a DID + +Once anchored to the KILT blockchain, you can update a full DID. +The SDK doesn't have a specific method for updating a DID, instead you use relevant methods to update the DID. + +### Services + +#### Add a service + +:::info + +Use the `addService` method from the `DidHelpers` class to add a service to a DID. + +[Read more in the API documentation](https://kiltprotocol.github.io/sdk-js/functions/sdk_js_src.DidHelpers.addService.html). + +::: + +```ts +const transactionHandler = Kilt.DidHelpers.addService({ + api, + submitter, + signers: [didKeypair], + didDocument, + // TODO: change service endpoint. + service: { + id: '#email_service', + type: ['https://schema.org/email'], + serviceEndpoint: ['mailto:info@kilt.io'], + }, + }) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +#### Remove a service + +:::info + +Use the `removeService` method from the `DidHelpers` class to add a service to a DID. + +[Read more in the API documentation](https://kiltprotocol.github.io/sdk-js/functions/sdk_js_src.DidHelpers.removeService.html). + +::: + +```ts +const transactionHandler = Kilt.DidHelpers.addService({ + api, + submitter, + signers: [didKeypair], + didDocument, + // TODO: change service endpoint. + service: { + id: '#email_service', + type: ['https://schema.org/email'], + serviceEndpoint: ['mailto:info@kilt.io'], + }, + }) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +## Delete + +Once a DID is no longer needed, it is recommended to deactivate it by removing it from the KILT blockchain. +The following snippet shows how to do it: + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +:::warning +Please note that once deleted, a full DID becomes unusable and cannot be re-created anymore. +This means that all credentials obtained with that DID are no longer valid and must be obtained with a different DID if needed. +::: + +### Claim back a DID deposit + +Claiming back the deposit of a DID is semantically equivalent to deactivating and deleting the DID, with the difference that the extrinsic to claim the deposit can only be called by the deposit owner and does not require a signature by the DID subject: + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +## Query + +Querying the state of a DID is called **resolution**. +The entity that queries the DID Document for a given DID, i.e., resolves it, is called a **resolver**. + +The KILT SDK provides such a resolver to use with KILT DIDs, as the snippet below shows: + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +:::note +The DID resolver can resolve both light and full DIDs. +For a more in-depth explanation about the KILT DID method and resolution, refer to our [specification](https://github.com/KILTprotocol/spec-kilt-did). +::: + +## Generate DID keys + + + +Creating a Decentralized Identifier (DID) on the KILT network involves generating keying material for authentication and encryption. +This guide shows how to create a set of key pairs suitable for generating a KILT DID. + +Before proceeding, it's important to note that this example assumes the usage of the `@kiltprotocol/sdk-js` library along with the `@polkadot/util-crypto` library for cryptographic operations. + +Additionally, it's important to securely store keys and the mnemonic seed phrase. +For production use, ensure that private keys are encrypted and stored safely, while also creating a backup of the mnemonic seed phrase. + +## Build DID Extrinsics + +DID keys can be used to sign extrinsic. +But not every extrinsic can be signed using a DID. +The Spiritnet blockchain offers two types of extrinsics. + +The first type can only be called using an account. +We call them account extrinsic. +The second callable type are DID extrinsics. +They must be used for all KILT features like creating CTypes, issue attestations, etc. +Since every extrinsic requires fees to be paid, this type needs to be wrapped inside an account extrinsic. +Accounts hold balances and can therefore pay fees and provide deposits. + +This document describes how to sign the DID extrinsics. +The KILT SDK provides two functions for signing DID extrinsics. +The first function signs a single extrinsic while the second one batches multiple extrinsics together. + +## Single extrinsics + +To sign a single extrinsic, you need to provide: + +- the DID that wants to sign the extrinsic (also called _origin_ of the extrinsic) + + +- the extrinsic that should be signed and submitted +- and the address of the account that pays for the fees. + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +## Batch multiple extrinsics + +Full DIDs can also be used to batch multiple extrinsics that require the signature of the DID. +For instance, a batch could create multiple services with a single submission to the blockchain. +This would save the user the time of generating one additional signature, as multiple extrinsics are batched and signed at once. +The extrinsics are also submitted and executed in the same block. +For more information, see the [official Substrate documentation](https://paritytech.github.io/substrate/master/pallet_utility/pallet/struct.Pallet.html). + +An example of a batch using the `authorizeBatch` is provided below. + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +DIDs have different keys that posses different capabilities. +Each key can only be used to authorize a specific subset of extrinsics. +If extrinsics are batched together that require different DID keys, the `authorizeBatch` function will call the sign callback multiple times. + +## Generate and Verify a DID Signature + +In addition to being used to authorize chain operations, both light and full DIDs have off-chain applications. + +One such applications is generating digital signatures. +As a DID can have multiple keys, in addition to the signature data itself, a DID signature contains information about the signer's DID and key used, so that Verifiers have all the information needed to resolve the DID from the KILT blockchain and use the right key to verify the generated signature. + +The snippet below shows how to generate and verify a DID signature using the KILT SDK. + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +:::note +Notice that the snippet above takes a `DidDocument` instance to generate the signature. +A `DidDocument` can represent either a light or a full DID. +This means that both light and full DIDs can generate signatures, and the KILT SDK implements the right verification logic depending on whether the signer is a light or a full DID. +::: + +## web3names + +### Claim a web3name + +A web3name can be claimed if it currently has no owner, using the following snippet as reference. + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +The claiming process requires the reservation of a deposit that is freed upon web3name release. + +Once claimed, the web3name will start appearing whenever the DID of its owner is resolved, for instance via the [Universal Resolver](https://dev.uniresolver.io/#did:kilt:4pZGzLSybfMsxB1DcpFNYmnqFv5QihbFb1zuSuuATqjRQv2g). +For more information about web3names and DIDs, see the official [KILT DID Specification](https://github.com/KILTprotocol/spec-kilt-did/blob/main/README.md). + +### Query public credentials for a web3name + +web3names are linked to KILT DIDs, and KILT DIDs can define services to expose additional service/information. +One of the possible endpoint types is the [`KiltPublishedCredentialCollectionV1`][kilt-published-credential-collection-v1-type] type. +The type defines the structure to make KILT credentials public and accessible to anyone. + +Because of the relationship between web3names and DIDs, it is possible, given a certain web3name, to retrieve all public credentials that the DID subject identified by that web3name has made available. +Below is a code snippet showing how to do that using the KILT SDK, and how to perform the needed security checks/validation as recommended by the [specification][kilt-published-credential-collection-v1-type]. + + + {QueryNameCredentials} + + +[kilt-published-credential-collection-v1-type]: https://github.com/KILTprotocol/spec-KiltPublishedCredentialCollectionV1/blob/main/README.md + +### Release a web3name + +If a web3name is no longer needed, either the DID owner or the deposit payer can release it, with deposit being released and returned to the original payer. + +### Releasing a Web3name by the DID Owner + +In the case of the DID owner willing to release the web3name, the following snippet provides a reference implementation on how to achieve that. + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +In the code above, the `releaseWeb3Name` function takes the following parameters: + +- **did**: The DID URI of the owner. +- **submitterAccount**: The keyring pair of the submitter. + + +The function `releaseWeb3Name` uses the KILT SDK to create a _web3name release transaction_ using `api.tx.web3Names.releaseByOwner`. +It then authorizes the transaction using the `Kilt.Did.authorizeTx` method and submits the authorized transaction to the blockchain using `Kilt.Blockchain.signAndSubmitTx`. +This process ensures that the release transaction is signed by the DID owner. + +### Reclaiming a Web3name Deposit by the Deposit Payer + +If the web3name is being released by the deposit payer, the signature of the DID owner is not required; a regular signed extrinsic can be submitted to the KILT blockchain, as shown below. + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +In the code above, the `reclaimWeb3NameDeposit` function takes the following parameters: + +- **submitterAddress**: The keyring pair of the submitter. +- **web3Name**: The web3name for which the deposit is to be reclaimed. + +The function creates a web3name deposit reclaim transaction using `api.tx.web3Names.reclaimDeposit` and submits the signed transaction to the blockchain using `Kilt.Blockchain.signAndSubmitTx`. +Since the web3name is being released by the deposit payer, the signature of the DID owner is not required. + +By using these code examples, you can easily release or reclaim the deposit of a web3name, depending on the scenario and the role of the entity initiating the release. + +### Resolve a web3name + + + +Resolving the web3name will provide the same information as resolving a DID does. + +To query and retrieve the DID document associated with a web3name, you can use the following code example: + +```ts +const transactionHandler = Kilt.DidHelpers.createDid({ + api, + signers: [authenticationKeyPair], + submitter: submitterAccount, + fromPublicKey: authenticationKeyPair.publicKeyMultibase +}) + +const didDocumentTransactionResult = await transactionHandler.submit() +``` + +In the code example above, the `queryDidDocument` function takes a web3Name parameter, which represents the web3name to be resolved. +It internally uses the `api.call.did.queryByWeb3Name` method to query the information of the provided web3name from the blockchain. + +The function then decodes the result using `Kilt.Did.linkedInfoFromChain` to extract the associated DID document and any other linked blockchain accounts. Finally, it returns the resolved DID document. From 2539b243c5506590f40fd55528c2f380e47619b3 Mon Sep 17 00:00:00 2001 From: dudleyneedham Date: Wed, 14 May 2025 14:56:45 +0200 Subject: [PATCH 2/3] feat: adding quickstart guide from aybars --- docs/sdk/01_quickstart.md | 255 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) diff --git a/docs/sdk/01_quickstart.md b/docs/sdk/01_quickstart.md index 50476322c..3e1cbb415 100644 --- a/docs/sdk/01_quickstart.md +++ b/docs/sdk/01_quickstart.md @@ -2,3 +2,258 @@ id: quickstart title: Quickstart --- + +import CodeBlock from '@theme/CodeBlock'; +import SnippetBlock from '@site/src/components/SnippetBlock'; +import TsJsSnippet from '@site/src/components/TsJsSnippet'; +import TsJsBlock from '@site/src/components/TsJsBlock'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +import ConnectSpirit from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/02_connect_spirit.ts'; +import ConnectPere from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/02_connect_pere.ts'; +import FetchDid from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/03_fetch_did.ts'; +import FetchEndpoints from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/04_fetch_endpoints.ts'; +import FetchEndpointData from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/05_fetch_endpoint_data.ts'; +import VerifyCredential from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/06_verify_credential.ts'; +import Disconnect from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/07_disconnect.ts'; + +Get started with KILT by following this guide, which teaches you to: + +1. Import the **KILT SDK** into your project +2. Connect to the **KILT blockchain** +3. Query a **web3name** to retrieve its **DID** +4. Verify a **credential** using a **DID service** + +:::info Prerequisites + +This quickstart guide provides hands-on experience to enhance your understanding of KILT. +Basic knowledge of JavaScript and command-line tools is recommended. + +::: + +## Core Functions Explained + +Throughout this guide, we use several key functions from the KILT SDK: + +### Kilt.connect() + +This function establishes a connection to a KILT blockchain node: + +- Creates a WebSocket connection to the specified node +- Initializes the blockchain API interface +- Enables communication with the KILT network + +### Did.linkedInfoFromChain() + +This function processes blockchain data to extract DID information: + +- Takes encoded blockchain data as input +- Decodes the DID document information +- Returns the structured DID document with its identifier + +### Kilt.DidResolver.resolve() + +The resolver function retrieves comprehensive DID information: + +- Takes a DID identifier as input +- Queries the blockchain for the complete DID Document +- Returns service endpoints and other DID-related data +- Useful for finding where to query for credentials + +### Kilt.Verifier.verifyCredential() + +This crucial function performs comprehensive credential verification: + +- Validates the credential's cryptographic signatures +- Checks if the credential has been revoked +- Verifies the credential's format and structure +- Returns a verification result object with detailed status + +The verification result includes: + +- `verified`: Boolean indicating overall validity +- Details about the verification process +- Any errors or issues encountered + +## Setup + +Create a new project and directory and move into the directory by running `mkdir kilt-rocks && cd kilt-rocks`. + + + + +Inside the `kilt-rocks` project directory, install the **KILT SDK**, **Typescript**, **ts-node**, and **Axios** dependencies: + +```bash npm2yarn +npm init -y +npm install @kiltprotocol/sdk-js @kiltprotocol/did @kiltprotocol/credentials ts-node typescript axios +``` + +With the required dependencies installed, create a TypeScript file with `touch quickstart.ts`. + + + + +From inside the `kilt-rocks` project directory, install the **KILT SDK**, **Node**, and **Axios** dependencies: + +```bash npm2yarn +npm init -y +npm install @kiltprotocol/sdk-js @kiltprotocol/did @kiltprotocol/credentials node axios +``` + +With the required dependencies installed, create a JavaScript file with `touch quickstart.js`. + +To enable ES modules in your project, add `"type": "module"` to the `package.json` file. + + + + +Declare an `async main` function that executes the rest of the code in this quickstart: + +```js +async function main() { +} + +main() +``` + +**With the setup completed, let's get started! 🔥** + +### Import the KILT SDK + +Begin by importing the required packages. Each package serves a specific purpose: + +- `@kiltprotocol/sdk-js`: Core SDK functionality for blockchain interaction +- `@kiltprotocol/did`: Handles DID (Decentralized Identifier) operations +- `@kiltprotocol/credentials`: Manages credential types and verification +- `axios`: Used for HTTP requests to credential endpoints + +```js +import * as Kilt from "@kiltprotocol/sdk-js"; +import axios from "axios"; +import * as Did from "@kiltprotocol/did"; +import { types } from "@kiltprotocol/credentials"; +``` + +### Connect to the KILT Blockchain + +To perform operations that rely on the **KILT blockchain**, first establish a connection that allows you to query the blockchain state and interact with smart contracts. + + + +

Peregrine is the development blockchain. + Connect to this network for testing and development purposes.

+ + {import type { ApiPromise } from '@polkadot/api' + +import * as Kilt from '@kiltprotocol/sdk-js' + +export async function main(): Promise { + let api = await Kilt.connect('wss://peregrine.kilt.io/') + + return api +} } + +
+ +

Spiritnet is the production blockchain. + When you are ready to publish your DApp, connect to the Spiritnet network for production purposes.

+ + {import type { ApiPromise } from '@polkadot/api' + + import * as Kilt from '@kiltprotocol/sdk-js' + + export async function main(): Promise { + let api = await Kilt.connect('wss://spiritnet.kilt.io/') + + return api + } + } + +
+
+ +## Query a KILT Identity + +The following code demonstrates how to retrieve a DID associated with a web3name. Web3names are human-readable identifiers that map to DIDs on the KILT blockchain: + + +{FetchDid} + + +Try running the code and check the result. + +Did you get the DID? You now have `kiltnerd123`'s DID. The next step is to see if `kiltnerd123` has any publicly linked KILT credentials to retrieve and verify. + +## Retrieve and Verify a Credential + +A **KILT DID** can expose services that allow external resources to be linked to the DID. **KILT credentials** represent one type of external resource. + +First, retrieve the services exposed by the DID: + + +{FetchEndpoints} + + +The code should print endpoints as JSON. + +Next, query the endpoint to retrieve a credential: + + + {FetchEndpointData} + + +Finally, verify the credential using KILT's verification system: + + +{VerifyCredential} + + +To ensure proper cleanup, make sure to disconnect at the end of your main function: + + +{Disconnect} + + +## Running the Code + + + + +```bash +yarn ts-node quickstart.ts +``` + + + + +```bash +node quickstart.js +``` + + + + +:::info Next steps + +- If you want to explore more of KILT's features, read our [Concepts section](../../concepts/01_what_is_kilt.md). +- If you want to dive deeper into the SDK, read the next section, [the KILT Cookbook](./02_cookbook/01_dids/01_light_did_creation.md). + +::: From a3a4fd71a794b8c31645b3f98f09a7e31c2c82f1 Mon Sep 17 00:00:00 2001 From: dudleyneedham Date: Wed, 14 May 2025 15:21:52 +0200 Subject: [PATCH 3/3] feat: updating the docs --- docs/sdk/01_quickstart.md | 254 ++++++++++++++++++++++---------------- 1 file changed, 150 insertions(+), 104 deletions(-) diff --git a/docs/sdk/01_quickstart.md b/docs/sdk/01_quickstart.md index 3e1cbb415..061fcf1ee 100644 --- a/docs/sdk/01_quickstart.md +++ b/docs/sdk/01_quickstart.md @@ -3,113 +3,109 @@ id: quickstart title: Quickstart --- -import CodeBlock from '@theme/CodeBlock'; -import SnippetBlock from '@site/src/components/SnippetBlock'; -import TsJsSnippet from '@site/src/components/TsJsSnippet'; -import TsJsBlock from '@site/src/components/TsJsBlock'; -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -import ConnectSpirit from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/02_connect_spirit.ts'; -import ConnectPere from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/02_connect_pere.ts'; -import FetchDid from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/03_fetch_did.ts'; -import FetchEndpoints from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/04_fetch_endpoints.ts'; -import FetchEndpointData from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/05_fetch_endpoint_data.ts'; -import VerifyCredential from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/06_verify_credential.ts'; -import Disconnect from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/getting_started/07_disconnect.ts'; - Get started with KILT by following this guide, which teaches you to: -1. Import the **KILT SDK** into your project -2. Connect to the **KILT blockchain** -3. Query a **web3name** to retrieve its **DID** +1. Import the **KILT SDK** into your project +2. Connect to the **KILT blockchain** +3. Query a **web3name** to retrieve its **DID** 4. Verify a **credential** using a **DID service** -:::info Prerequisites - -This quickstart guide provides hands-on experience to enhance your understanding of KILT. -Basic knowledge of JavaScript and command-line tools is recommended. - -::: +> **Prerequisites:** +> This quickstart guide provides hands-on experience to enhance your understanding of KILT. +> Basic knowledge of JavaScript and command-line tools is recommended. ## Core Functions Explained -Throughout this guide, we use several key functions from the KILT SDK: - -### Kilt.connect() +### `Kilt.connect()` This function establishes a connection to a KILT blockchain node: -- Creates a WebSocket connection to the specified node -- Initializes the blockchain API interface -- Enables communication with the KILT network +- Creates a WebSocket connection to the specified node +- Initializes the blockchain API interface +- Enables communication with the KILT network -### Did.linkedInfoFromChain() +### `Did.linkedInfoFromChain()` This function processes blockchain data to extract DID information: -- Takes encoded blockchain data as input -- Decodes the DID document information -- Returns the structured DID document with its identifier +- Takes encoded blockchain data as input +- Decodes the DID document information +- Returns the structured DID document with its identifier -### Kilt.DidResolver.resolve() +### `Kilt.DidResolver.resolve()` The resolver function retrieves comprehensive DID information: -- Takes a DID identifier as input -- Queries the blockchain for the complete DID Document -- Returns service endpoints and other DID-related data -- Useful for finding where to query for credentials +- Takes a DID identifier as input +- Queries the blockchain for the complete DID Document +- Returns service endpoints and other DID-related data +- Useful for finding where to query for credentials -### Kilt.Verifier.verifyCredential() +### `Kilt.Verifier.verifyCredential()` This crucial function performs comprehensive credential verification: -- Validates the credential's cryptographic signatures -- Checks if the credential has been revoked -- Verifies the credential's format and structure -- Returns a verification result object with detailed status +- Validates the credential's cryptographic signatures +- Checks if the credential has been revoked +- Verifies the credential's format and structure +- Returns a verification result object with detailed status The verification result includes: -- `verified`: Boolean indicating overall validity -- Details about the verification process -- Any errors or issues encountered +- `verified`: Boolean indicating overall validity +- Details about the verification process +- Any errors or issues encountered ## Setup -Create a new project and directory and move into the directory by running `mkdir kilt-rocks && cd kilt-rocks`. +Create a new project and directory: + +```bash +mkdir kilt-rocks && cd kilt-rocks +``` -Inside the `kilt-rocks` project directory, install the **KILT SDK**, **Typescript**, **ts-node**, and **Axios** dependencies: +Install the dependencies: ```bash npm2yarn npm init -y npm install @kiltprotocol/sdk-js @kiltprotocol/did @kiltprotocol/credentials ts-node typescript axios ``` -With the required dependencies installed, create a TypeScript file with `touch quickstart.ts`. +Create a TypeScript file: + +```bash npm2yarn +touch quickstart.ts +``` -From inside the `kilt-rocks` project directory, install the **KILT SDK**, **Node**, and **Axios** dependencies: +Install the dependencies: ```bash npm2yarn npm init -y npm install @kiltprotocol/sdk-js @kiltprotocol/did @kiltprotocol/credentials node axios ``` -With the required dependencies installed, create a JavaScript file with `touch quickstart.js`. +Create a TypeScript file: -To enable ES modules in your project, add `"type": "module"` to the `package.json` file. +```bash npm2yarn +touch quickstart.ts +``` -Declare an `async main` function that executes the rest of the code in this quickstart: +Enable ES modules by adding the following to your package.json: + +```json +"type": "module" +``` + +Declare an async main function: ```js async function main() { @@ -144,39 +140,37 @@ To perform operations that rely on the **KILT blockchain**, first establish a co

Peregrine is the development blockchain. Connect to this network for testing and development purposes.

- - {import type { ApiPromise } from '@polkadot/api' -import * as Kilt from '@kiltprotocol/sdk-js' +```ts + import type { ApiPromise } from '@polkadot/api' -export async function main(): Promise { - let api = await Kilt.connect('wss://peregrine.kilt.io/') + import * as Kilt from '@kiltprotocol/sdk-js' + + export async function main(): Promise { + let api = await Kilt.connect('wss://peregrine.kilt.io/') + + return api + } + ``` - return api -} } -

Spiritnet is the production blockchain. When you are ready to publish your DApp, connect to the Spiritnet network for production purposes.

- - {import type { ApiPromise } from '@polkadot/api' - import * as Kilt from '@kiltprotocol/sdk-js' +```ts +import type { ApiPromise } from '@polkadot/api' + + import * as Kilt from '@kiltprotocol/sdk-js' - export async function main(): Promise { - let api = await Kilt.connect('wss://spiritnet.kilt.io/') + export async function main(): Promise { + let api = await Kilt.connect('wss://spiritnet.kilt.io/') + + return api + } +} +``` - return api - } - } -
@@ -184,12 +178,22 @@ export async function main(): Promise { The following code demonstrates how to retrieve a DID associated with a web3name. Web3names are human-readable identifiers that map to DIDs on the KILT blockchain: - -{FetchDid} - +``` ts +import * as Kilt from '@kiltprotocol/sdk-js' +import * as Did from '@kiltprotocol/did' + +export async function main(): Promise { + const apiConfig = Kilt.ConfigService.get('api') + const encodedKiltnerd123Details = await apiConfig.call.did.queryByWeb3Name('kiltnerd123') + + const { + document: { id } + } = Did.linkedInfoFromChain(encodedKiltnerd123Details) + + console.log(`My name is kiltnerd123 and this is my DID: "${id}"`) + return id +} +``` Try running the code and check the result. @@ -201,36 +205,78 @@ A **KILT DID** can expose services that allow external resources to be linked to First, retrieve the services exposed by the DID: - -{FetchEndpoints} - +```ts +import * as Kilt from '@kiltprotocol/sdk-js' +import {Did} from "@kiltprotocol/types" + +export async function main(id: Did): Promise { + const kiltnerd123DidDocument = await Kilt.DidResolver.resolve(id) + console.log(`kiltnerd123's DID Document:`) + console.log(JSON.stringify(kiltnerd123DidDocument, null, 2)) + + const endpoints = kiltnerd123DidDocument?.didDocument?.service + if (!endpoints) { + console.log('No endpoints for the DID.') + return [] + } + console.log('Endpoints:') + console.log(JSON.stringify(endpoints, null, 2)) + + return endpoints +} +``` The code should print endpoints as JSON. Next, query the endpoint to retrieve a credential: - - {FetchEndpointData} - +```ts +import axios from 'axios' + +import * as Kilt from '@kiltprotocol/sdk-js' +import { types } from '@kiltprotocol/credentials' + +export async function main( + endpoints: types.DidUrl[] +): Promise { + const { data: credential } = await axios.get( + endpoints[0].serviceEndpoint[0] + ) + console.log(`Credentials: ${JSON.stringify(credential, null, 2)}`) + return credential +} +``` Finally, verify the credential using KILT's verification system: - -{VerifyCredential} - +```ts +import * as Kilt from '@kiltprotocol/sdk-js' +import { VerifiableCredential } from '@kiltprotocol/credentials/lib/cjs/V1/types' + +export async function main(credential: VerifiableCredential): Promise { + try { + const result = await Kilt.Verifier.verifyCredential({ credential }) + console.log(JSON.stringify(result, null, 2)) + if (result.verified == false) { + throw new Error("kiltnerd123's credential is not valid.") + } else { + console.log(`kiltnerd123's credential is valid`) + } + } catch { + console.log("kiltnerd123's credential is not valid.") + } +} +``` To ensure proper cleanup, make sure to disconnect at the end of your main function: - -{Disconnect} - +```ts +import * as Kilt from '@kiltprotocol/sdk-js' + +export async function main(): Promise { + await Kilt.disconnect() +} +``` ## Running the Code @@ -253,7 +299,7 @@ node quickstart.js :::info Next steps -- If you want to explore more of KILT's features, read our [Concepts section](../../concepts/01_what_is_kilt.md). -- If you want to dive deeper into the SDK, read the next section, [the KILT Cookbook](./02_cookbook/01_dids/01_light_did_creation.md). + :::