├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ └── sdk-incompatible-with-docs.md └── workflows │ ├── deploy-docs.yml │ ├── sdk-update-test.yml │ └── test.yml ├── .gitignore ├── .nvmrc ├── .prettierrc ├── README.md ├── babel.config.js ├── code_examples └── sdk_examples │ ├── .eslintrc │ ├── .prettierrc │ ├── package.json │ ├── src │ ├── core_features │ │ ├── claiming │ │ │ ├── 01_create_ctype.ts │ │ │ ├── 02_fetch_ctype.ts │ │ │ ├── 03_request_attestation.ts │ │ │ ├── 04_create_attestation.ts │ │ │ ├── 05_create_presentation.ts │ │ │ ├── 06_verify_presentation.ts │ │ │ ├── 07_revoke_credential.ts │ │ │ ├── 08_reclaim_attestation_deposit.ts │ │ │ └── index.ts │ │ ├── did │ │ │ ├── 00_generate_did_keys.ts │ │ │ ├── 01_light_did_simple.ts │ │ │ ├── 02_light_did_complete.ts │ │ │ ├── 03_light_did_migrate.ts │ │ │ ├── 04_full_did_simple.ts │ │ │ ├── 05_full_did_complete.ts │ │ │ ├── 06_did_query.ts │ │ │ ├── 07_full_did_update.ts │ │ │ ├── 08_full_did_batch.ts │ │ │ ├── 09_full_did_tx.ts │ │ │ ├── 10_did_signature.ts │ │ │ ├── 11_full_did_delete.ts │ │ │ ├── 12_did_export.ts │ │ │ ├── 13_full_did_deposit_reclaim.ts │ │ │ └── index.ts │ │ ├── getting_started │ │ │ ├── 01_print_hello_world.ts │ │ │ ├── 02_connect_pere.ts │ │ │ ├── 02_connect_spirit.ts │ │ │ ├── 03_fetch_did.ts │ │ │ ├── 04_fetch_endpoints.ts │ │ │ ├── 05_fetch_endpoint_data.ts │ │ │ ├── 06_verify_credential.ts │ │ │ ├── 07_disconnect.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── linking │ │ │ ├── 01_eth_link.ts │ │ │ ├── 01_eth_link_metamask.ts │ │ │ ├── 01_eth_link_web3js.ts │ │ │ ├── 01_sub_link.ts │ │ │ ├── 02_sender_link.ts │ │ │ ├── 03_account_web3name_query.ts │ │ │ ├── 04_account_web3name_query_no_sdk.ts │ │ │ ├── 05_did_unlink.ts │ │ │ ├── 06_account_unlink.ts │ │ │ ├── 07_reclaim_deposit.ts │ │ │ └── index.ts │ │ ├── messaging │ │ │ ├── 01_generate_request_credential_message.ts │ │ │ ├── 02_encrypt_message.ts │ │ │ ├── 03_decrypt_message.ts │ │ │ ├── _replay_protection_01.ts │ │ │ ├── _replay_protection_02.ts │ │ │ ├── _replay_protection_03.ts │ │ │ └── index.ts │ │ ├── public_credentials │ │ │ ├── 01_create_credential.ts │ │ │ ├── 02_issue_credential.ts │ │ │ ├── 03_retrieve_credential_by_id.ts │ │ │ ├── 04_retrieve_credentials_by_subject.ts │ │ │ ├── 05_verify_credential.ts │ │ │ ├── 06_revoke_remove_credential_by_id.ts │ │ │ ├── 07_revoke_remove_credential_by_content.ts │ │ │ ├── 08_unrevoke_credential.ts │ │ │ ├── 09_reclaim_deposit.ts │ │ │ └── index.ts │ │ ├── signCallback │ │ │ ├── index.ts │ │ │ ├── useDecryptionCallback.ts │ │ │ ├── useEncryptionCallback.ts │ │ │ ├── useExtrinsicCallback.ts │ │ │ ├── useSignCallback.ts │ │ │ └── useStoreTxSignCallback.ts │ │ ├── utils │ │ │ ├── generateKeypairs.ts │ │ │ └── getExtrinsic.ts │ │ └── web3names │ │ │ ├── 01_claim.ts │ │ │ ├── 02_query_did_name.ts │ │ │ ├── 03_query_name_credentials.ts │ │ │ ├── 04_release.ts │ │ │ ├── 05_reclaim_deposit.ts │ │ │ └── index.ts │ ├── dapp │ │ ├── dapp │ │ │ ├── 01_domain_linkage_ctype.ts │ │ │ ├── 02_domain_linkage_claim.ts │ │ │ ├── 03_sign_presentation.ts │ │ │ ├── 04_attest_credential.ts │ │ │ ├── 05_format_credential.ts │ │ │ ├── 06_dapp_introduction.ts │ │ │ └── 07_session_check.ts │ │ ├── index.ts │ │ └── verifier │ │ │ ├── 01_email_ctype.ts │ │ │ ├── 02_generate_challenge.ts │ │ │ ├── 03_create_request_credential_message.ts │ │ │ ├── 04_encrypt_request_credential_message.ts │ │ │ └── 05_verify_credential_message.ts │ ├── getFunds.ts │ ├── staking │ │ ├── index.ts │ │ ├── rewards │ │ │ ├── 01_query_staking_rewards.ts │ │ │ ├── 02_claim_collator_staking_rewards.ts │ │ │ └── 03_claim_delegator_staking_rewards.ts │ │ └── utility.ts │ ├── test.ts │ └── workshop │ │ ├── attester │ │ ├── attestCredential.ts │ │ ├── ctypeSchema.ts │ │ ├── generateAccount.ts │ │ ├── generateCtype.ts │ │ ├── generateDid.ts │ │ └── generateKeypairs.ts │ │ ├── claimer │ │ ├── createClaim.ts │ │ ├── createPresentation.ts │ │ ├── generateAccount.ts │ │ ├── generateCredential.ts │ │ ├── generateKeypairs.ts │ │ └── generateLightDid.ts │ │ ├── index.ts │ │ └── verify.ts │ ├── tsconfig.json │ └── yarn.lock ├── collator ├── .env ├── auth_config.yml ├── docker-compose.yml ├── grafana │ └── provisioning │ │ ├── dashboards │ │ ├── dashboard.yml │ │ └── spiritnet.json │ │ └── datasources │ │ └── datasource.yml └── prometheus.yml ├── docs ├── concepts │ ├── 01_what_is_kilt.md │ ├── 02_did.md │ ├── 03_web3names.md │ ├── 04_asset_dids.md │ ├── 05_credentials │ │ ├── 01_overview.md │ │ ├── 02_ctypes.md │ │ ├── 03_claiming.md │ │ ├── 04_attestation.md │ │ ├── 05_verification.md │ │ ├── 06_public_credentials.md │ │ └── _category_.json │ ├── 06_distributed_trust.md │ ├── 07_dip │ │ ├── 01_overview.md │ │ ├── 02_provider.md │ │ ├── 03_consumer.md │ │ ├── 04_user_account_kilt.md │ │ ├── 05_dapp_developer.md │ │ └── _category_.json │ ├── 08_messaging.md │ ├── 09_advanced_concepts │ │ ├── 01_terms_and_quote.md │ │ ├── 02_nested_ctypes.md │ │ └── _category_.json │ └── 10_glossary.md ├── develop │ ├── 01_sdk │ │ ├── 01_quickstart.md │ │ ├── 02_cookbook │ │ │ ├── 01_dids │ │ │ │ ├── 00_generate_keys.md │ │ │ │ ├── 01_light_did_creation.md │ │ │ │ ├── 02_full_did_creation.md │ │ │ │ ├── 03_full_did_update.md │ │ │ │ ├── 04_did_query.md │ │ │ │ ├── 05_full_did_delete.md │ │ │ │ ├── 06_full_did_tx.md │ │ │ │ ├── 07_did_signature.md │ │ │ │ ├── 08_did_export.md │ │ │ │ └── _category_.json │ │ │ ├── 02_web3names │ │ │ │ ├── 01_claim.md │ │ │ │ ├── 02_credential_query.md │ │ │ │ ├── 03_release.md │ │ │ │ ├── 04_query.md │ │ │ │ └── _category_.json │ │ │ ├── 03_account_linking │ │ │ │ ├── 01_link.md │ │ │ │ ├── 02_account_name.md │ │ │ │ ├── 03_unlink.md │ │ │ │ └── _category_.json │ │ │ ├── 04_claiming │ │ │ │ ├── 01_ctype_creation.md │ │ │ │ ├── 02_attestation_request.md │ │ │ │ ├── 03_attestation_creation.md │ │ │ │ ├── 04_presentation_creation.md │ │ │ │ ├── 05_presentation_verification.md │ │ │ │ ├── 06_credential_revocation.md │ │ │ │ └── _category_.json │ │ │ ├── 05_public_credentials │ │ │ │ ├── 01_credential_issuance.md │ │ │ │ ├── 02_credential_retrieval.md │ │ │ │ ├── 03_credential_revocation.md │ │ │ │ └── _category_.json │ │ │ ├── 06_messaging │ │ │ │ ├── 01_messaging.md │ │ │ │ ├── 02_replay_protection.md │ │ │ │ └── _category_.json │ │ │ ├── 07_signCallback.md │ │ │ ├── 08_upgrading_to_v0_29 │ │ │ │ ├── 01_backward_compatibility.md │ │ │ │ ├── _category_.json │ │ │ │ └── index.md │ │ │ └── _category_.json │ │ ├── 03_chain_setup │ │ │ ├── 01_standalone_setup.md │ │ │ ├── 02_peregrine_setup.md │ │ │ ├── 03_prod_chain_setup.md │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── 04_integrate │ │ │ ├── 01_nodejs.md │ │ │ ├── 02_browser.md │ │ │ ├── 03_distillery.md │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── 05_troubleshoot.md │ │ └── _category_.json │ ├── 02_chain │ │ ├── 01_introduction.md │ │ ├── 02_pallets │ │ │ ├── 01_did.md │ │ │ └── _category_.json │ │ ├── 03_deployments.md │ │ ├── 04_fullnode.md │ │ └── _category_.json │ ├── 03_workshop │ │ ├── 01_welcome.md │ │ ├── 02_setup.md │ │ ├── 03_overview.md │ │ ├── 04_attester │ │ │ ├── 01_account.md │ │ │ ├── 02_did.md │ │ │ ├── 03_ctype.md │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── 05_claimer │ │ │ ├── 01_did.md │ │ │ ├── 02_request.md │ │ │ ├── _category_.json │ │ │ └── index.md │ │ ├── 06_attestation.md │ │ ├── 07_verification.md │ │ ├── 08_done.md │ │ └── _category_.json │ ├── 04_specifications.md │ ├── 05_builtonkilt.md │ ├── 06_contribute.md │ ├── 07_dApp │ │ ├── 01_welcome.md │ │ ├── 02_well-known-did-config.md │ │ ├── 03_session.md │ │ ├── 04_verifier.md │ │ └── _category_.json │ ├── 08_opendid │ │ ├── 01_overview.md │ │ ├── 02_opendid_flow.md │ │ ├── 03_opendid_service.md │ │ ├── 04_integrate_opendid.md │ │ ├── 05_demo_project.md │ │ ├── 06_advanced.md │ │ └── _category_.json │ ├── 09_polarpath │ │ ├── 01_overview.md │ │ ├── 02_switch_pallet.md │ │ └── _category_.json │ └── _category_.json └── participate │ ├── 01_staking │ ├── 01_become_a_collator │ │ ├── 01_overview.md │ │ ├── 02_hardware_requirements.md │ │ ├── 03_setup_node.md │ │ ├── 04_session_keys.md │ │ ├── 05_join_collators.md │ │ ├── _03_start_node_binary.mdx │ │ ├── _03_start_node_docker.mdx │ │ └── _category_.json │ ├── 02_advanced_collator_section │ │ ├── 01_adjust_stake.md │ │ ├── 02_exit.md │ │ ├── 03_collator_lifecycle.md │ │ ├── 04_monitoring.md │ │ ├── 05_bootnodes.md │ │ ├── 06_benchmarking.md │ │ └── _category_.json │ ├── 03_delegate │ │ ├── 01_overview.md │ │ ├── 02_become.md │ │ ├── 03_adjust_stake.md │ │ ├── 04_exit.md │ │ ├── 05_delegator_lifecycle.md │ │ └── _category_.json │ ├── 04_claim_rewards.md │ ├── 05_unlock_unstaked.md │ ├── 06_troubleshooting.md │ ├── _04_claim_rewards_collator.mdx │ ├── _04_claim_rewards_delegator.mdx │ ├── _category_.json │ └── _disclaimer_staking_tx.md │ ├── 02_governance │ ├── 01_vote.md │ ├── 02_remove_vote.md │ ├── 03_unlock_coins.md │ └── _category_.json │ ├── 03_treasury_proposal.md │ ├── 04_content_creation_guidelines.md │ ├── 05_propose_tip.md │ └── _category_.json ├── docusaurus.config.js ├── markdown-link-check.config.json ├── package.json ├── scripts ├── .eslintrc ├── .prettierrc ├── out │ ├── claim.json │ ├── ctype-schema.json │ ├── ctype.json │ ├── encrypted-message.json │ └── public-credential.json ├── package.json ├── src │ ├── dids.ts │ ├── main.ts │ └── publicCredentials.ts ├── tsconfig.json └── yarn.lock ├── sidebars.js ├── src ├── components │ ├── LogoText │ │ ├── custom.module.css │ │ └── index.js │ ├── SnippetBlock │ │ └── index.js │ ├── TsJsBlock │ │ └── index.js │ └── TsJsSnippet │ │ └── index.js ├── css │ └── custom.css ├── pages │ ├── index.js │ └── styles.module.css ├── theme │ └── Admonition │ │ └── Types.js ├── utilities │ └── archive.js └── versions.js ├── static ├── .nojekyll ├── CNAME └── img │ ├── app-overview.svg │ ├── apps-dark.svg │ ├── apps-light.svg │ ├── catbox.svg │ ├── chain.jpg │ ├── chain │ ├── author-hasKey.png │ ├── author-rotateKeys.png │ ├── cast-vote.png │ ├── chain-menu.png │ ├── chain-selection.png │ ├── find-referendum-index.png │ ├── parachainStaking-batch-incrementCollatorRewards-claimRewards.png │ ├── parachainStaking-batch-incrementDelegatorRewards-claimRewards.png │ ├── parachainStaking-cancelLeaveCandidates.png │ ├── parachainStaking-candidateStakeLess.png │ ├── parachainStaking-candidateStakeMore.png │ ├── parachainStaking-claimRewards.png │ ├── parachainStaking-delegatorStakeLess.png │ ├── parachainStaking-delegatorStakeMore.png │ ├── parachainStaking-executeLeaveCandidates.png │ ├── parachainStaking-getUnclaimedStakingRewards.png │ ├── parachainStaking-incrementCollatorRewards.png │ ├── parachainStaking-incrementDelegatorRewards.png │ ├── parachainStaking-initLeaveCandidates.png │ ├── parachainStaking-joinCandidates.png │ ├── parachainStaking-joinDelegators.png │ ├── parachainStaking-leaveDelegators.png │ ├── parachainStaking-revokeDelegation.png │ ├── parachainStaking-topCandidates1.png │ ├── parachainStaking-topCandidates2.png │ ├── parachainStaking-unlockUnstaked.png │ ├── remove-vote.png │ ├── session-key-file.png │ ├── session-setKeys.png │ ├── session-validators.png │ ├── tipping-extrinsic.png │ ├── tipping-navigation.png │ ├── unlock-vote.jpg │ ├── vote-conviction.png │ └── vote-sign-sporran.png │ ├── community_dark.svg │ ├── community_light.svg │ ├── concepts │ ├── credentials │ │ ├── overview.drawio │ │ ├── overview.png │ │ ├── overview_dark.drawio │ │ └── overview_dark.png │ ├── did │ │ ├── did-lookup-dark.drawio │ │ ├── did-lookup-dark.png │ │ ├── did-lookup-light.drawio │ │ └── did-lookup-light.png │ └── distributed_trust │ │ ├── coming-soon.png │ │ ├── delegation-hierarchies-dark.svg │ │ ├── delegation-hierarchies.drawio │ │ └── delegation-hierarchies.svg │ ├── delegated-attestation.png │ ├── delegation-attestation.png │ ├── demo.jpg │ ├── expert_dark.svg │ ├── expert_dark_preview.png │ ├── expert_light.svg │ ├── faucet.jpg │ ├── favicon.ico │ ├── infrastructure.jpg │ ├── logo_dark.svg │ ├── logo_light.svg │ ├── phone_hand.jpg │ ├── showcase │ ├── didsign_dark.svg │ ├── didsign_light.svg │ ├── skyc_dark.svg │ ├── skyc_light.svg │ ├── sporran_dark.svg │ ├── sporran_light.svg │ ├── stakeboard_dark.svg │ ├── stakeboard_light.svg │ ├── w3n_dark.svg │ └── w3n_light.svg │ ├── telemetry.jpg │ ├── tools.svg │ ├── whitepaper_dark.svg │ └── whitepaper_light.svg └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style=space 5 | indent_size=4 6 | tab_width=4 7 | end_of_line=lf 8 | charset=utf-8 9 | trim_trailing_whitespace=true 10 | max_line_length=120 11 | insert_final_newline=true 12 | 13 | [*.{ts,js,jsx,tsx,json,yaml,yml}] 14 | indent_style=space 15 | indent_size=2 16 | tab_width=2 17 | 18 | [*.md] 19 | indent_style=space 20 | indent_size=4 21 | tab_width=4 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/sdk-incompatible-with-docs.md: -------------------------------------------------------------------------------- 1 | --- 2 | ## Incompatible SDK detected 3 | 4 | --- 5 | 6 | - [ ] Check if any docs needs to be updated, and if needed do so 7 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: deploy 2 | 3 | on: 4 | workflow_run: 5 | workflows: ['test-code-examples'] 6 | branches: [master] 7 | types: 8 | - completed 9 | 10 | jobs: 11 | gh-release: 12 | if: (github.event_name != 'pull_request' && github.event.workflow_run.conclusion == 'success') 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version-file: '.nvmrc' 19 | cache: 'yarn' 20 | - uses: webfactory/ssh-agent@v0.7.0 21 | with: 22 | ssh-private-key: ${{ secrets.GH_PAGES_DEPLOY }} 23 | - name: Release to GitHub Pages 24 | env: 25 | USE_SSH: true 26 | GIT_USER: git 27 | run: | 28 | git config --global user.email "actions@github.com" 29 | git config --global user.name "gh-actions" 30 | yarn install --frozen-lockfile 31 | yarn run deploy 32 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test-code-examples 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - '*' 9 | pull_request: 10 | branches: 11 | - '*' 12 | 13 | jobs: 14 | code_examples: 15 | name: Test code snippets 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | test_case: ['dapp', 'workshop', 'core'] 20 | required: ['required'] 21 | include: 22 | - test_case: 'staking' 23 | required: 'optional' 24 | 25 | continue-on-error: ${{ matrix.required == 'optional' }} 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | 30 | - name: Setup Node.js 31 | uses: actions/setup-node@v4 32 | with: 33 | node-version-file: '.nvmrc' 34 | cache: 'yarn' 35 | 36 | - name: Test style conventions 37 | working-directory: code_examples/sdk_examples 38 | run: | 39 | yarn install --frozen-lockfile 40 | yarn lint && yarn style 41 | 42 | - name: Run tests 43 | timeout-minutes: 60 44 | env: 45 | NODE_OPTIONS: --unhandled-rejections=strict 46 | BASE_MNEMONIC: ${{ secrets.BASE_MNEMONIC }} 47 | FAUCET_SEED: ${{ secrets.FAUCET_SEED }} 48 | run: | 49 | yarn install --frozen-lockfile 50 | yarn test ${{ matrix.test_case }} 51 | 52 | check-links: 53 | name: Check for broken links 54 | runs-on: ubuntu-latest 55 | 56 | steps: 57 | - uses: actions/checkout@v4 58 | 59 | - name: Setup Node.js 60 | uses: actions/setup-node@v4 61 | with: 62 | node-version-file: '.nvmrc' 63 | cache: 'yarn' 64 | 65 | - name: Install 66 | run: | 67 | yarn install --frozen-lockfile 68 | - name: Check for broken links 69 | run: | 70 | yarn check-links 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | **/node_modules 3 | .env 4 | 5 | # Production 6 | /build 7 | 8 | # Generated files 9 | .docusaurus 10 | .cache-loader 11 | **/*.zip 12 | /scripts/out 13 | 14 | # Misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .vscode 21 | .idea 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | *yalc* 28 | .yarn -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/Iron -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "semi": false, 4 | "singleQuote": true, 5 | "printWidth": 80 6 | } 7 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | } 4 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "rules": { 8 | "eol-last": "error", 9 | "max-len": [ 10 | "error", 11 | 140 12 | ], 13 | "sort-imports": [ 14 | "error", 15 | { 16 | "ignoreCase": false, 17 | "ignoreDeclarationSort": false, 18 | "ignoreMemberSort": false, 19 | "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], 20 | "allowSeparatedGroups": true 21 | } 22 | ] 23 | }, 24 | "extends": [ 25 | "eslint:recommended", 26 | "plugin:@typescript-eslint/eslint-recommended", 27 | "plugin:@typescript-eslint/recommended", 28 | "prettier" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "trailingComma": "none", 4 | "singleQuote": true, 5 | "printWidth": 80 6 | } 7 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "KILT Protocol", 3 | "name": "kilt-sdk_examples", 4 | "private": "true", 5 | "license": "MIT", 6 | "scripts": { 7 | "check-ts": "yarn tsc -p tsconfig.json --noEmit", 8 | "lint": "eslint . --ext .ts --format=codeframe", 9 | "lint:fix": "yarn lint --fix", 10 | "style": "prettier --check --config .prettierrc '**/*.ts'", 11 | "style:fix": "yarn style --write", 12 | "fix": "yarn lint:fix && yarn style:fix", 13 | "test": "ts-node src/test.ts" 14 | }, 15 | "dependencies": { 16 | "@kiltprotocol/sdk-js": "0.36.0-rc.1", 17 | "axios": "^1.5.1", 18 | "commander": "^11.1.0", 19 | "dotenv": "^16.3.1", 20 | "web3": "^4.1.2" 21 | }, 22 | "devDependencies": { 23 | "@polkadot/types": "^11.3.1", 24 | "@types/node": "^20.8.6", 25 | "@types/node-fetch": "^2.6.6", 26 | "@typescript-eslint/eslint-plugin": "^5.36.0", 27 | "@typescript-eslint/parser": "^6.8.0", 28 | "eslint": "^8.51.0", 29 | "eslint-config-prettier": "^9.0.0", 30 | "eslint-formatter-codeframe": "^7.32.1", 31 | "eslint-plugin-import": "^2.28.1", 32 | "eslint-plugin-node": "^11.1.0", 33 | "eslint-plugin-prettier": "^5.0.1", 34 | "node-fetch": "^2.6.7", 35 | "prettier": "^3.0.3", 36 | "ts-node": "^10.9.1", 37 | "typescript": "^5.2.2" 38 | }, 39 | "resolutions": { 40 | "@kiltprotocol/type-definitions": "1.11501.0-peregrine", 41 | "@kiltprotocol/augment-api": "1.11501.0-peregrine" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/01_create_ctype.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function createDriversLicenseCType( 4 | creator: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback 7 | ): Promise { 8 | const api = Kilt.ConfigService.get('api') 9 | 10 | // Create a new CType definition. 11 | const ctype = Kilt.CType.fromProperties(`Drivers License by ${creator}`, { 12 | name: { 13 | type: 'string' 14 | }, 15 | age: { 16 | type: 'integer' 17 | }, 18 | id: { 19 | type: 'string' 20 | } 21 | }) 22 | 23 | // Generate a creation tx. 24 | const encodedCtype = Kilt.CType.toChain(ctype) 25 | const ctypeCreationTx = api.tx.ctype.add(encodedCtype) 26 | // Sign it with the right DID key. 27 | const authorizedCtypeCreationTx = await Kilt.Did.authorizeTx( 28 | creator, 29 | ctypeCreationTx, 30 | signCallback, 31 | submitterAccount.address 32 | ) 33 | // Submit the creation tx to the KILT blockchain 34 | // using the KILT account specified in the creation operation. 35 | await Kilt.Blockchain.signAndSubmitTx( 36 | authorizedCtypeCreationTx, 37 | submitterAccount 38 | ) 39 | 40 | return ctype 41 | } 42 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/02_fetch_ctype.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function fetchCType( 4 | ctypeId: Kilt.ICType['$id'] 5 | ): Promise { 6 | // Example CType ID: kilt:ctype:0x329a2a5861ea63c250763e5e4c4d4a18fe4470a31e541365c7fb831e5432b940 7 | return Kilt.CType.fetchFromChain(ctypeId) 8 | } 9 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/03_request_attestation.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function requestAttestation( 4 | claimer: Kilt.DidDocument, 5 | ctype: Kilt.ICType 6 | ): Kilt.ICredential { 7 | // The claimer generates the claim they would like to get attested. 8 | const claim = Kilt.Claim.fromCTypeAndClaimContents( 9 | ctype, 10 | { 11 | name: 'Alice', 12 | age: 29, 13 | id: '123456789987654321' 14 | }, 15 | claimer.uri 16 | ) 17 | 18 | const credential = Kilt.Credential.fromClaim(claim) 19 | return credential 20 | } 21 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/04_create_attestation.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function createAttestation( 4 | attester: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback, 7 | credential: Kilt.ICredential 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | // Create an attestation object and write its root hash on the chain 12 | // using the provided attester's full DID. 13 | const { cTypeHash, claimHash, delegationId } = 14 | Kilt.Attestation.fromCredentialAndDid(credential, attester) 15 | 16 | // Write the attestation info on the chain. 17 | const attestationTx = api.tx.attestation.add( 18 | claimHash, 19 | cTypeHash, 20 | delegationId 21 | ) 22 | const authorizedAttestationTx = await Kilt.Did.authorizeTx( 23 | attester, 24 | attestationTx, 25 | signCallback, 26 | submitterAccount.address 27 | ) 28 | await Kilt.Blockchain.signAndSubmitTx( 29 | authorizedAttestationTx, 30 | submitterAccount 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/05_create_presentation.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function createPresentation( 4 | credential: Kilt.ICredential, 5 | signCallback: Kilt.SignCallback, 6 | selectedAttributes?: string[], 7 | challenge?: string 8 | ): Promise { 9 | // Create a presentation with only the specified fields revealed, if specified. 10 | return Kilt.Credential.createPresentation({ 11 | credential, 12 | signCallback, 13 | selectedAttributes, 14 | challenge 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/06_verify_presentation.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function verifyPresentation( 4 | presentation: Kilt.ICredentialPresentation, 5 | { 6 | challenge, 7 | trustedAttesterUris = [] 8 | }: { 9 | challenge?: string 10 | trustedAttesterUris?: Kilt.DidUri[] 11 | } = {} 12 | ): Promise { 13 | // Verify the presentation with the provided challenge. 14 | const { revoked, attester } = await Kilt.Credential.verifyPresentation( 15 | presentation, 16 | { challenge } 17 | ) 18 | 19 | if (revoked) { 20 | throw new Error("Credential has been revoked and hence it's not valid.") 21 | } 22 | if (!trustedAttesterUris.includes(attester)) { 23 | throw `Credential was issued by ${attester} which is not in the provided list of trusted attesters: ${trustedAttesterUris}.` 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/07_revoke_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function revokeCredential( 4 | attester: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback, 7 | credential: Kilt.ICredential, 8 | shouldRemove = false 9 | ): Promise { 10 | const api = Kilt.ConfigService.get('api') 11 | 12 | const tx = shouldRemove 13 | ? // If the attestation is to be removed, create a `remove` tx, 14 | // which revokes and removes the attestation in one go. 15 | api.tx.attestation.remove(credential.rootHash, null) 16 | : // Otherwise, simply revoke the attestation but leave it on chain. 17 | // Hence, the storage is not cleared and the deposit not returned. 18 | api.tx.attestation.revoke(credential.rootHash, null) 19 | 20 | const authorizedTx = await Kilt.Did.authorizeTx( 21 | attester, 22 | tx, 23 | signCallback, 24 | submitterAccount.address 25 | ) 26 | 27 | // Submit the right tx to the KILT blockchain. 28 | await Kilt.Blockchain.signAndSubmitTx(authorizedTx, submitterAccount) 29 | } 30 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/claiming/08_reclaim_attestation_deposit.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function reclaimAttestationDeposit( 4 | submitterAddress: Kilt.KiltKeyringPair, 5 | credential: Kilt.ICredential 6 | ): Promise { 7 | const api = Kilt.ConfigService.get('api') 8 | 9 | // Generate the tx to claim the deposit back. 10 | const depositReclaimTx = api.tx.attestation.reclaimDeposit( 11 | credential.rootHash 12 | ) 13 | 14 | // Submit the revocation tx to the KILT blockchain. 15 | await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress) 16 | } 17 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/00_generate_did_keys.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | import { mnemonicGenerate } from '@polkadot/util-crypto' 4 | 5 | export function generateKeypairs(mnemonic = mnemonicGenerate()): { 6 | authentication: Kilt.KiltKeyringPair 7 | keyAgreement: Kilt.KiltEncryptionKeypair 8 | assertionMethod: Kilt.KiltKeyringPair 9 | capabilityDelegation: Kilt.KiltKeyringPair 10 | } { 11 | const authentication = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 12 | 13 | const assertionMethod = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 14 | 15 | const capabilityDelegation = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 16 | 17 | const keyAgreement = Kilt.Utils.Crypto.makeEncryptionKeypairFromSeed( 18 | Kilt.Utils.Crypto.mnemonicToMiniSecret(mnemonic) 19 | ) 20 | 21 | return { 22 | authentication: authentication, 23 | keyAgreement: keyAgreement, 24 | assertionMethod: assertionMethod, 25 | capabilityDelegation: capabilityDelegation 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/01_light_did_simple.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function createSimpleLightDid({ 4 | authentication 5 | }: { 6 | authentication: Kilt.NewLightDidVerificationKey 7 | }): Kilt.DidDocument { 8 | // Create a light DID from the generated authentication key. 9 | const lightDID = Kilt.Did.createLightDidDocument({ 10 | authentication: [authentication] 11 | }) 12 | console.log(lightDID.uri) 13 | 14 | return lightDID 15 | } 16 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/02_light_did_complete.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function createCompleteLightDid({ 4 | authentication, 5 | keyAgreement 6 | }: { 7 | authentication: Kilt.NewLightDidVerificationKey 8 | keyAgreement: Kilt.NewDidEncryptionKey 9 | }): Kilt.DidDocument { 10 | // Example service for the DID. 11 | const service: Kilt.DidServiceEndpoint[] = [ 12 | { 13 | id: '#my-service', 14 | type: ['KiltPublishedCredentialCollectionV1'], 15 | serviceEndpoint: ['http://example.domain.org'] 16 | } 17 | ] 18 | 19 | // Create the KILT light DID with the information generated. 20 | const lightDID = Kilt.Did.createLightDidDocument({ 21 | authentication: [authentication], 22 | keyAgreement: [keyAgreement], 23 | service 24 | }) 25 | console.log(lightDID.uri) 26 | 27 | return lightDID 28 | } 29 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/03_light_did_migrate.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function migrateLightDid( 4 | lightDid: Kilt.DidDocument, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback 7 | ): Promise { 8 | const api = Kilt.ConfigService.get('api') 9 | 10 | // Generate the DID migration tx. 11 | const migrationTx = await Kilt.Did.getStoreTx( 12 | lightDid, 13 | submitterAccount.address, 14 | signCallback 15 | ) 16 | 17 | // The tx can then be submitted by the authorized account as usual. 18 | await Kilt.Blockchain.signAndSubmitTx(migrationTx, submitterAccount) 19 | 20 | // The new information is fetched from the blockchain and returned. 21 | const migratedFullDidUri = Kilt.Did.getFullDidUri(lightDid.uri) 22 | const encodedUpdatedDidDetails = await api.call.did.query( 23 | Kilt.Did.toChain(migratedFullDidUri) 24 | ) 25 | return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document 26 | } 27 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/04_full_did_simple.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function createSimpleFullDid( 4 | submitterAccount: Kilt.KiltKeyringPair, 5 | { 6 | authentication 7 | }: { 8 | authentication: Kilt.NewDidVerificationKey 9 | }, 10 | signCallback: Kilt.Did.GetStoreTxSignCallback 11 | ): Promise { 12 | const api = Kilt.ConfigService.get('api') 13 | 14 | // Generate the DID-signed creation tx and submit it to the blockchain with the specified account. 15 | // The submitter account parameter, ensures that only an entity authorized by the DID subject 16 | // can submit the tx to the KILT blockchain. 17 | const fullDidCreationTx = await Kilt.Did.getStoreTx( 18 | { 19 | authentication: [authentication] 20 | }, 21 | submitterAccount.address, 22 | signCallback 23 | ) 24 | 25 | await Kilt.Blockchain.signAndSubmitTx(fullDidCreationTx, submitterAccount) 26 | 27 | // The new information is fetched from the blockchain and returned. 28 | const fullDid = Kilt.Did.getFullDidUriFromKey(authentication) 29 | const encodedUpdatedDidDetails = await api.call.did.query( 30 | Kilt.Did.toChain(fullDid) 31 | ) 32 | return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document 33 | } 34 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/05_full_did_complete.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function createCompleteFullDid( 4 | submitterAccount: Kilt.KiltKeyringPair, 5 | { 6 | authentication, 7 | keyAgreement, 8 | assertionMethod, 9 | capabilityDelegation 10 | }: { 11 | authentication: Kilt.NewDidVerificationKey 12 | keyAgreement: Kilt.NewDidEncryptionKey 13 | assertionMethod: Kilt.NewDidVerificationKey 14 | capabilityDelegation: Kilt.NewDidVerificationKey 15 | }, 16 | signCallback: Kilt.SignExtrinsicCallback 17 | ): Promise { 18 | const api = Kilt.ConfigService.get('api') 19 | 20 | const fullDidCreationTx = await Kilt.Did.getStoreTx( 21 | { 22 | authentication: [authentication], 23 | keyAgreement: [keyAgreement], 24 | assertionMethod: [assertionMethod], 25 | capabilityDelegation: [capabilityDelegation], 26 | // Example service. 27 | service: [ 28 | { 29 | id: '#my-service', 30 | type: ['service-type'], 31 | serviceEndpoint: ['https://www.example.com'] 32 | } 33 | ] 34 | }, 35 | submitterAccount.address, 36 | signCallback 37 | ) 38 | 39 | await Kilt.Blockchain.signAndSubmitTx(fullDidCreationTx, submitterAccount) 40 | 41 | // The new information is fetched from the blockchain and returned. 42 | const fullDid = Kilt.Did.getFullDidUriFromKey(authentication) 43 | const encodedUpdatedDidDetails = await api.call.did.query( 44 | Kilt.Did.toChain(fullDid) 45 | ) 46 | return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document 47 | } 48 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/06_did_query.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function queryFullDid( 4 | didUri: Kilt.DidUri 5 | ): Promise { 6 | const { metadata, document } = await Kilt.Did.resolve(didUri) 7 | if (metadata.deactivated) { 8 | console.log(`DID ${didUri} has been deleted.`) 9 | return null 10 | } else if (document === undefined) { 11 | console.log(`DID ${didUri} does not exist.`) 12 | return null 13 | } else { 14 | return document 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/08_full_did_batch.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | // Just a helper to get an extrinsic 3 | import getExtrinsic from '../utils/getExtrinsic' 4 | 5 | export async function signAndSubmitDidExtrinsicBatch( 6 | submitterAccount: Kilt.KiltKeyringPair, 7 | fullDid: Kilt.DidUri, 8 | signCallback: Kilt.SignExtrinsicCallback 9 | ): Promise { 10 | const api = Kilt.ConfigService.get('api') 11 | 12 | // Build two extrinsics 13 | const extrinsic1 = getExtrinsic() 14 | const extrinsic2 = getExtrinsic() 15 | 16 | // Create the DID-signed batch. 17 | const authorizedBatch = await Kilt.Did.authorizeBatch({ 18 | batchFunction: api.tx.utility.batchAll, 19 | did: fullDid, 20 | extrinsics: [extrinsic1, extrinsic2], 21 | sign: signCallback, 22 | submitter: submitterAccount.address 23 | }) 24 | 25 | // Wrap the DID extrinsic in an account extrinsic. 26 | await Kilt.Blockchain.signAndSubmitTx(authorizedBatch, submitterAccount) 27 | } 28 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/09_full_did_tx.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | // Just a helper to get an extrinsic 3 | import getExtrinsic from '../utils/getExtrinsic' 4 | 5 | export async function signAndSubmitDidExtrinsic( 6 | submitterAccount: Kilt.KiltKeyringPair, 7 | fullDid: Kilt.DidUri, 8 | signCallback: Kilt.SignExtrinsicCallback 9 | ): Promise { 10 | const extrinsic = getExtrinsic() 11 | 12 | // This results in a DID-signed tx that can be signed and submitted to 13 | // the KILT blockchain by the account authorized in this operation (the `submitterAccount`). 14 | const didSignedExtrinsic = await Kilt.Did.authorizeTx( 15 | fullDid, 16 | extrinsic, 17 | signCallback, 18 | submitterAccount.address 19 | ) 20 | 21 | // Wrap the DID extrinsic in an account extrinsic. 22 | await Kilt.Blockchain.signAndSubmitTx(didSignedExtrinsic, submitterAccount) 23 | } 24 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/10_did_signature.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | type KeyLookup = (parameter: { 4 | didUri: Kilt.DidUri 5 | keyRelationship: Kilt.VerificationKeyRelationship 6 | }) => Promise<{ 7 | key: Kilt.KiltKeyringPair 8 | keyType: Kilt.VerificationKeyType 9 | keyUri: Kilt.DidResourceUri 10 | }> 11 | 12 | export async function generateAndVerifyDidAuthenticationSignature( 13 | did: Kilt.DidDocument, 14 | payload: Uint8Array, 15 | keyLookup: KeyLookup 16 | ): Promise { 17 | // How the key is looked up depends on where the key is stored (e.g. memory, hardware wallet, browser extension) 18 | const { key, keyUri } = await keyLookup({ 19 | didUri: did.uri, 20 | keyRelationship: 'authentication' 21 | }) 22 | 23 | // Generate a signature using the key that we just looked up. 24 | const signature = key.sign(payload) 25 | 26 | // Print the generated signature object. 27 | console.log('Generated signature:') 28 | console.log(Kilt.Utils.Crypto.u8aToHex(signature)) 29 | 30 | // Verify the validity of the signature using the DID's authentication public key. 31 | // It throws if the signature cannot be verified. 32 | await Kilt.Did.verifyDidSignature({ 33 | message: payload, 34 | signature, 35 | keyUri, 36 | expectedVerificationMethod: 'authentication' 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/11_full_did_delete.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function deleteFullDid( 4 | submitterAccount: Kilt.KiltKeyringPair, 5 | fullDid: Kilt.DidUri, 6 | signCallback: Kilt.SignExtrinsicCallback 7 | ): Promise { 8 | const api = Kilt.ConfigService.get('api') 9 | 10 | // Create a DID deletion tx. We specify the number of endpoints currently stored under the DID because 11 | // of the upper computation limit required by the blockchain runtime. 12 | const didIdentifier = Kilt.Did.toChain(fullDid) 13 | const endpointsCountForDid = 14 | await api.query.did.didEndpointsCount(didIdentifier) 15 | const didDeletionExtrinsic = api.tx.did.delete(endpointsCountForDid) 16 | 17 | // Sign the DID deletion tx using the DID authentication key. 18 | // This results in a DID-signed tx that can be then signed and submitted to the KILT blockchain by the account 19 | // authorized in this operation, Alice in this case. 20 | const didSignedDeletionExtrinsic = await Kilt.Did.authorizeTx( 21 | fullDid, 22 | didDeletionExtrinsic, 23 | signCallback, 24 | submitterAccount.address 25 | ) 26 | 27 | await Kilt.Blockchain.signAndSubmitTx( 28 | didSignedDeletionExtrinsic, 29 | submitterAccount 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/12_did_export.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function exportDid( 4 | did: Kilt.DidDocument, 5 | exportType: 'application/json' | 'application/ld+json' 6 | ) { 7 | const conformingDidDocument = Kilt.Did.exportToDidDocument(did, exportType) 8 | 9 | // Will print the DID URI. 10 | console.log(conformingDidDocument.id) 11 | 12 | // Will print all the public keys associated with the DID. 13 | console.log(conformingDidDocument.verificationMethod) 14 | 15 | // Will print all the assertion keys IDs. 16 | console.log(conformingDidDocument.assertionMethod) 17 | 18 | // Will print all the encryption keys IDs. 19 | console.log(conformingDidDocument.keyAgreement) 20 | 21 | // Will print all the delegation keys IDs. 22 | console.log(conformingDidDocument.capabilityDelegation) 23 | 24 | // Will print all the external services referenced inside the `DidDocument` instance. 25 | console.log(conformingDidDocument.service) 26 | 27 | return conformingDidDocument 28 | } 29 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/did/13_full_did_deposit_reclaim.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function reclaimFullDidDeposit( 4 | submitterAddress: Kilt.KiltKeyringPair, 5 | fullDid: Kilt.DidUri 6 | ): Promise { 7 | const api = Kilt.ConfigService.get('api') 8 | 9 | // Generate the tx to claim the deposit back. 10 | // It includes the DID identifier for which the deposit needs to be returned 11 | // and the count of services to provide an upper bound to the computation of the tx execution. 12 | const identifier = Kilt.Did.toChain(fullDid) 13 | const endpointsCountForDid = await api.query.did.didEndpointsCount(identifier) 14 | const depositClaimExtrinsic = api.tx.did.reclaimDeposit( 15 | identifier, 16 | endpointsCountForDid 17 | ) 18 | 19 | // The submission will fail if `submitterAddress` is not the owner of the deposit associated with the given DID identifier. 20 | await Kilt.Blockchain.signAndSubmitTx(depositClaimExtrinsic, submitterAddress) 21 | } 22 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/01_print_hello_world.ts: -------------------------------------------------------------------------------- 1 | export async function main() { 2 | console.log('Hello, world!') 3 | } 4 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/02_connect_pere.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-const */ 2 | import type { ApiPromise } from '@polkadot/api' 3 | 4 | import * as Kilt from '@kiltprotocol/sdk-js' 5 | 6 | export async function main(): Promise { 7 | let api = await Kilt.connect('wss://peregrine.kilt.io/') 8 | 9 | return api 10 | } 11 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/02_connect_spirit.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-const */ 2 | import type { ApiPromise } from '@polkadot/api' 3 | 4 | import * as Kilt from '@kiltprotocol/sdk-js' 5 | 6 | export async function main(): Promise { 7 | let api = await Kilt.connect('wss://spiritnet.kilt.io/') 8 | 9 | return api 10 | } 11 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/03_fetch_did.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable prefer-const */ 2 | import * as Kilt from '@kiltprotocol/sdk-js' 3 | 4 | export async function main(): Promise { 5 | let apiConfig = Kilt.ConfigService.get('api') 6 | const encodedKiltnerd123Details = 7 | await apiConfig.call.did.queryByWeb3Name('kiltnerd123') 8 | 9 | // This function will throw if kiltnerd123 does not exist 10 | const { 11 | document: { uri } 12 | } = Kilt.Did.linkedInfoFromChain(encodedKiltnerd123Details) 13 | console.log(`My name is kiltnerd123 and this is my DID: "${uri}"`) 14 | 15 | return uri 16 | } 17 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/04_fetch_endpoints.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main( 4 | uri: Kilt.DidUri 5 | ): Promise { 6 | const kiltnerd123DidDocument = await Kilt.Did.resolve(uri) 7 | console.log(`kiltnerd123's DID Document:`) 8 | console.log(JSON.stringify(kiltnerd123DidDocument, null, 2)) 9 | 10 | const endpoints = kiltnerd123DidDocument?.document?.service 11 | if (!endpoints) { 12 | console.log('No endpoints for the DID.') 13 | return [] 14 | } 15 | 16 | console.log('Endpoints:') 17 | console.log(JSON.stringify(endpoints, null, 2)) 18 | 19 | return endpoints 20 | } 21 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/05_fetch_endpoint_data.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | 3 | import * as Kilt from '@kiltprotocol/sdk-js' 4 | 5 | export async function main( 6 | endpoints: Kilt.DidServiceEndpoint[] 7 | ): Promise { 8 | const { 9 | data: [{ credential }] 10 | } = await axios.get( 11 | endpoints[0].serviceEndpoint[0] 12 | ) 13 | console.log(`Credentials: ${JSON.stringify(credential, null, 2)}`) 14 | return credential 15 | } 16 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/06_verify_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main(credential: Kilt.ICredential): Promise { 4 | try { 5 | const { attester, revoked } = 6 | await Kilt.Credential.verifyCredential(credential) 7 | 8 | // Verify that the credential is not revoked. Exception caught by the catch {} block below. 9 | if (revoked) { 10 | throw new Error('The credential has been revoked, hence it is not valid.') 11 | } 12 | console.log( 13 | `kiltnerd123's credential is valid and has been attested by ${attester}!` 14 | ) 15 | } catch { 16 | console.log("kiltnerd123's credential is not valid.") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/07_disconnect.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main(): Promise { 4 | await Kilt.disconnect() 5 | } 6 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/getting_started/index.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | import { main as connectToPeregrine } from './02_connect_pere' 4 | import { main as disconnect } from './07_disconnect' 5 | import { main as fetchEndpointData } from './05_fetch_endpoint_data' 6 | import { main as fetchkiltnerd123Did } from './03_fetch_did' 7 | import { main as fetchkiltnerd123Endpoints } from './04_fetch_endpoints' 8 | import { main as printHelloWorld } from './01_print_hello_world' 9 | import { main as verifyCredential } from './06_verify_credential' 10 | 11 | async function fetchDidAndCredential() { 12 | const kiltnerd123Did = await fetchkiltnerd123Did() 13 | if (!kiltnerd123Did) 14 | throw new Error('"kiltnerd123" is not associated to any DID on Spiritnet') 15 | const endpoints = await fetchkiltnerd123Endpoints(kiltnerd123Did) 16 | if (!endpoints || !endpoints.length) 17 | throw new Error(`DID doesn't include services`) 18 | 19 | let credential: Kilt.ICredential 20 | try { 21 | // FIXME: Occasionally there is a timeout error, because the endpoint uses the official ipfs gateway. 22 | // Fix it by using a reliable endpoint. 23 | // For now simply disconnect and return (i.e., ignore this error). 24 | credential = await fetchEndpointData(endpoints) 25 | } catch (error) { 26 | console.error('Error while fetching IPFS', error) 27 | return 28 | } 29 | await verifyCredential(credential) 30 | } 31 | 32 | export async function runAll(): Promise { 33 | await printHelloWorld() 34 | 35 | await connectToPeregrine() 36 | try { 37 | await fetchDidAndCredential() 38 | } finally { 39 | await disconnect() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/01_eth_link.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function linkAccountToDid( 4 | did: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | linkedAccount: Kilt.KeyringPair & { type: 'ethereum' }, 7 | signCallback: Kilt.SignExtrinsicCallback 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | // Generate the parameters for the extrinsic that links account and DID. 12 | // This will contain the signature of the account that will be linked to the DID 13 | // and therefore signals the agreement of the account to be linked. 14 | const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs( 15 | linkedAccount.address, 16 | did, 17 | async (payload) => linkedAccount.sign(payload) 18 | ) 19 | 20 | // Afterwards we build the extrinsic using the parameters from above. 21 | const accountLinkingTx = await api.tx.didLookup.associateAccount( 22 | ...accountLinkingParameters 23 | ) 24 | 25 | // Next the DID signs the extrinsic. 26 | // This signals the agreement of the DID owner to be linked to the account. 27 | const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx( 28 | did, 29 | accountLinkingTx, 30 | signCallback, 31 | submitterAccount.address 32 | ) 33 | 34 | // finally we need to submit everything to the blockchain, so that the link gets 35 | // registered. 36 | // This account will provide the required deposit and pay the fees. 37 | await Kilt.Blockchain.signAndSubmitTx( 38 | authorizedAccountLinkingTx, 39 | submitterAccount 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/01_eth_link_metamask.ts: -------------------------------------------------------------------------------- 1 | import { hexToU8a, u8aToString } from '@polkadot/util' 2 | 3 | import * as Kilt from '@kiltprotocol/sdk-js' 4 | 5 | type MetamaskApi = { 6 | request: (_: { 7 | method: string 8 | params: [string, string, string] 9 | }) => Promise 10 | } 11 | 12 | declare global { 13 | interface Window { 14 | ethereum: MetamaskApi 15 | } 16 | } 17 | 18 | export async function linkAccountToDid( 19 | did: Kilt.DidUri, 20 | submitterAccount: Kilt.KiltKeyringPair, 21 | linkedAccountAddress: string, 22 | signCallback: Kilt.SignExtrinsicCallback 23 | ): Promise { 24 | const api = Kilt.ConfigService.get('api') 25 | 26 | const blockNo = await api.query.system.number() 27 | // the challenge will be valid for 300 blocks (~1h) 28 | const validTill = blockNo.addn(300) 29 | 30 | // We build the challenge that needs to be signed by the ethereum account 31 | const challenge = u8aToString( 32 | await Kilt.Did.getLinkingChallenge(did, validTill) 33 | ) 34 | 35 | // sign the challenge 36 | const signature = await window.ethereum.request({ 37 | method: 'personal_sign', 38 | params: [challenge, linkedAccountAddress, ''] 39 | }) 40 | 41 | // build the arguments for the extrinsic that links ethereum account and DID 42 | const accountLinkingParameters = await Kilt.Did.getLinkingArguments( 43 | linkedAccountAddress, 44 | validTill, 45 | hexToU8a(signature), 46 | 'ethereum' 47 | ) 48 | 49 | // Build the actual extrinsic 50 | const accountLinkingTx = await api.tx.didLookup.associateAccount( 51 | ...accountLinkingParameters 52 | ) 53 | const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx( 54 | did, 55 | accountLinkingTx, 56 | signCallback, 57 | submitterAccount.address 58 | ) 59 | 60 | // sign and submit the extrinsic to the blockchain 61 | await Kilt.Blockchain.signAndSubmitTx( 62 | authorizedAccountLinkingTx, 63 | submitterAccount 64 | ) 65 | } 66 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/01_eth_link_web3js.ts: -------------------------------------------------------------------------------- 1 | import { hexToU8a, u8aToString } from '@polkadot/util' 2 | import Web3 from 'web3' 3 | 4 | import * as Kilt from '@kiltprotocol/sdk-js' 5 | 6 | export async function linkAccountToDid( 7 | did: Kilt.DidUri, 8 | submitterAccount: Kilt.KiltKeyringPair, 9 | linkedAccountPrivateKey: string, 10 | linkedAccountAddress: string, 11 | signCallback: Kilt.SignExtrinsicCallback 12 | ): Promise { 13 | const api = Kilt.ConfigService.get('api') 14 | const web3 = new Web3() 15 | 16 | const blockNo = await api.query.system.number() 17 | // the challenge will be valid for 300 blocks (~1h) 18 | const validTill = blockNo.addn(300) 19 | 20 | // We build the challenge that needs to be signed by the ethereum account 21 | const challenge = u8aToString( 22 | await Kilt.Did.getLinkingChallenge(did, validTill) 23 | ) 24 | 25 | // sign the challenge 26 | const signResult = await web3.eth.accounts.sign( 27 | challenge, 28 | linkedAccountPrivateKey 29 | ) 30 | 31 | // build the arguments for the extrinsic that links ethereum account and DID 32 | const accountLinkingParameters = await Kilt.Did.getLinkingArguments( 33 | linkedAccountAddress, 34 | validTill, 35 | hexToU8a(signResult.signature), 36 | 'ethereum' 37 | ) 38 | 39 | // Build the actual extrinsic 40 | const accountLinkingTx = await api.tx.didLookup.associateAccount( 41 | ...accountLinkingParameters 42 | ) 43 | const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx( 44 | did, 45 | accountLinkingTx, 46 | signCallback, 47 | submitterAccount.address 48 | ) 49 | 50 | // sign and submit the extrinsic to the blockchain 51 | await Kilt.Blockchain.signAndSubmitTx( 52 | authorizedAccountLinkingTx, 53 | submitterAccount 54 | ) 55 | } 56 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/01_sub_link.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function linkAccountToDid( 4 | did: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | linkedAccount: Kilt.KeyringPair & { type: 'ed25519' | 'sr25519' | 'ecdsa' }, 7 | signCallback: Kilt.SignExtrinsicCallback 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | // Generate the parameters for the extrinsic that links account and DID. 12 | // This will contain the signature of the account that will be linked to the DID 13 | // and therefore signals the agreement of the account to be linked. 14 | const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs( 15 | linkedAccount.address, 16 | did, 17 | async (payload) => linkedAccount.sign(payload) 18 | ) 19 | 20 | // Afterwards we build the extrinsic using the parameters from above. 21 | const accountLinkingTx = await api.tx.didLookup.associateAccount( 22 | ...accountLinkingParameters 23 | ) 24 | 25 | // Next the DID signs the extrinsic. 26 | // This signals the agreement of the DID owner to be linked to the account. 27 | const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx( 28 | did, 29 | accountLinkingTx, 30 | signCallback, 31 | submitterAccount.address 32 | ) 33 | 34 | // finally we need to submit everything to the blockchain, so that the link gets 35 | // registered. 36 | // This account will provide the required deposit and pay the fees. 37 | await Kilt.Blockchain.signAndSubmitTx( 38 | authorizedAccountLinkingTx, 39 | submitterAccount 40 | ) 41 | } 42 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/02_sender_link.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function linkDidToAccount( 4 | did: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback 7 | ): Promise { 8 | const api = Kilt.ConfigService.get('api') 9 | 10 | // Authorizing the tx with the full DID and submitting it with the provided account 11 | // results in the submitter's account being linked to the DID authorizing the operation. 12 | const accountLinkingTx = api.tx.didLookup.associateSender() 13 | const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx( 14 | did, 15 | accountLinkingTx, 16 | signCallback, 17 | submitterAccount.address 18 | ) 19 | 20 | await Kilt.Blockchain.signAndSubmitTx( 21 | authorizedAccountLinkingTx, 22 | submitterAccount 23 | ) 24 | } 25 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/03_account_web3name_query.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function queryAccountWeb3Name( 4 | lookupAccountAddress: Kilt.KiltAddress 5 | ): Promise { 6 | const api = Kilt.ConfigService.get('api') 7 | 8 | const encodedLinkedDetails = await api.call.did.queryByAccount( 9 | Kilt.Did.accountToChain(lookupAccountAddress) 10 | ) 11 | const { web3Name } = Kilt.Did.linkedInfoFromChain(encodedLinkedDetails) 12 | if (web3Name) { 13 | console.log( 14 | `web3name for account "${lookupAccountAddress}" -> "${web3Name}"` 15 | ) 16 | } else { 17 | console.log( 18 | `Account "${lookupAccountAddress}" does not have a linked web3name.` 19 | ) 20 | } 21 | 22 | return web3Name 23 | } 24 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/04_account_web3name_query_no_sdk.ts: -------------------------------------------------------------------------------- 1 | import type { KeyringPair } from '@polkadot/keyring/types' 2 | 3 | import { ApiPromise, WsProvider } from '@polkadot/api' 4 | 5 | // Import needed to provide KILT Typescript support to the api object. 6 | import '@kiltprotocol/augment-api' 7 | import { typesBundle } from '@kiltprotocol/type-definitions' 8 | 9 | export async function queryAccountWeb3Name( 10 | endpoint: string, 11 | lookupAccountAddress: KeyringPair['address'] 12 | ): Promise { 13 | const api = await ApiPromise.create({ 14 | provider: new WsProvider(endpoint), 15 | typesBundle 16 | }) 17 | // Call to the KILT runtime API `did.queryByAccount` 18 | const didDetails = await api.call.did.queryByAccount({ 19 | AccountId32: lookupAccountAddress 20 | }) 21 | if (didDetails.isNone) { 22 | throw new Error(`No DID for the KILT account "${lookupAccountAddress}".`) 23 | } 24 | 25 | const { w3n } = didDetails.unwrap() 26 | if (w3n.isNone) { 27 | throw new Error( 28 | `No web3name for the KILT account "${lookupAccountAddress}".` 29 | ) 30 | } 31 | 32 | const web3Name = w3n.unwrap().toHuman() 33 | console.log( 34 | `The provided account is identifiable by the following web3name: "w3n:${web3Name}"` 35 | ) 36 | 37 | return web3Name 38 | } 39 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/05_did_unlink.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function unlinkAccountFromDid( 4 | did: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | linkedAccountAddress: Kilt.KiltAddress, 7 | signCallback: Kilt.SignExtrinsicCallback 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | // The DID owner removes the link between itself and the specified account. 12 | const accountUnlinkTx = api.tx.didLookup.removeAccountAssociation({ 13 | AccountId32: linkedAccountAddress 14 | }) 15 | const authorizedAccountUnlinkTx = await Kilt.Did.authorizeTx( 16 | did, 17 | accountUnlinkTx, 18 | signCallback, 19 | submitterAccount.address 20 | ) 21 | 22 | await Kilt.Blockchain.signAndSubmitTx( 23 | authorizedAccountUnlinkTx, 24 | submitterAccount 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/06_account_unlink.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function unlinkDidFromAccount( 4 | linkOwnerAccount: Kilt.KeyringPair 5 | ): Promise { 6 | const api = Kilt.ConfigService.get('api') 7 | 8 | // The tx does not need to be authorized by a DID, but the submitter account removes its own link. 9 | const accountUnlinkTx = api.tx.didLookup.removeSenderAssociation() 10 | 11 | await Kilt.Blockchain.signAndSubmitTx(accountUnlinkTx, linkOwnerAccount) 12 | } 13 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/linking/07_reclaim_deposit.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function reclaimLinkDeposit( 4 | submitterAddress: Kilt.KeyringPair, 5 | linkedAccountAddress: Kilt.KiltAddress 6 | ): Promise { 7 | const api = Kilt.ConfigService.get('api') 8 | 9 | // The tx does not need to be authorized by a DID, but the deposit payer's account claims the deposit and removes the link. 10 | const accountUnlinkTx = api.tx.didLookup.reclaimDeposit({ 11 | AccountId32: linkedAccountAddress 12 | }) 13 | 14 | await Kilt.Blockchain.signAndSubmitTx(accountUnlinkTx, submitterAddress) 15 | } 16 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/messaging/01_generate_request_credential_message.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function generateRequestCredentialMessage( 4 | senderUri: Kilt.DidUri, 5 | receiverUri: Kilt.DidUri, 6 | cTypeHash: Kilt.CTypeHash 7 | ) { 8 | // Creating a challenge to submit to the receiver 9 | const challenge = Kilt.Utils.UUID.generate() 10 | 11 | // Sender uri is checked if it is a valid URI 12 | Kilt.Did.validateUri(senderUri) 13 | // Receiver uri is checked if it is a valid URI 14 | Kilt.Did.validateUri(receiverUri) 15 | 16 | // The content of the 'request-credential' message 17 | // It includes a CType that is being requested, this can be for attestation or verification 18 | // The sender is the trusted attester in the scenario 19 | const requestCredentialContent = { 20 | cTypeHash: cTypeHash, 21 | trustedAttesters: [senderUri] 22 | } 23 | 24 | const messageBody: Kilt.IRequestCredential = { 25 | type: 'request-credential', 26 | content: { cTypes: [requestCredentialContent], challenge: challenge } 27 | } 28 | 29 | // The message will throw an Error if invalid 30 | const message = Kilt.Message.fromBody(messageBody, senderUri, receiverUri) 31 | 32 | console.log(`Generated message: ${JSON.stringify(message, null, 4)}`) 33 | 34 | return message 35 | } 36 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/messaging/02_encrypt_message.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | import { useEncryptionCallback } from '../signCallback/useEncryptionCallback' 3 | 4 | export async function encryptMessage( 5 | message: Kilt.IMessage, 6 | senderUri: Kilt.DidUri, 7 | receiverUri: Kilt.DidUri, 8 | keyAgreement: Kilt.KiltEncryptionKeypair 9 | ): Promise { 10 | const { document: senderDocument } = await Kilt.Did.resolve(senderUri) 11 | 12 | const { document: receiverDocument } = await Kilt.Did.resolve(receiverUri) 13 | 14 | const receiverKeyAgreementUri = 15 | `${receiverUri}${receiverDocument.keyAgreement?.[0].id}` as Kilt.DidResourceUri 16 | const senderKeyAgreeementUri = 17 | `${senderUri}${senderDocument.keyAgreement?.[0].id}` as Kilt.DidResourceUri 18 | // encrypt the message 19 | const encryptedMessage = await Kilt.Message.encrypt( 20 | message, 21 | useEncryptionCallback({ 22 | keyAgreement, 23 | keyAgreementUri: senderKeyAgreeementUri 24 | }), 25 | receiverKeyAgreementUri 26 | ) 27 | 28 | console.log(`Encrypted Message: ${JSON.stringify(encryptedMessage, null, 4)}`) 29 | 30 | return encryptedMessage 31 | } 32 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/messaging/03_decrypt_message.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | import { useDecryptionCallback } from '../signCallback/useDecryptionCallback' 3 | 4 | export async function decryptMessage( 5 | encryptedMessage: Kilt.IEncryptedMessage, 6 | keyAgreement: Kilt.KiltEncryptionKeypair 7 | ): Promise { 8 | // Decrypting the message to retrieve the content 9 | const decryptedMessage = await Kilt.Message.decrypt( 10 | encryptedMessage, 11 | useDecryptionCallback(keyAgreement) 12 | ) 13 | 14 | // Verifying this is a properly-formatted message 15 | Kilt.Message.verify(decryptedMessage) 16 | 17 | console.log(`Decrypted Message: ${JSON.stringify(decryptedMessage, null, 4)}`) 18 | 19 | // Checking if the message type matches the expected checks 20 | if (decryptedMessage.body.type !== 'request-credential') { 21 | throw new Error('Not the correct body type') 22 | } 23 | 24 | // Destructing the message to receive the cTypes array to see what credentials 25 | // Are valid for the given request 26 | const { cTypes } = decryptedMessage.body.content 27 | 28 | const { cTypeHash, trustedAttesters } = cTypes[0] 29 | 30 | // The receiver can check if they have a valid credential that matches the cTypeHash 31 | console.log('The sent cType hash :', cTypeHash) 32 | 33 | // The trusted attesters is an array that includes the list of trusted entities 34 | // The receiver can check if they have a given credential from the trusted list 35 | console.log(`A list of trusted attesters DID :${trustedAttesters}`) 36 | 37 | return decryptedMessage 38 | } 39 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/messaging/_replay_protection_01.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | export function main() { 3 | const MAX_ACCEPTED_AGE = 60_000 // ms -> 1 minute 4 | const MIN_ACCEPTED_AGE = -1_000 // allow for some imprecision in system time 5 | const submissions = new Map() 6 | } 7 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/messaging/_replay_protection_02.ts: -------------------------------------------------------------------------------- 1 | import { blake2AsHex } from '@polkadot/util-crypto' 2 | 3 | import * as Kilt from '@kiltprotocol/sdk-js' 4 | 5 | export function main( 6 | submissions: Map, 7 | decrypted: Kilt.IMessage, 8 | MIN_ACCEPTED_AGE: number, 9 | MAX_ACCEPTED_AGE: number 10 | ) { 11 | // Is messageId fresh and createdAt recent? 12 | const messageId = 13 | decrypted.messageId || blake2AsHex(JSON.stringify(decrypted)) 14 | if ( 15 | submissions.has(messageId) || 16 | decrypted.createdAt < Date.now() - MAX_ACCEPTED_AGE || 17 | decrypted.createdAt > Date.now() - MIN_ACCEPTED_AGE 18 | ) { 19 | // no -> reject message 20 | } else { 21 | submissions.set(messageId, decrypted.createdAt) 22 | // yes -> accept & process message 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/messaging/_replay_protection_03.ts: -------------------------------------------------------------------------------- 1 | export function main( 2 | submissions: Map, 3 | MAX_ACCEPTED_AGE: number 4 | ) { 5 | setInterval(() => { 6 | const outdatedTimestamp = Date.now() - MAX_ACCEPTED_AGE 7 | submissions.forEach((timestamp, hash) => { 8 | if (timestamp < outdatedTimestamp) submissions.delete(hash) 9 | }) 10 | }, 1000) 11 | } 12 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/01_create_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | // CType definition. 4 | const ctype = Kilt.CType.fromProperties(`NFT Collection Certification CType`, { 5 | name: { 6 | type: 'string' 7 | }, 8 | pieces: { 9 | type: 'integer' 10 | }, 11 | creationDate: { 12 | type: 'string' 13 | }, 14 | artistIdentity: { 15 | type: 'string' 16 | } 17 | }) 18 | 19 | export function createNftCollectionCredential( 20 | assetDid: Kilt.AssetDidUri, 21 | artistDid: Kilt.DidUri 22 | ): Kilt.IPublicCredentialInput { 23 | const claimProperties: Kilt.IClaimContents = { 24 | name: 'Awesome NFT drop', 25 | // NFT collection only has 100 pieces in total 26 | pieces: 100, 27 | // NFT collection was released on Jan 1st, 2023 28 | creationDate: new Date(2023, 0, 1).toISOString(), 29 | artistIdentity: artistDid 30 | } 31 | const fullClaim: Kilt.IAssetClaim = { 32 | contents: claimProperties, 33 | cTypeHash: Kilt.CType.idToHash(ctype.$id), 34 | subject: assetDid 35 | } 36 | 37 | return Kilt.PublicCredential.fromClaim(fullClaim) 38 | } 39 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/02_issue_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function issueCredential( 4 | attester: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback, 7 | credential: Kilt.IPublicCredentialInput 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | const credentialCreationTx = api.tx.publicCredentials.add( 12 | Kilt.PublicCredential.toChain(credential) 13 | ) 14 | 15 | // Same as for traditional KILT credentials 16 | const authorizedAttestationTx = await Kilt.Did.authorizeTx( 17 | attester, 18 | credentialCreationTx, 19 | signCallback, 20 | submitterAccount.address 21 | ) 22 | await Kilt.Blockchain.signAndSubmitTx( 23 | authorizedAttestationTx, 24 | submitterAccount 25 | ) 26 | } 27 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/03_retrieve_credential_by_id.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function fetchCredentialById( 4 | credentialId: Kilt.IPublicCredential['id'] 5 | ): Promise { 6 | return Kilt.PublicCredential.fetchCredentialFromChain(credentialId) 7 | } 8 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/04_retrieve_credentials_by_subject.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function retrieveAllAssetCredentials( 4 | assetDid: Kilt.AssetDidUri 5 | ): Promise { 6 | return Kilt.PublicCredential.fetchCredentialsFromChain(assetDid) 7 | } 8 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/05_verify_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function verifyCredential( 4 | credential: Kilt.IPublicCredential, 5 | cType?: Kilt.ICType 6 | ): Promise { 7 | await Kilt.PublicCredential.verifyCredential(credential, { cType }) 8 | } 9 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/06_revoke_remove_credential_by_id.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function revokeCredentialById( 4 | attester: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback, 7 | credentialId: Kilt.IPublicCredential['id'], 8 | shouldRemove = false 9 | ): Promise { 10 | const api = Kilt.ConfigService.get('api') 11 | 12 | const tx = shouldRemove 13 | ? api.tx.publicCredentials.remove(credentialId, null) 14 | : api.tx.publicCredentials.revoke(credentialId, null) 15 | 16 | // Same as for traditional KILT credentials 17 | const authorizedAttestationTx = await Kilt.Did.authorizeTx( 18 | attester, 19 | tx, 20 | signCallback, 21 | submitterAccount.address 22 | ) 23 | await Kilt.Blockchain.signAndSubmitTx( 24 | authorizedAttestationTx, 25 | submitterAccount 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/07_revoke_remove_credential_by_content.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function revokeCredential( 4 | attester: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback, 7 | credential: Kilt.IPublicCredentialInput, 8 | shouldRemove = false 9 | ): Promise { 10 | const api = Kilt.ConfigService.get('api') 11 | 12 | const credentialId = Kilt.PublicCredential.getIdForCredential( 13 | credential, 14 | attester 15 | ) 16 | const tx = shouldRemove 17 | ? api.tx.publicCredentials.remove(credentialId, null) 18 | : api.tx.publicCredentials.revoke(credentialId, null) 19 | 20 | // Same as for traditional KILT credentials 21 | const authorizedAttestationTx = await Kilt.Did.authorizeTx( 22 | attester, 23 | tx, 24 | signCallback, 25 | submitterAccount.address 26 | ) 27 | await Kilt.Blockchain.signAndSubmitTx( 28 | authorizedAttestationTx, 29 | submitterAccount 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/08_unrevoke_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function unrevokeCredential( 4 | attester: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback, 7 | credential: Kilt.IPublicCredentialInput 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | const credentialId = Kilt.PublicCredential.getIdForCredential( 12 | credential, 13 | attester 14 | ) 15 | const tx = api.tx.publicCredentials.unrevoke(credentialId, null) 16 | 17 | const authorizedAttestationTx = await Kilt.Did.authorizeTx( 18 | attester, 19 | tx, 20 | signCallback, 21 | submitterAccount.address 22 | ) 23 | await Kilt.Blockchain.signAndSubmitTx( 24 | authorizedAttestationTx, 25 | submitterAccount 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/public_credentials/09_reclaim_deposit.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function reclaimDeposit( 4 | submitterAddress: Kilt.KiltKeyringPair, 5 | credential: Kilt.IPublicCredential 6 | ): Promise { 7 | const api = Kilt.ConfigService.get('api') 8 | 9 | // Generate the tx to claim the deposit back. 10 | const credentialId = Kilt.PublicCredential.getIdForCredential( 11 | credential, 12 | credential.attester 13 | ) 14 | const depositReclaimTx = api.tx.publicCredentials.reclaimDeposit(credentialId) 15 | 16 | // Submit the revocation tx to the KILT blockchain. 17 | await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress) 18 | } 19 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/signCallback/useDecryptionCallback.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function useDecryptionCallback( 4 | keyAgreement: Kilt.KiltEncryptionKeypair 5 | ): Kilt.DecryptCallback { 6 | return async function decryptCallback({ 7 | data, 8 | nonce, 9 | peerPublicKey 10 | }): Promise { 11 | const decrypted = Kilt.Utils.Crypto.decryptAsymmetric( 12 | { box: data, nonce }, 13 | peerPublicKey, 14 | keyAgreement.secretKey 15 | ) 16 | 17 | if (!decrypted) { 18 | throw new Error('Failed to decrypt with given key') 19 | } 20 | 21 | return { 22 | data: decrypted 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/signCallback/useEncryptionCallback.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function useEncryptionCallback({ 4 | keyAgreement, 5 | keyAgreementUri 6 | }: { 7 | keyAgreement: Kilt.KiltEncryptionKeypair 8 | keyAgreementUri: Kilt.DidResourceUri 9 | }): Kilt.EncryptCallback { 10 | return async function encryptCallback({ 11 | data, 12 | peerPublicKey 13 | }): Promise { 14 | const { box, nonce } = Kilt.Utils.Crypto.encryptAsymmetric( 15 | data, 16 | peerPublicKey, 17 | keyAgreement.secretKey 18 | ) 19 | return { 20 | nonce, 21 | data: box, 22 | keyUri: keyAgreementUri 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/signCallback/useExtrinsicCallback.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | import * as Kilt from '@kiltprotocol/sdk-js' 3 | import { Extrinsic } from '@polkadot/types/interfaces' 4 | 5 | export async function useSignExtrinsicCallback( 6 | didUri: Kilt.DidUri, 7 | didSigningKey: Kilt.KeyringPair & { type: 'sr25519' | 'ed25519' }, 8 | extrinsic: Extrinsic, 9 | submitterAddress: Kilt.KiltAddress 10 | ) { 11 | // The SignExtrinsicCallback is a more specialized SignCallback since it doesn't 12 | // need to return the keyUri. 13 | const signCallback: Kilt.SignExtrinsicCallback = async ({ 14 | data, 15 | // The key relationship specifies which DID key must be used. 16 | keyRelationship, 17 | // The DID URI specifies which DID must be used. We already know which DID 18 | // this will be since we will use this callback just a few lines later (did === didUri). 19 | did 20 | }) => ({ 21 | signature: didSigningKey.sign(data), 22 | keyType: didSigningKey.type 23 | }) 24 | 25 | return await Kilt.Did.authorizeTx( 26 | didUri, 27 | extrinsic, 28 | signCallback, 29 | submitterAddress 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/signCallback/useSignCallback.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | import * as Kilt from '@kiltprotocol/sdk-js' 3 | 4 | export function useSignCallback( 5 | keyUri: Kilt.DidResourceUri, 6 | didSigningKey: Kilt.KeyringPair & { type: 'sr25519' | 'ed25519' } 7 | ): Kilt.SignCallback { 8 | const signCallback: Kilt.SignCallback = async ({ 9 | data, 10 | // The key relationship specifies which DID key must be used. 11 | keyRelationship, 12 | // The DID URI specifies which DID must be used. We already know which DID 13 | // this will be since we will use this callback just a few lines later (did === didUri). 14 | did 15 | }) => ({ 16 | signature: didSigningKey.sign(data), 17 | keyType: didSigningKey.type, 18 | keyUri 19 | }) 20 | 21 | return signCallback 22 | } 23 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/signCallback/useStoreTxSignCallback.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function useStoreTxSignCallback( 4 | submitterAddress: Kilt.KiltAddress 5 | ): Promise { 6 | // Here we create a new key pair for the DID that will be created later. 7 | // This step might happen in an extension or else where, depending on your application. 8 | const authenticationKey: Kilt.KiltKeyringPair = 9 | Kilt.Utils.Crypto.makeKeypairFromSeed() 10 | 11 | // This is the sign callback. We use the just created key to sign arbitrary data 12 | // and return the signature together with the key type. 13 | const getStoreTxSignCallback: Kilt.Did.GetStoreTxSignCallback = async ({ 14 | data 15 | }) => ({ 16 | signature: authenticationKey.sign(data), 17 | keyType: authenticationKey.type 18 | }) 19 | 20 | // Here we use the call back 21 | return await Kilt.Did.getStoreTx( 22 | { 23 | authentication: [authenticationKey] 24 | }, 25 | submitterAddress, 26 | getStoreTxSignCallback 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/utils/generateKeypairs.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | import { mnemonicGenerate } from '@polkadot/util-crypto' 4 | 5 | export function generateKeypairs(mnemonic = mnemonicGenerate()): { 6 | authentication: Kilt.KiltKeyringPair 7 | keyAgreement: Kilt.KiltEncryptionKeypair 8 | assertionMethod: Kilt.KiltKeyringPair 9 | capabilityDelegation: Kilt.KiltKeyringPair 10 | } { 11 | const authentication = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 12 | 13 | const assertionMethod = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 14 | 15 | const capabilityDelegation = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 16 | 17 | const keyAgreement = Kilt.Utils.Crypto.makeEncryptionKeypairFromSeed( 18 | Kilt.Utils.Crypto.mnemonicToMiniSecret(mnemonic) 19 | ) 20 | 21 | return { 22 | authentication: authentication, 23 | keyAgreement: keyAgreement, 24 | assertionMethod: assertionMethod, 25 | capabilityDelegation: capabilityDelegation 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/utils/getExtrinsic.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export default function getExtrinsic(): Kilt.SubmittableExtrinsic { 4 | const api = Kilt.ConfigService.get('api') 5 | 6 | // Random factor ensures that each created CType is unique and does not already exist on chain. 7 | const randomFactor = Kilt.Utils.UUID.generate() 8 | return api.tx.ctype.add( 9 | Kilt.CType.toChain( 10 | Kilt.CType.fromProperties(`CType ${randomFactor}`, { 11 | name: { 12 | type: 'string' 13 | }, 14 | age: { 15 | type: 'integer' 16 | } 17 | }) 18 | ) 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/web3names/01_claim.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function claimWeb3Name( 4 | did: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | name: Kilt.Did.Web3Name, 7 | signCallback: Kilt.SignExtrinsicCallback 8 | ): Promise { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | const web3NameClaimTx = api.tx.web3Names.claim(name) 12 | const authorizedWeb3NameClaimTx = await Kilt.Did.authorizeTx( 13 | did, 14 | web3NameClaimTx, 15 | signCallback, 16 | submitterAccount.address 17 | ) 18 | await Kilt.Blockchain.signAndSubmitTx( 19 | authorizedWeb3NameClaimTx, 20 | submitterAccount 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/web3names/02_query_did_name.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function queryDidDocument( 4 | web3Name: Kilt.Did.Web3Name 5 | ): Promise { 6 | const api = Kilt.ConfigService.get('api') 7 | 8 | console.log(`Querying the blockchain for the web3name "${web3Name}"`) 9 | // Query the owner of the provided web3name. 10 | const encodedWeb3NameOwner = await api.call.did.queryByWeb3Name(web3Name) 11 | 12 | // Extract the DidDocument and other linked information from the encodedWeb3NameOwner. 13 | const { document } = Kilt.Did.linkedInfoFromChain(encodedWeb3NameOwner) 14 | 15 | return document 16 | } 17 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/web3names/04_release.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function releaseWeb3Name( 4 | did: Kilt.DidUri, 5 | submitterAccount: Kilt.KiltKeyringPair, 6 | signCallback: Kilt.SignExtrinsicCallback 7 | ): Promise { 8 | const api = Kilt.ConfigService.get('api') 9 | 10 | const web3NameReleaseTx = api.tx.web3Names.releaseByOwner() 11 | const authorizedWeb3NameReleaseTx = await Kilt.Did.authorizeTx( 12 | did, 13 | web3NameReleaseTx, 14 | signCallback, 15 | submitterAccount.address 16 | ) 17 | await Kilt.Blockchain.signAndSubmitTx( 18 | authorizedWeb3NameReleaseTx, 19 | submitterAccount 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/core_features/web3names/05_reclaim_deposit.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function reclaimWeb3NameDeposit( 4 | submitterAccount: Kilt.KiltKeyringPair, 5 | web3Name: Kilt.Did.Web3Name 6 | ): Promise { 7 | const api = Kilt.ConfigService.get('api') 8 | 9 | // Release the web3name by the deposit payer. 10 | const web3NameReleaseTx = api.tx.web3Names.reclaimDeposit(web3Name) 11 | await Kilt.Blockchain.signAndSubmitTx(web3NameReleaseTx, submitterAccount) 12 | } 13 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/01_domain_linkage_ctype.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | import * as Kilt from '@kiltprotocol/sdk-js' 3 | 4 | export async function main(): Promise { 5 | const { 6 | creator, 7 | createdAt, 8 | cType: domainLinkageCType 9 | } = await Kilt.CType.fetchFromChain( 10 | 'kilt:ctype:0xb08800a574c436831a2b9fce00fd16e9df489b2b3695e88a0895d148eca0311e' 11 | ) 12 | 13 | console.log(JSON.stringify(domainLinkageCType, null, 2)) 14 | 15 | /** Prints the following definition: 16 | { 17 | "$schema": "ipfs://bafybeiah66wbkhqbqn7idkostj2iqyan2tstc4tpqt65udlhimd7hcxjyq/", 18 | "additionalProperties": false, 19 | "properties": { 20 | "id": { 21 | "type": "string" 22 | }, 23 | "origin": { 24 | "type": "string" 25 | } 26 | }, 27 | "title": "Domain Linkage Credential", 28 | "type": "object", 29 | "$id": "kilt:ctype:0xb08800a574c436831a2b9fce00fd16e9df489b2b3695e88a0895d148eca0311e" 30 | } 31 | */ 32 | return domainLinkageCType 33 | } 34 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/02_domain_linkage_claim.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function main({ 4 | domainLinkageCType, 5 | didUri 6 | }: { 7 | domainLinkageCType: Kilt.ICType 8 | didUri: Kilt.DidUri 9 | }) { 10 | const claimContents: Kilt.IClaimContents = { 11 | id: didUri, 12 | origin: 'https://example.com' 13 | } 14 | 15 | const claim = Kilt.Claim.fromCTypeAndClaimContents( 16 | domainLinkageCType, 17 | claimContents, 18 | didUri 19 | ) 20 | const domainLinkageCredential = Kilt.Credential.fromClaim(claim) 21 | 22 | return { domainLinkageCredential } 23 | } 24 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/03_sign_presentation.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main({ 4 | didUri, 5 | assertionMethodKey, 6 | domainLinkageCredential 7 | }: { 8 | didUri: Kilt.DidUri 9 | assertionMethodKey: Kilt.KiltKeyringPair 10 | domainLinkageCredential: Kilt.ICredential 11 | }) { 12 | // We need the KeyId of the AssertionMethod Key. There is only 13 | // one AssertionMethodKey and its id is stored on the blockchain. 14 | const didResolveResult = await Kilt.Did.resolve(didUri) 15 | if (typeof didResolveResult.document === 'undefined') { 16 | throw new Error('DID must be resolvable (i.e. not deleted)') 17 | } 18 | const assertionMethodKeyId = didResolveResult.document.assertionMethod[0].id 19 | 20 | const domainLinkagePresentation = await Kilt.Credential.createPresentation({ 21 | credential: domainLinkageCredential, 22 | signCallback: async ({ data }) => ({ 23 | signature: assertionMethodKey.sign(data), 24 | keyType: assertionMethodKey.type, 25 | keyUri: `${didUri}${assertionMethodKeyId}` 26 | }) 27 | }) 28 | 29 | return { domainLinkagePresentation } 30 | } 31 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/04_attest_credential.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-unused-vars */ 2 | import * as Kilt from '@kiltprotocol/sdk-js' 3 | 4 | export async function main({ 5 | didUri, 6 | dappAccount, 7 | assertionMethodKey, 8 | domainLinkageCredential 9 | }: { 10 | didUri: Kilt.DidUri 11 | dappAccount: Kilt.KiltKeyringPair 12 | assertionMethodKey: Kilt.KiltKeyringPair 13 | domainLinkageCredential: Kilt.ICredential 14 | }) { 15 | const api = Kilt.ConfigService.get('api') 16 | const { cTypeHash, claimHash } = Kilt.Attestation.fromCredentialAndDid( 17 | domainLinkageCredential, 18 | didUri 19 | ) 20 | const attestationTx = api.tx.attestation.add(claimHash, cTypeHash, null) 21 | 22 | // We authorize the call using the attestation key of the Dapps DID. 23 | const extrinsic = api.tx.did.dispatchAs(dappAccount.address, attestationTx) 24 | 25 | // Since DIDs can not hold any balance, we pay for the transaction using our blockchain account 26 | const result = await Kilt.Blockchain.signAndSubmitTx(extrinsic, dappAccount) 27 | 28 | if (result.isError) { 29 | console.log('Attestation failed') 30 | } else { 31 | console.log('Attestation successful') 32 | } 33 | return result 34 | } 35 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/05_format_credential.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main( 4 | domainLinkagePresentation: Kilt.ICredentialPresentation 5 | ) { 6 | const api = Kilt.ConfigService.get('api') 7 | 8 | const credentialSubject = { 9 | ...domainLinkagePresentation.claim.contents, 10 | rootHash: domainLinkagePresentation.rootHash 11 | } 12 | 13 | const encodedAttestationDetails = await api.query.attestation.attestations( 14 | domainLinkagePresentation.rootHash 15 | ) 16 | const issuer = Kilt.Attestation.fromChain( 17 | encodedAttestationDetails, 18 | domainLinkagePresentation.claim.cTypeHash 19 | ).owner 20 | 21 | const issuanceDate = new Date().toISOString() 22 | 23 | const claimerSignature = domainLinkagePresentation.claimerSignature 24 | if (!claimerSignature) { 25 | throw new Error('Claimer signature is required.') 26 | } 27 | 28 | const proof = { 29 | type: 'KILTSelfSigned2020', 30 | proofPurpose: 'assertionMethod', 31 | verificationMethod: claimerSignature.keyUri, 32 | signature: claimerSignature.signature, 33 | challenge: claimerSignature.challenge 34 | } 35 | 36 | const wellKnownDidconfig = { 37 | '@context': 'https://identity.foundation/.well-known/did-configuration/v1', 38 | linked_dids: [ 39 | { 40 | '@context': [ 41 | 'https://www.w3.org/2018/credentials/v1', 42 | 'https://identity.foundation/.well-known/did-configuration/v1' 43 | ], 44 | issuer, 45 | issuanceDate, 46 | type: [ 47 | 'VerifiableCredential', 48 | 'DomainLinkageCredential', 49 | 'KiltCredential2020' 50 | ], 51 | credentialSubject, 52 | proof 53 | } 54 | ] 55 | } 56 | 57 | return wellKnownDidconfig 58 | } 59 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/06_dapp_introduction.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | // `window` object: Should be used only in the following example. 4 | // Otherwise import directly from the KILT extension library. 5 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 6 | let window: { 7 | kilt: { 8 | sporran: { 9 | startSession: ( 10 | dAppName: string, 11 | dAppEncryptionKeyUri: Kilt.DidResourceUri, 12 | challenge: string 13 | ) => Promise 14 | } 15 | } 16 | } 17 | 18 | export async function main() { 19 | const api = Kilt.ConfigService.get('api') 20 | 21 | const did = 'did:kilt:4smcAoiTiCLaNrGhrAM4wZvt5cMKEGm8f3Cu9aFrpsh5EiNV' 22 | const dAppName = 'Your dApp Name' 23 | 24 | const encodedFullDid = await api.call.did.query(Kilt.Did.toChain(did)) 25 | const { document } = Kilt.Did.linkedInfoFromChain(encodedFullDid) 26 | // If there is no DID, or the DID does not have any key agreement key, return 27 | if (!document.keyAgreement || !document.keyAgreement[0]) { 28 | return 29 | } 30 | const dAppEncryptionKeyUri = 31 | `${document.uri}${document.keyAgreement[0].id}` as Kilt.DidResourceUri 32 | 33 | // Generate and store challenge on the server side for the next step. 34 | const response = await fetch('/challenge') 35 | const challenge = await response.text() 36 | 37 | const session = await window.kilt.sporran.startSession( 38 | dAppName, 39 | dAppEncryptionKeyUri, 40 | challenge 41 | ) 42 | 43 | return session 44 | } 45 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/dapp/07_session_check.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main({ 4 | session, 5 | keyAgreementKeyPair, 6 | originalChallenge 7 | }: { 8 | session: { 9 | encryptionKeyUri: Kilt.DidResourceUri 10 | encryptedChallenge: string 11 | nonce: string 12 | } 13 | keyAgreementKeyPair: Kilt.KiltEncryptionKeypair 14 | originalChallenge: `0x{string}` 15 | }) { 16 | const { encryptionKeyUri, encryptedChallenge, nonce } = session 17 | const encryptionKey = await Kilt.Did.resolveKey(encryptionKeyUri) 18 | if (!encryptionKey) { 19 | throw new Error('an encryption key is required') 20 | } 21 | 22 | const decryptedBytes = Kilt.Utils.Crypto.decryptAsymmetric( 23 | { box: encryptedChallenge, nonce }, 24 | encryptionKey.publicKey, 25 | keyAgreementKeyPair.secretKey // derived from your seed phrase 26 | ) 27 | // If it fails to decrypt, return. 28 | if (!decryptedBytes) { 29 | throw new Error('Could not decode') 30 | } 31 | 32 | const decryptedChallenge = Kilt.Utils.Crypto.u8aToHex(decryptedBytes) 33 | 34 | // Compare the decrypted challenge to the challenge you stored earlier. 35 | if (decryptedChallenge !== originalChallenge) { 36 | throw new Error('Invalid challenge') 37 | } 38 | return session 39 | } 40 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/index.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | import { main as attestCredential } from './dapp/04_attest_credential' 3 | import { createFullDid } from '../workshop/attester/generateDid' 4 | import { main as formatCredential } from './dapp/05_format_credential' 5 | import { generateAccount } from '../workshop/attester/generateAccount' 6 | import { generateKeypairs as generateAttesterKeypairs } from '../workshop/attester/generateKeypairs' 7 | import { main as getDomainLinkageCType } from './dapp/01_domain_linkage_ctype' 8 | import { main as getDomainLinkageCredential } from './dapp/02_domain_linkage_claim' 9 | import { getFunds } from '../getFunds' 10 | import { main as signPresentation } from './dapp/03_sign_presentation' 11 | 12 | export async function testDapp(account: Kilt.KeyringPair, wssAddress: string) { 13 | console.log('Running the dapp examples!') 14 | 15 | Kilt.ConfigService.set({ submitTxResolveOn: Kilt.Blockchain.IS_IN_BLOCK }) 16 | await Kilt.connect(wssAddress) 17 | 18 | // Setup attester account. 19 | const { account: dappAccount } = generateAccount() 20 | 21 | await getFunds(account, dappAccount.address, 4) 22 | 23 | // Create attester DID & ensure CType. 24 | const { fullDid: attesterDid } = await createFullDid(dappAccount) 25 | const { assertionMethod: assertionMethodKey } = generateAttesterKeypairs() 26 | 27 | const domainLinkageCType = await getDomainLinkageCType() 28 | const { domainLinkageCredential } = getDomainLinkageCredential({ 29 | domainLinkageCType, 30 | didUri: attesterDid.uri 31 | }) 32 | await attestCredential({ 33 | didUri: attesterDid.uri, 34 | dappAccount, 35 | assertionMethodKey, 36 | domainLinkageCredential 37 | }) 38 | const { domainLinkagePresentation } = await signPresentation({ 39 | didUri: attesterDid.uri, 40 | assertionMethodKey, 41 | domainLinkageCredential 42 | }) 43 | const pseudoVc = await formatCredential(domainLinkagePresentation) 44 | console.log(JSON.stringify(pseudoVc)) 45 | } 46 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/verifier/01_email_ctype.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function main() { 4 | const emailCType: Kilt.ICType = { 5 | $id: 'kilt:ctype:0xae5bc64e500eb576b7b137288cec5d532094e103be46872f1ad54641e477d9fe', 6 | $schema: 7 | 'ipfs://bafybeiah66wbkhqbqn7idkostj2iqyan2tstc4tpqt65udlhimd7hcxjyq/', 8 | title: 'Email', 9 | properties: { 10 | Email: { 11 | type: 'string' 12 | } 13 | }, 14 | type: 'object', 15 | additionalProperties: false 16 | } 17 | 18 | console.log(emailCType) 19 | } 20 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/verifier/02_generate_challenge.ts: -------------------------------------------------------------------------------- 1 | import { randomAsHex } from '@polkadot/util-crypto' 2 | 3 | // Store somewhere in the backend. 4 | export function generateRequestChallenge() { 5 | return randomAsHex(24) 6 | } 7 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/verifier/03_create_request_credential_message.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export function main({ 4 | verifierDidUri, 5 | session, 6 | requestChallenge 7 | }: { 8 | verifierDidUri: Kilt.DidUri 9 | session: { 10 | encryptionKeyUri: Kilt.DidResourceUri 11 | } 12 | requestChallenge: string 13 | }): { 14 | message: Kilt.IMessage 15 | } { 16 | // The `session` was created earlier in your frontend. Only the session DID URI is sent to your backend. 17 | const { did: claimerSessionDidUri } = Kilt.Did.parse(session.encryptionKeyUri) 18 | 19 | // The message is constructed in your backend 20 | const message = Kilt.Message.fromBody( 21 | { 22 | content: { 23 | cTypes: [ 24 | { 25 | // the hash of the email CType 26 | cTypeHash: 27 | '0x3291bb126e33b4862d421bfaa1d2f272e6cdfc4f96658988fbcffea8914bd9ac', 28 | requiredProperties: ['Email'] 29 | } 30 | ], 31 | challenge: requestChallenge 32 | }, 33 | type: 'request-credential' 34 | }, 35 | verifierDidUri, 36 | claimerSessionDidUri 37 | ) 38 | 39 | return { message } 40 | } 41 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/dapp/verifier/04_encrypt_request_credential_message.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function main({ 4 | message, 5 | verifierDidUri, 6 | verifierKeys, 7 | session 8 | }: { 9 | message: Kilt.IMessage 10 | verifierDidUri: Kilt.DidUri 11 | verifierKeys: { 12 | authentication: Kilt.KiltKeyringPair 13 | encryption: Kilt.KiltEncryptionKeypair 14 | attestation: Kilt.KiltKeyringPair 15 | delegation: Kilt.KiltKeyringPair 16 | } 17 | session: { 18 | encryptionKeyUri: Kilt.DidResourceUri 19 | send: (message: Kilt.IEncryptedMessage) => Promise 20 | } 21 | }) { 22 | const { document: verifierDidDoc } = await Kilt.Did.resolve(verifierDidUri) 23 | if (!verifierDidDoc) { 24 | throw new Error('The verifier DID must exist') 25 | } 26 | const verifierEncryptionKey = verifierDidDoc.keyAgreement?.[0] 27 | if (!verifierEncryptionKey) { 28 | throw new Error('The verifier DID must have a key agreement key') 29 | } 30 | 31 | // Create a callback that uses the DID encryption key to encrypt the message. 32 | const encryptCallback: Kilt.EncryptCallback = async ({ 33 | data, 34 | peerPublicKey 35 | }) => { 36 | const { box, nonce } = Kilt.Utils.Crypto.encryptAsymmetric( 37 | data, 38 | peerPublicKey, 39 | verifierKeys.encryption.secretKey 40 | ) 41 | return { 42 | data: box, 43 | nonce, 44 | keyUri: `${verifierDidDoc.uri}${verifierEncryptionKey.id}` 45 | } 46 | } 47 | 48 | const encryptedMessage = await Kilt.Message.encrypt( 49 | message, 50 | encryptCallback, 51 | session.encryptionKeyUri 52 | ) 53 | 54 | // Finally, send the encrypted message to the extension. 55 | // While the above code will be executed on the server, this must happen in 56 | // the frontend since it's dispatching the message to the browser extension. 57 | await session.send(encryptedMessage) 58 | } 59 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/staking/index.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | import { claimCollatorStakingRewards } from './rewards/02_claim_collator_staking_rewards' 4 | import { claimDelegatorStakingRewards } from './rewards/03_claim_delegator_staking_rewards' 5 | 6 | import { getUnclaimedStakingRewards } from './rewards/01_query_staking_rewards' 7 | 8 | // We don't expect these tests to pass yet. 9 | // We would need a collator seed and a delegator seed to test if we can claim rewards. 10 | export async function testStaking(wssAddress: string) { 11 | await Kilt.connect(wssAddress) 12 | 13 | const collator = Kilt.Utils.Crypto.makeKeypairFromUri('//Alice', 'sr25519') 14 | const delegator = Kilt.Utils.Crypto.makeKeypairFromUri('//Charlie', 'sr25519') 15 | 16 | console.log('1) Checking staking rewards') 17 | const rewards = await getUnclaimedStakingRewards(collator.address) 18 | console.log(`Done checking rewards: ${rewards}`) 19 | 20 | console.log('2) Claiming staking rewards') 21 | console.log(`2a) Claiming collator rewards for ${collator.address}`) 22 | await claimCollatorStakingRewards(collator) 23 | console.log(`2b) Claiming delegator rewards for ${delegator.address}`) 24 | await claimDelegatorStakingRewards(delegator) 25 | } 26 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/staking/rewards/01_query_staking_rewards.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | import { Balance } from '@polkadot/types/interfaces' 3 | 4 | export async function getUnclaimedStakingRewards(account: Kilt.KiltAddress) { 5 | const api = Kilt.ConfigService.get('api') 6 | 7 | const rewards = 8 | await api.call.staking.getUnclaimedStakingRewards(account) 9 | return rewards.toBigInt() 10 | } 11 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/staking/rewards/02_claim_collator_staking_rewards.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function claimCollatorStakingRewards( 4 | submitterAccount: Kilt.KeyringPair 5 | ) { 6 | const api = Kilt.ConfigService.get('api') 7 | 8 | const tx = api.tx.utility.batch([ 9 | // convert collator participation points into rewards 10 | api.tx.parachainStaking.incrementCollatorRewards(), 11 | // mint rewards for collator address 12 | api.tx.parachainStaking.claimRewards() 13 | ]) 14 | 15 | // boilerplate to sign and send tx to websocket 16 | return new Promise((resolve, reject) => 17 | tx.signAndSend(submitterAccount, ({ status, dispatchError }) => { 18 | if (status.isFinalized && !dispatchError) { 19 | onSuccess( 20 | submitterAccount.address, 21 | status.asFinalized.toString(), 22 | resolve 23 | ) 24 | } 25 | if (dispatchError) { 26 | if (dispatchError.isModule) { 27 | // for module errors, we have the section indexed, lookup 28 | const decoded = api.registry.findMetaError(dispatchError.asModule) 29 | const { docs, name, section } = decoded 30 | 31 | const error = new Error(`${section}.${name}: ${docs.join(' ')}`) 32 | onError(error, reject) 33 | } else { 34 | // Other, CannotLookup, BadOrigin, no extra info 35 | const error = new Error(dispatchError.toString()) 36 | onError(error, reject) 37 | } 38 | } 39 | }) 40 | ) 41 | } 42 | 43 | // boilerplate handlers 44 | const onSuccess = ( 45 | address: string, 46 | txHash: string, 47 | resolve: (res: string) => void 48 | ) => { 49 | console.log( 50 | `Claimed collator staking rewards for ${address} with tx hash ${txHash}` 51 | ) 52 | resolve(txHash) 53 | } 54 | const onError = (error: Error, reject: (err: Error) => void) => { 55 | console.error(`Failed to claim collator staking rewards due to ${error}`) 56 | reject(error) 57 | } 58 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/staking/rewards/03_claim_delegator_staking_rewards.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function claimDelegatorStakingRewards( 4 | submitterAccount: Kilt.KeyringPair 5 | ) { 6 | const api = Kilt.ConfigService.get('api') 7 | 8 | const tx = api.tx.utility.batch([ 9 | // convert delegator participation points into rewards 10 | api.tx.parachainStaking.incrementDelegatorRewards(), 11 | // mint rewards for delegator address 12 | api.tx.parachainStaking.claimRewards() 13 | ]) 14 | 15 | // boilerplate to sign and send tx to websocket 16 | return new Promise((resolve, reject) => 17 | tx.signAndSend(submitterAccount, ({ status, dispatchError }) => { 18 | if (status.isFinalized && !dispatchError) { 19 | onSuccess( 20 | submitterAccount.address, 21 | status.asFinalized.toString(), 22 | resolve 23 | ) 24 | } 25 | if (dispatchError) { 26 | if (dispatchError.isModule) { 27 | // for module errors, we have the section indexed, lookup 28 | const decoded = api.registry.findMetaError(dispatchError.asModule) 29 | const { docs, name, section } = decoded 30 | 31 | const error = new Error(`${section}.${name}: ${docs.join(' ')}`) 32 | onError(error, reject) 33 | } else { 34 | // Other, CannotLookup, BadOrigin, no extra info 35 | const error = new Error(dispatchError.toString()) 36 | onError(error, reject) 37 | } 38 | } 39 | }) 40 | ) 41 | } 42 | 43 | // boilerplate handlers 44 | const onSuccess = ( 45 | address: string, 46 | txHash: string, 47 | resolve: (res: string) => void 48 | ) => { 49 | console.log( 50 | `Claimed delegator staking rewards for ${address} with tx hash ${txHash}` 51 | ) 52 | resolve(txHash) 53 | } 54 | const onError = (error: Error, reject: (err: Error) => void) => { 55 | console.error(`Failed to claim delegator staking rewards due to ${error}`) 56 | reject(error) 57 | } 58 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/staking/utility.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function signAndSend( 4 | tx: Kilt.SubmittableExtrinsic, 5 | signer: Kilt.KeyringPair, 6 | onSuccess: (txHash: string) => void, 7 | onError: (error: Error) => void 8 | ) { 9 | const api = Kilt.ConfigService.get('api') 10 | 11 | return tx.signAndSend(signer, ({ status, dispatchError }) => { 12 | if (status.isFinalized && !dispatchError) { 13 | onSuccess(status.asFinalized.toString()) 14 | } 15 | if (dispatchError) { 16 | if (dispatchError.isModule) { 17 | // for module errors, we have the section indexed, lookup 18 | const decoded = api.registry.findMetaError(dispatchError.asModule) 19 | const { docs, name, section } = decoded 20 | 21 | const error = new Error(`${section}.${name}: ${docs.join(' ')}`) 22 | onError(error) 23 | } else { 24 | // Other, CannotLookup, BadOrigin, no extra info 25 | const error = new Error(dispatchError.toString()) 26 | onError(error) 27 | } 28 | } 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/attester/ctypeSchema.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | // Return CType with the properties matching a given schema. 4 | export function getCtypeSchema(): Kilt.ICType { 5 | return Kilt.CType.fromProperties('Drivers License', { 6 | name: { 7 | type: 'string' 8 | }, 9 | age: { 10 | type: 'integer' 11 | } 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/attester/generateAccount.ts: -------------------------------------------------------------------------------- 1 | import { config as envConfig } from 'dotenv' 2 | 3 | import * as Kilt from '@kiltprotocol/sdk-js' 4 | 5 | export function generateAccount( 6 | mnemonic = Kilt.Utils.Crypto.mnemonicGenerate() 7 | ): { 8 | account: Kilt.KiltKeyringPair & { type: 'ed25519' } 9 | mnemonic: string 10 | } { 11 | return { 12 | account: Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic), 13 | mnemonic 14 | } 15 | } 16 | 17 | // Don't execute if this is imported by another file. 18 | if (require.main === module) { 19 | ;(async () => { 20 | envConfig() 21 | 22 | try { 23 | await Kilt.init() 24 | 25 | const { mnemonic, account } = generateAccount() 26 | console.log('save to mnemonic and address to .env to continue!\n\n') 27 | console.log(`ATTESTER_ACCOUNT_MNEMONIC="${mnemonic}"`) 28 | console.log(`ATTESTER_ACCOUNT_ADDRESS="${account.address}"\n\n`) 29 | } catch (e) { 30 | console.log('Error while setting up attester account') 31 | throw e 32 | } 33 | })() 34 | } 35 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/attester/generateDid.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | import { config as envConfig } from 'dotenv' 3 | import { generateAccount } from './generateAccount' 4 | 5 | export async function createFullDid( 6 | creatorAccount: Kilt.KiltKeyringPair & { 7 | type: 'ed25519' | 'sr25519' | 'ecdsa' 8 | } 9 | ): Promise<{ 10 | fullDid: Kilt.DidDocument 11 | }> { 12 | const api = Kilt.ConfigService.get('api') 13 | 14 | const verificationMethod = Kilt.Did.publicKeyToChain(creatorAccount) 15 | 16 | const txs = [ 17 | api.tx.did.createFromAccount(verificationMethod), 18 | api.tx.did.dispatchAs( 19 | creatorAccount.address, 20 | api.tx.did.setAttestationKey(verificationMethod) 21 | ) 22 | ] 23 | 24 | console.log('Creating DID from account…') 25 | await Kilt.Blockchain.signAndSubmitTx( 26 | api.tx.utility.batch(txs), 27 | creatorAccount 28 | ) 29 | const didUri = Kilt.Did.getFullDidUriFromKey(creatorAccount) 30 | const encodedFullDid = await api.call.did.query(Kilt.Did.toChain(didUri)) 31 | const { document: didDocument } = Kilt.Did.linkedInfoFromChain(encodedFullDid) 32 | 33 | if (!didDocument) { 34 | throw new Error('Full DID was not successfully created.') 35 | } 36 | 37 | return { fullDid: didDocument } 38 | } 39 | 40 | // Don't execute if this is imported by another file. 41 | if (require.main === module) { 42 | ;(async () => { 43 | envConfig() 44 | 45 | try { 46 | await Kilt.connect(process.env.WSS_ADDRESS as string) 47 | 48 | // Load attester account 49 | const accountMnemonic = process.env.ATTESTER_ACCOUNT_MNEMONIC as string 50 | const { account } = generateAccount(accountMnemonic) 51 | const { fullDid } = await createFullDid(account) 52 | 53 | console.log('\nsave following to .env to continue\n') 54 | console.error(`ATTESTER_DID_URI="${fullDid.uri}"\n`) 55 | } catch (e) { 56 | console.log('Error while creating attester DID') 57 | throw e 58 | } 59 | })() 60 | } 61 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/attester/generateKeypairs.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | import { mnemonicGenerate } from '@polkadot/util-crypto' 4 | 5 | export function generateKeypairs(mnemonic = mnemonicGenerate()): { 6 | authentication: Kilt.KiltKeyringPair 7 | keyAgreement: Kilt.KiltEncryptionKeypair 8 | assertionMethod: Kilt.KiltKeyringPair 9 | capabilityDelegation: Kilt.KiltKeyringPair 10 | } { 11 | const authentication = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 12 | 13 | const assertionMethod = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 14 | 15 | const capabilityDelegation = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 16 | 17 | const keyAgreement = Kilt.Utils.Crypto.makeEncryptionKeypairFromSeed( 18 | Kilt.Utils.Crypto.mnemonicToMiniSecret(mnemonic) 19 | ) 20 | 21 | return { 22 | authentication: authentication, 23 | keyAgreement: keyAgreement, 24 | assertionMethod: assertionMethod, 25 | capabilityDelegation: capabilityDelegation 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/claimer/createClaim.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | // Create a Claim object from light DID, CType and given content. 4 | export function createClaim( 5 | lightDid: Kilt.DidUri, 6 | ctype: Kilt.ICType, 7 | content: Kilt.IClaim['contents'] 8 | ): Kilt.IClaim { 9 | const claim = Kilt.Claim.fromCTypeAndClaimContents(ctype, content, lightDid) 10 | 11 | return claim 12 | } 13 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/claimer/createPresentation.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | 3 | export async function createPresentation( 4 | credential: Kilt.ICredential, 5 | signCallback: Kilt.SignCallback, 6 | challenge?: string 7 | ): Promise { 8 | // Create the presentation from credential, DID and challenge. 9 | return Kilt.Credential.createPresentation({ 10 | credential, 11 | signCallback, 12 | challenge 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/claimer/generateAccount.ts: -------------------------------------------------------------------------------- 1 | import { mnemonicGenerate } from '@polkadot/util-crypto' 2 | 3 | import * as Kilt from '@kiltprotocol/sdk-js' 4 | 5 | export function generateAccount(mnemonic = mnemonicGenerate()): { 6 | account: Kilt.KiltKeyringPair 7 | mnemonic: string 8 | } { 9 | const keyring = new Kilt.Utils.Keyring({ 10 | ss58Format: 38, 11 | type: 'sr25519' 12 | }) 13 | return { 14 | account: keyring.addFromMnemonic(mnemonic) as Kilt.KiltKeyringPair, 15 | mnemonic 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/claimer/generateCredential.ts: -------------------------------------------------------------------------------- 1 | import { config as envConfig } from 'dotenv' 2 | 3 | import * as Kilt from '@kiltprotocol/sdk-js' 4 | 5 | import { createClaim } from './createClaim' 6 | import { generateLightDid } from './generateLightDid' 7 | import { getCtypeSchema } from '../attester/ctypeSchema' 8 | 9 | export function generateCredential( 10 | claimerDid: Kilt.DidUri, 11 | claimAttributes: Kilt.IClaim['contents'] 12 | ): Kilt.ICredential { 13 | // Create claim. 14 | const ctype = getCtypeSchema() 15 | const claim = createClaim(claimerDid, ctype, claimAttributes) 16 | 17 | // Create credential and request attestation. 18 | console.log('Claimer -> create request') 19 | return Kilt.Credential.fromClaim(claim) 20 | } 21 | 22 | // Don't execute if this is imported by another file. 23 | if (require.main === module) { 24 | ;(async () => { 25 | envConfig() 26 | 27 | try { 28 | await Kilt.init() 29 | 30 | const claimerDidMnemonic = process.env.CLAIMER_DID_MNEMONIC as string 31 | const claimerDid = generateLightDid(claimerDidMnemonic) 32 | 33 | const request = generateCredential(claimerDid.uri, { 34 | age: 28, 35 | name: 'Max Mustermann' 36 | }) 37 | console.log( 38 | '⚠️ save this to ./claimer/_credential.json for testing ⚠️\n\n' 39 | ) 40 | console.log(JSON.stringify(request, null, 2)) 41 | } catch (e) { 42 | console.log('Error while building credential') 43 | throw e 44 | } 45 | })() 46 | } 47 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/claimer/generateKeypairs.ts: -------------------------------------------------------------------------------- 1 | import * as Kilt from '@kiltprotocol/sdk-js' 2 | import { mnemonicGenerate } from '@polkadot/util-crypto' 3 | 4 | export function generateKeypairs(mnemonic = mnemonicGenerate()) { 5 | const authentication = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic) 6 | 7 | const keyAgreement = Kilt.Utils.Crypto.makeEncryptionKeypairFromSeed( 8 | Kilt.Utils.Crypto.mnemonicToMiniSecret(mnemonic) 9 | ) 10 | 11 | return { 12 | authentication: authentication, 13 | keyAgreement: keyAgreement 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/src/workshop/claimer/generateLightDid.ts: -------------------------------------------------------------------------------- 1 | import { config as envConfig } from 'dotenv' 2 | 3 | import { mnemonicGenerate } from '@polkadot/util-crypto' 4 | 5 | import * as Kilt from '@kiltprotocol/sdk-js' 6 | 7 | import { generateKeypairs } from './generateKeypairs' 8 | 9 | export function generateLightDid(mnemonic: string): Kilt.DidDocument { 10 | const { authentication, keyAgreement } = generateKeypairs(mnemonic) 11 | return Kilt.Did.createLightDidDocument({ 12 | authentication: [authentication as Kilt.NewLightDidVerificationKey], 13 | keyAgreement: [keyAgreement] 14 | }) 15 | } 16 | 17 | // Don't execute if this is imported by another file. 18 | if (require.main === module) { 19 | ;(async () => { 20 | envConfig() 21 | 22 | try { 23 | await Kilt.init() 24 | 25 | const mnemonic = mnemonicGenerate() 26 | console.log('\nsave following to .env to continue\n') 27 | console.log(`CLAIMER_DID_MNEMONIC="${mnemonic}"`) 28 | } catch (e) { 29 | console.log('Error while setting up claimer DID') 30 | throw e 31 | } 32 | })() 33 | } 34 | -------------------------------------------------------------------------------- /code_examples/sdk_examples/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "moduleResolution": "node", 5 | "skipLibCheck": true, 6 | "target": "ES2020" 7 | }, 8 | "exclude": [ 9 | "src/test.ts" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /collator/.env: -------------------------------------------------------------------------------- 1 | 2 | ADMIN_USER=admin 3 | ADMIN_PASSWORD= 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /collator/auth_config.yml: -------------------------------------------------------------------------------- 1 | basic_auth_users: 2 | prometheus: $2y$10$DkPVNPI3uXkFZfOTVDccBOw0LSycOqJ2NUZP/yFq6Y9pLQdnupexW -------------------------------------------------------------------------------- /collator/grafana/provisioning/dashboards/dashboard.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | providers: 4 | - name: 'Prometheus' 5 | orgId: 1 6 | folder: '' 7 | type: file 8 | disableDeletion: false 9 | editable: true 10 | allowUiUpdates: true 11 | options: 12 | path: /etc/grafana/provisioning/dashboards -------------------------------------------------------------------------------- /collator/grafana/provisioning/datasources/datasource.yml: -------------------------------------------------------------------------------- 1 | apiVersion: 1 2 | 3 | datasources: 4 | - name: Prometheus 5 | type: prometheus 6 | access: proxy 7 | orgId: 1 8 | url: http://prometheus:9090 9 | basicAuth: true 10 | isDefault: true 11 | editable: true 12 | basicAuthUser: prometheus 13 | basicAuthPassword: Prometheus -------------------------------------------------------------------------------- /collator/prometheus.yml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | evaluation_interval: 15s 4 | 5 | # Attach these labels to any time series or alerts when communicating with 6 | # external systems (federation, remote storage, Alertmanager). 7 | external_labels: 8 | monitor: 'docker-host-alpha' 9 | 10 | # Load and evaluate rules in this file every 'evaluation_interval' seconds. 11 | rule_files: 12 | - "alert.rules" 13 | 14 | # A scrape configuration containing exactly one endpoint to scrape. 15 | scrape_configs: 16 | - job_name: 'nodeexporter' 17 | scrape_interval: 5s 18 | static_configs: 19 | - targets: ['node-exporter:9100'] 20 | - job_name: 'blockchain' 21 | scrape_interval: 5s 22 | static_configs: 23 | - targets: ['collator:9615'] -------------------------------------------------------------------------------- /docs/concepts/05_credentials/01_overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: overview 3 | title: Overview 4 | --- 5 | 6 | import ThemedImage from '@theme/ThemedImage'; 7 | 8 | **Credentials** consist of a set of claims which belong to a **Claimer**, are attested by an **Attester**, and that a **Verifier** can verify. 9 | 10 |
11 | 18 |
19 | 20 | To get a credential, a Claimer needs to take the following steps: 21 | 22 | 1. Find a **CType** to base a claim on. Potential Attesters and Verifiers might advertise this information themselves. 23 | 2. Make a **claim** containing a set of properties about themselves. 24 | 3. Fulfil any requirement from your Attester. For example, accepting their **Terms** and paying a **Quote**. 25 | 4. **Request an attestation** from the Attester. 26 | 5. Wait for the Attester to **attest** claims. 27 | 28 | Once attested, the wrapped claims are considered to be a valid credential. 29 | 30 | To use a Credential, the Claimer can generate a Credential-Presentation for a Verifier. 31 | The verification would follow this process: 32 | 33 | 1. The Verifier may request a **Credential** of a CType, along with with properties to reveal. 34 | He would also provide a **challenge** to ensure the presentations are not recycled. 35 | 2. The Claimer selectively **discloses** the requested properties and signs them along with the challenge to generate a presentation. 36 | 3. The Verifier **verify** the presentation structure, content and signature, and decides whether they trust the Attester of the presented credential. 37 | 38 | The next sections describe each step in more detail. 39 | 40 | :::info 41 | 42 | To learn about how to implement the flow above in a dapp that interacts with a browser extension, read the [Credential API specification](https://github.com/KILTprotocol/spec-ext-credential-api). 43 | 44 | ::: 45 | -------------------------------------------------------------------------------- /docs/concepts/05_credentials/04_attestation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: attestation 3 | title: Attestations 4 | --- 5 | 6 | KILT uses the terms Attestation and Credential interchangeably, but their meaning is different. 7 | A _Credential_ includes the original claimer's data and all the information linked to it, while an _Attestation_ only refers to the on-chain proof that a given credential has been attested. 8 | 9 | To write an attestation on the KILT blockchain, the Attester checks the validity of the received to-be-attested `Credential` data, ensuring that the data inside it matches the requirements of the attestation. For example, that the user's name is indeed Alice. 10 | 11 | After that, the Attester writes the `Credential`'s root hash on the KILT blockchain, certifying that a credential with that root hash is valid. 12 | The Claimer can monitor the blockchain to listen for the event resulting from the attestation process, marking when the credential is attested and usable. 13 | 14 | After the credential has been attested, the Claimer can store it in their wallet and can now use it with Verifiers that trust credentials issued by that Attester. 15 | 16 | :::info 17 | 18 | For a detailed developer-oriented guide to KILT attestations, read the [Attestation cookbook section](../../develop/01_sdk/02_cookbook/04_claiming/03_attestation_creation.md). 19 | 20 | ::: 21 | 22 | ### Storing attestations 23 | 24 | Storing a attestation in the blockchain requires providing a constant deposit, which is currently around 0.12 KILT. The deposit amount is calculated based on the worst-case scenario for a attestation, where the maximum storage for one attestation reaches 179 bytes. 25 | The deposit serves as a security measure to ensure the integrity of the blockchain and incentivize users to manage their attestation responsibly. 26 | By requiring a deposit, it discourages spamming or unnecessary creation of attestation. 27 | The attester can reclaim the deposit by deleting their attestation. 28 | Revoking them isn't sufficient as the deposit still shows in chain storage, but marked as invalid. -------------------------------------------------------------------------------- /docs/concepts/05_credentials/06_public_credentials.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: public-credentials 3 | title: Public Credentials for Assets 4 | --- 5 | 6 | import CodeBlock from '@theme/CodeBlock'; 7 | 8 | import PublicCredential from '@site/scripts/out/public-credential.json.raw!=!raw-loader!@site/scripts/out/public-credential.json'; 9 | 10 | [AssetDIDs][asset-did-concepts] give a way to uniquely identify assets regardless of the blockchain they live on or their current owner. 11 | KILT allows owners of an on-chain DID with an assertion key (a.k.a. attesters) to issue credentials to those assets. 12 | 13 | Public credentials aren't that different in their structure from traditional KILT credentials. 14 | The main difference is that, since they're public, they don't have selective disclosure capabilities. 15 | This is because the cryptographic information required to enable this is stripped away from the credential content. 16 | 17 | 18 | {PublicCredential} 19 | 20 | 21 | :::warning Anyone can be an attester! 22 | While the owner of normal KILT credentials holds them in their wallet and decides what credential to share with who, public credentials are, as the name suggests, public by design. 23 | 24 | This means that when reading the credentials issued for a given asset, consumers should be aware of the level of trust they have towards the issuer of each credential. 25 | ::: 26 | 27 | [asset-did-concepts]: ../04_asset_dids.md -------------------------------------------------------------------------------- /docs/concepts/05_credentials/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Credentials", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/concepts/07_dip/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Decentralized Identity Protocol (DIP)", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/concepts/09_advanced_concepts/02_nested_ctypes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: nested-ctypes 3 | title: Nested CTypes 4 | --- 5 | 6 | A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them. 7 | For example, a company could use a Nested CType that includes the required credentials, qualifications, health and safety certificates, etc. of its current employees. 8 | When verifying a Nested CType, the sub-CTypes need to be available. 9 | 10 | ## Referencing 11 | 12 | JSON-schema provides a referencing keyword `$ref` that can be used as a pointer from other JSON schemas. 13 | This allows CTypes to either reference fields in other CTypes or nest entire CTypes within one another, providing flexibility for several different use cases. 14 | A claim from a Nested CType requires the given CType, a list of comprised schemas, the claim content and the address of the owner. 15 | 16 | This facility requires all JSON objects to build the schema and allows the reuse of previous schemas, reducing the need for copy-and-paste. 17 | -------------------------------------------------------------------------------- /docs/concepts/09_advanced_concepts/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Advanced Concepts", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/01_light_did_creation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: light-did-creation 3 | title: Create a Light DID 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import LightDidSimple from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/01_light_did_simple.ts'; 9 | import LightDidComplete from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/02_light_did_complete.ts'; 10 | 11 | The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption. 12 | For the sake of ease of use, the example snippets below show how to use keys generated with a `Keyring`, provided also by the `@polkadot/api` library, to generate key pairs that are kept in memory and disappear at the end of the program execution, unless saved to some persistent storage. 13 | 14 | The following is an example of how to create a light DID after creating an authentication keypair. 15 | 16 | 17 | {LightDidSimple} 18 | 19 | 20 | For cases in which an encryption key and some services also need to be added to a light DID: 21 | 22 | 23 | {LightDidComplete} 24 | 25 | 26 | :::info 27 | In KILT, light DIDs are meant to be used in one of two cases: 28 | 29 | 1. As *ephemeral, one-time identifiers* when establishing new communication channels with untrusted parties. 30 | 2. As an *entrypoint into the KILT ecosystem*, i.e., to obtain one's first credentials and get acquainted with KILT. 31 | 32 | As such, light DIDs do not support updates of any sort, but they retain the same identifier until they are upgraded to full DIDs. 33 | They are not intended for use in complex and/or high-security use cases. 34 | In those situations, a full DID should be used. 35 | Visit the [next section](./02_full_did_creation.md) to see how to create and manage full DIDs. 36 | ::: 37 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/02_full_did_creation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: full-did-creation 3 | title: Create a Full DID 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import FullDidSimple from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/04_full_did_simple.ts'; 9 | import FullDidComplete from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/05_full_did_complete.ts'; 10 | import LightDidMigrate from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/03_light_did_migrate.ts'; 11 | 12 | The following is an example of how to create and write on the blockchain a full DID that specifies only an authentication key. 13 | 14 | 15 | {FullDidSimple} 16 | 17 | 18 | If additional keys or services are to be specified, they can be passed as parameters to the creation transaction. 19 | 20 | 21 | {FullDidComplete} 22 | 23 | 24 | ## Upgrade a Light DID to a Full DID 25 | 26 | Another way to obtain a full DID is by upgrading a previously-created light DID. 27 | KILT supports this operation in a way that does not invalidate any credentials that had been issued to the light DID before being upgraded. 28 | 29 | The following code shows how to migrate a light DID to a full DID. 30 | Credentials, presentations, and verifications remain unchanged and remain valid. 31 | 32 | 33 | {LightDidMigrate} 34 | 35 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/03_full_did_update.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: full-did-update 3 | title: Update a Full DID keys and service endpoints 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import FullDidUpdate from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/07_full_did_update.ts'; 9 | 10 | Once anchored to the KILT blockchain, a full DID can be updated. 11 | For instance, the following snippet shows how to use the `authorizeBatch` function to update the authentication key, remove an old service *and* add a new one for a full DID in the same transaction. 12 | 13 | 14 | {FullDidUpdate} 15 | 16 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/04_did_query.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: did-query 3 | title: Resolve a DID 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import DidQuery from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/06_did_query.ts'; 9 | 10 | Querying the state of a DID is called **resolution**. 11 | The entity that queries the DID Document for a given DID, i.e., resolves it, is called a **resolver**. 12 | 13 | The KILT SDK provides such a resolver to use with KILT DIDs, as the snippet below shows: 14 | 15 | 16 | {DidQuery} 17 | 18 | 19 | :::note 20 | The DID resolver can resolve both light and full DIDs. 21 | For a more in-depth explanation about the KILT DID method and resolution, refer to our [specification](https://github.com/KILTprotocol/spec-kilt-did). 22 | ::: 23 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/05_full_did_delete.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: full-did-delete 3 | title: Delete a Full DID 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import FullDidDelete from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/11_full_did_delete.ts'; 9 | import FullDidDepositReclaim from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/13_full_did_deposit_reclaim.ts'; 10 | 11 | Once a DID is no longer needed, it is recommended to deactivate it by removing it from the KILT blockchain. 12 | The following snippet shows how to do it: 13 | 14 | 15 | {FullDidDelete} 16 | 17 | 18 | :::warning 19 | Please note that once deleted, a full DID becomes unusable and cannot be re-created anymore. 20 | This means that all credentials obtained with that DID are no longer valid and must be obtained with a different DID if needed. 21 | ::: 22 | 23 | ## Claim back a DID deposit 24 | 25 | 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: 26 | 27 | 28 | {FullDidDepositReclaim} 29 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/07_did_signature.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: did-signature 3 | title: Generate and Verify a DID Signature 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import DidSignature from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/10_did_signature.ts'; 9 | 10 | In addition to being used to authorize chain operations, both light and full DIDs have off-chain applications. 11 | 12 | One such applications is generating digital signatures. 13 | 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. 14 | 15 | The snippet below shows how to generate and verify a DID signature using the KILT SDK. 16 | 17 | 18 | {DidSignature} 19 | 20 | 21 | :::note 22 | Notice that the snippet above takes a `DidDocument` instance to generate the signature. 23 | A `DidDocument` can represent either a light or a full DID. 24 | 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. 25 | ::: 26 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/08_did_export.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: did-export 3 | title: Exporting a KILT DID 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import DidExport from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/did/12_did_export.ts'; 9 | 10 | The DID Document exporter provides the functionality needed to convert an instance of an SDK `DidDocument` object into a document that is compliant with the [W3C specification](https://www.w3.org/TR/did-core/). 11 | This component is required for the KILT plugin for the [DIF Universal Resolver](https://dev.uniresolver.io/). 12 | 13 | ## How to use the exporter 14 | 15 | The exporter interface and used types are part of the `@kiltprotocol/types` package, while the actual `DidDocumentExporter` is part of the `@kiltprotocol/did` package. 16 | Both types and DID packages are accessible via the top-level `@kiltprotocol/sdk-js` import. 17 | The following shows how to use the exporter to generate a W3C-compliant DID Document from a given `DidDocument`, which can represent either a light or a full DID. 18 | 19 | 20 | {DidExport} 21 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/01_dids/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "KILT DIDs", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/02_web3names/01_claim.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: web3name-claim 3 | title: Claim a web3name 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import Claim from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/web3names/01_claim.ts'; 9 | 10 | A web3name can be claimed if it currently has no owner, using the following snippet as reference. 11 | 12 | 13 | {Claim} 14 | 15 | 16 | The claiming process requires the reservation of a deposit that is freed upon web3name release. 17 | 18 | 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). 19 | For more information about web3names and DIDs, see the official [KILT DID Specification](https://github.com/KILTprotocol/spec-kilt-did/blob/main/README.md). 20 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/02_web3names/02_credential_query.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: credential-query 3 | title: Query Public Credentials for a web3name 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import QueryNameCredentials from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/web3names/03_query_name_credentials.ts'; 9 | 10 | web3names are linked to KILT DIDs, and KILT DIDs can define services to expose additional service/information. 11 | One of the possible endpoint types is the [`KiltPublishedCredentialCollectionV1`][kilt-published-credential-collection-v1-type] type. 12 | The type defines the structure to make KILT credentials public and accessible to anyone. 13 | 14 | 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. 15 | 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]. 16 | 17 | 18 | {QueryNameCredentials} 19 | 20 | 21 | [kilt-published-credential-collection-v1-type]: https://github.com/KILTprotocol/spec-KiltPublishedCredentialCollectionV1/blob/main/README.md 22 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/02_web3names/04_query.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: web3name-query 3 | title: Resolve a web3name 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import QueryDid from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/web3names/02_query_did_name.ts'; 9 | 10 | 11 | A web3name can be resolved in a similar manner to [how a DID is resolved](../01_dids/04_did_query.md). 12 | Resolving the web3name will provide the same information as resolving a DID does. 13 | 14 | To query and retrieve the DID document associated with a web3name, you can use the following code example: 15 | 16 | 17 | 18 | {QueryDid} 19 | 20 | 21 | In the code example above, the `queryDidDocument` function takes a web3Name parameter, which represents the web3name to be resolved. 22 | It internally uses the `api.call.did.queryByWeb3Name` method to query the information of the provided web3name from the blockchain. 23 | 24 | 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. 25 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/02_web3names/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "web3names", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/03_account_linking/02_account_name.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: account-name 3 | title: Query the web3name of an Account 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import AccountWeb3NameQuery from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/linking/03_account_web3name_query.ts'; 9 | import AccountWeb3NameQueryNoSDK from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/linking/04_account_web3name_query_no_sdk.ts'; 10 | 11 | For accounts that have been linked to DIDs that have claimed a web3name, the linking feature opens the way to a host of possibilities, e.g., showing the web3name of a collator's account on the [KILT Stakeboard][kilt-stakeboard]. 12 | 13 | This section shows how to perform the `account -> web3name` querying both with and without the support of the KILT SDK. 14 | 15 | ## Query an Account's web3name with the KILT SDK 16 | 17 | 18 | {AccountWeb3NameQuery} 19 | 20 | 21 | ## Query an Account's web3name without the KILT SDK 22 | 23 | 24 | {AccountWeb3NameQueryNoSDK} 25 | 26 | 27 | [kilt-stakeboard]: https://stakeboard.kilt.io/ 28 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/03_account_linking/03_unlink.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: account-unlink 3 | title: Unlink an Account From a KILT DID 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import DidUnlink from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/linking/05_did_unlink.ts'; 9 | import AccountUnlink from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/linking/06_account_unlink.ts'; 10 | import ReclaimDeposit from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/linking/07_reclaim_deposit.ts'; 11 | 12 | Similar to the way a new account to DID link is created, removing a link can happen in one of three ways: 13 | 14 | 1. The DID owner submits a transaction indicating which account to unlink: 15 | 16 | 17 | {DidUnlink} 18 | 19 | 20 | 2. The linked account submits a transaction indicating that the link with the DID should be removed: 21 | 22 | 23 | {AccountUnlink} 24 | 25 | 26 | 3. The deposit payer submits a transaction indicating that they want to reclaim their deposit, which in turn removes the existing link between the specified account and DID: 27 | 28 | 29 | {ReclaimDeposit} 30 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/03_account_linking/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Account <-> KILT DID Relationship", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/01_ctype_creation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: ctype-creation 3 | title: Create a CType 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import CreateCType from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/01_create_ctype.ts'; 9 | import FetchCType from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/02_fetch_ctype.ts'; 10 | 11 | Every KILT credential has to conform to a CType. 12 | A CType describes which properties a credential has and what type these properties have. 13 | CTypes must be registered on the Spiritnet blockchain. 14 | To learn more about CTypes, see the [CType concept section](../../../../concepts/05_credentials/02_ctypes.md). 15 | 16 | The creation of a CType in KILT involves two steps: the definition of a CType and the anchoring of its hash on the KILT blockchain. 17 | 18 | :::info DID required 19 | The creator of a CType is required to have a full DID with an attestation key. 20 | To see how to manage DIDs, please refer to the [DID section](../01_dids/03_full_did_update.md). 21 | ::: 22 | 23 | :::info CTypes are unique 24 | The creation of a new CType requires the CType hash to be unique. 25 | Before writing a new CType, Attesters should check whether there is already an existing CType which matches their requirements. 26 | 27 | Visit our [CType index repository](https://github.com/KILTprotocol/ctype-index) for a non-exhaustive list of existing CTypes. 28 | ::: 29 | 30 | The following snippets show how to create a CType: 31 | 32 | 33 | {CreateCType} 34 | 35 | 36 | 37 | ## Retrieve a CType from its ID 38 | 39 | CTypes can be queried directly from any KILT archive nodes. 40 | The following example shows how to query a CType using the SDK: 41 | 42 | 43 | {FetchCType} 44 | 45 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/02_attestation_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: attestation-request 3 | title: Request an Attestation 4 | --- 5 | import TsJsBlock from '@site/src/components/TsJsBlock'; 6 | 7 | import RequestAttestation from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/03_request_attestation.ts'; 8 | 9 | To obtain credentials, Claimers have to request an attestation for a set of claims from an Attester. 10 | The resulting object is a `Credential`, which can be created following the snippet below. 11 | 12 | This process does not involve any interaction with the KILT blockchain, but is simply a communication channel where the Claimer and the Attester can communicate. 13 | 14 | 15 | {RequestAttestation} 16 | 17 | 18 | :::note 19 | The structure of the claims must respect the schema defined in the specified CType. 20 | Attesters (and Verifiers) will reject claims that fail to verify correctly. 21 | ::: -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/03_attestation_creation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: attestation-creation 3 | title: Attest a Claim (Issue a Credential) 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import CreateAttestation from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/04_create_attestation.ts'; 9 | 10 | Once an Attester has received a to-be-attested `Credential` from a Claimer, they will typically verify the information in the claim. 11 | If the claims correspond to truth, the Attester will proceed by attesting the root hash of the credential on the KILT blockchain, timestamping the attestation operation. 12 | A deposit is reserved from the balance of the KILT account submitting the creation transaction, which is returned if and when the attestation is removed from the chain. 13 | 14 | :::info 15 | An Attester is required to have a full DID with an attestation key. 16 | To see how to manage DIDs, please refer to the [DID section](../01_dids/03_full_did_update.md). 17 | ::: 18 | 19 | 20 | {CreateAttestation} 21 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/04_presentation_creation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: presentation-creation 3 | title: Present a Credential 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import CreatePresentation from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/05_create_presentation.ts'; 9 | 10 | With a valid credential, Claimers can now go to Verifiers to request some service upon providing proof of validity of a certain credential. 11 | The process of presenting one or more credentials to a Verifier is called `Presentation`. 12 | 13 | This step, similar to the [attestation request](./02_attestation_request.md), requires that a communication channel exist between the Claimer and the Verifier so that information about the presentation can be shared. 14 | To verify the revocation status of the presented credential(s), a Verifier must be able to interact with a KILT full node. 15 | 16 | :::info 17 | KILT supports selective disclosure of claims when creating presentations. 18 | This means that given a credential, it is possible for the Claimer to reveal only a subset of its claims, depending on the requirements set by the Verifier. 19 | Check the snippet below to see how that is done using the KILT SDK. 20 | ::: 21 | 22 | The Claimer can generate a presentation starting from a credential, optionally specifying the fields to reveal and a presentation challenge, which is useful to prove freshness of the generated presentation. 23 | 24 | 25 | {CreatePresentation} 26 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/05_presentation_verification.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: presentation-verification 3 | title: Verify a Credential or a Presentation 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import VerifyPresentation from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/06_verify_presentation.ts'; 9 | 10 | Whether a presentation involves selective disclosure or a whole credential is not technically relevant to Verifiers. 11 | This is because in KILT a presentation **is** a credential. 12 | This means that the logic for Verifiers does not change depending on the case, thus verifying a presentation is as easy as calling one SDK function, like the following code snippet: 13 | 14 | 15 | {VerifyPresentation} 16 | 17 | 18 | :::warning Check if the presenter is the credential subject 19 | Verifying a presentation provides proof that all the information is correct and authentic, and that the credential has not been revoked. 20 | Verifiers still need to match the subject of the credential to the entity that is presenting it. 21 | One way of achieving this is by asking the Claimer to include a challenge in the presentation signature, as shown in the snippet above. 22 | Without a challenge, Verifiers must implement other measures to be certain about the identity of the presenter. 23 | ::: 24 | 25 | :::warning Evaluation of the attester's trust is up to the Verifiers 26 | Verifiers must also have a registry of attesters they trust, and verify that the issuer of the credential they are verifying belongs to such list and, where necessary, whether it is still in operation or not, i.e., whether its DID still exists or has been deleted. 27 | ::: -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/06_credential_revocation.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: attestation-removal 3 | title: Revoke a Credential 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import RevokeCredential from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/07_revoke_credential.ts'; 9 | import ReclaimDeposit from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/claiming/08_reclaim_attestation_deposit.ts'; 10 | 11 | If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain. 12 | This does not automatically delete the credential from the Claimer's wallet, of course, but it makes it impossible for the Claimer to use the credential in the future. 13 | 14 | Since the attestation creation reserved some KILT tokens from the submitter's balance, removing an attestation would return those funds into the payer's pockets. 15 | 16 | 17 | {RevokeCredential} 18 | 19 | 20 | ## Claim Back an Attestation Deposit 21 | 22 | Claiming back the deposit of an attestation is semantically equivalent to revoking and removing the attestation, with the difference that the extrinsic to claim the deposit can only be called by the deposit owner and does not require the Attester's signature: 23 | 24 | 25 | {ReclaimDeposit} 26 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/04_claiming/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "KILT Credentials", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/05_public_credentials/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Public Credentials and AssetDIDs", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/06_messaging/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Messaging", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/08_upgrading_to_v0_29/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Upgrading to v0.29", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/08_upgrading_to_v0_29/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: howto-upgrade-v29-index 3 | title: Upgrading to v0.29 4 | --- 5 | 6 | Version 0.29.0 is the result of our efforts to make the SDK easier to understand and to use. 7 | 8 | As a consequence, quite a few things have changed relative to previous versions. 9 | These pages serve as a reference point for what to consider when upgrading to make your transition as smooth as possible. 10 | 11 | 12 | 13 | Find out what has changed and how to upgrade in the [release notes](https://github.com/KILTprotocol/sdk-js/releases/tag/0.29.0). 14 | 15 | Also make sure to read up on [how to remain interoperable](./01_backward_compatibility.md) with previous versions of the SDK. 16 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/02_cookbook/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Cookbook", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/03_chain_setup/02_peregrine_setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: peregrine-chain-setup 3 | title: Connect to Peregrine 4 | --- 5 | 6 | Before connecting to the production Spiritnet, it is recommended to test applications using its canary network _Peregrine_. 7 | In contrast to [running your own blockchain](./01_standalone_setup.md), you will neither have control over the blockchain, nor have any initial funds. 8 | 9 | In this section we will guide you through the process of receiving funds on Peregrine and connecting to one of the network nodes. 10 | Additionally, we explain the difference between the Standalone and Parachain runtimes. 11 | 12 | ## Receive Funds 13 | 14 | Since the native token of Peregrine, the _PILT_, does not have any economic value, you can request 100 PILT from the [Peregrine faucet](https://substratefaucet.xyz/kilt). 15 | 16 | ## Connect to the Network 17 | 18 | Replace the WebSocket address of [your script](./index.md#set-up-your-project) or application with `wss://peregrine.kilt.io`. 19 | 20 | You can either use your own frontend or the [Polkadot JS Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine.kilt.io%2Fparachain-public-ws#/explorer) to interact with the chain. 21 | For a full list of deployments and services, take a look [here](../../02_chain/03_deployments.md). 22 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/03_chain_setup/03_prod_chain_setup.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: prod-chain-setup 3 | title: Connect to Spiritnet 4 | --- 5 | 6 | For production setups it is important to run your own full node. 7 | Running your own full node has several advantages over relying on a public full node. 8 | 9 | The most important advantage is security. 10 | You rely on the full node to provide you with correct data. 11 | When using a public full node, you rely on a third party: there is no 100% guarantee that the information returned is correct. 12 | 13 | Another important aspect when hosting a full node is availability. 14 | Public full nodes typically do not come with a Service Level Agreement (SLA) and might go down for maintenance or are simply too slow. 15 | With your own full node infrastructure, you can ensure that there is always enough capacity to serve your needs and your customers. 16 | 17 | In our [blockchain section](../../02_chain/01_introduction.md), you can find a [tutorial on how to run your own full node](../../02_chain/04_fullnode.md). 18 | 19 | ## Connect to the Network 20 | 21 | Replace the WebSocket address of [your script](./index.md#set-up-your-project) or application with `wss://kilt-rpc.dwellir.com`. 22 | 23 | You can either use your own frontend or the [Polkadot JS Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com/explorer) to interact with the chain. 24 | Moreover, you can use [Subscan](https://spiritnet.subscan.io/) as a chain explorer. 25 | For a full list of deployments and services, see [here](../../02_chain/03_deployments.md). 26 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/03_chain_setup/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Chain Setup for Development", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/03_chain_setup/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: dev-chain-setup 3 | title: Chain Setup for Development 4 | --- 5 | 6 | If you want to develop solutions that integrate KILT, such as a dapp, a wallet, or a Web3 login, you will need a blockchain environment that can be used for development and testing without requiring you to buy actual KILT tokens. 7 | For that purpose, you can either use the public KILT Peregrine testnet or run your own development blockchain. 8 | 9 | The **Peregrine** network is a parachain that is similar to Spiritnet (our mainnet) in functionality, but its coin, the PILT, doesn't hold any monetary value. 10 | Any new features that we plan to add to our Spiritnet runtime will first undergo a testing period on Peregrine. 11 | This gives developers like you the chance to test your software with any new features before they are available on Spiritnet. 12 | 13 | Nevertheless, there are a scenarios where a public network (that everyone else is also using) is not ideal. 14 | For instance, if you need more funds than the faucet can provide, or if you need to reset the state of the blockchain at any time, you will need to setup your own little KILT blockchain. 15 | 16 | In this section, we will guide you through the process of 17 | 1. [Running your own KILT blockchain](./01_standalone_setup.md) 18 | 2. [Connecting to the Peregrine test network](./02_peregrine_setup.md) 19 | 3. [Connecting to the Spiritnet production network](./03_prod_chain_setup.md) 20 | 21 | ## Set up your Project 22 | 23 | We expect you to already have a small project which can connect and potentially interact with a KILT blockchain given the WebSocket address of a KILT node. 24 | If that is not the case, please take a look at our [Quickstart section](../01_quickstart.md) which will provide you with all necessary means to create and run a basic script. 25 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/04_integrate/01_nodejs.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: howto-integrate-nodejs 3 | title: NodeJS 4 | --- 5 | 6 | import TsJsBlock from '@site/src/components/TsJsBlock'; 7 | 8 | import QueryAccountName from '!!raw-loader!@site/code_examples/sdk_examples/src/core_features/linking/03_account_web3name_query.ts'; 9 | 10 | NodeJS is natively supported and doesn't require any additional setup. 11 | 12 | Have a look at these example `package.json` and `index.js` files for reference: 13 | 14 | ```json 15 | { 16 | "name": "kilt-sdk-node-test", 17 | "type": "module", 18 | "version": "1.0.0", 19 | "main": "index.js", 20 | "license": "MIT", 21 | "dependencies": { 22 | "@kiltprotocol/sdk-js": "0.35.0" 23 | } 24 | } 25 | ``` 26 | 27 | 28 | {QueryAccountName} 29 | 30 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/04_integrate/02_browser.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: howto-integrate-browser 3 | title: Browser 4 | --- 5 | 6 | import Tabs from '@theme/Tabs'; 7 | import TabItem from '@theme/TabItem'; 8 | 9 | Our JavaScript SDK (`@kiltprotocol/sdk-js`) is ready to be used in a browser context. For rapid prototyping of simple web apps, we provide a code bundle of the entire SDK which you can embed in a site by adding the following script tag: 10 | 11 | ```html 12 | 13 | ``` 14 | 15 | The SDK's functions then become available via a new `kilt` property on the global `window` object. 16 | 17 | To get started with your first **React application** using KILT, we recommend using either the [KILT Distillery](./03_distillery.md) CLI tool for bootstrapping or a framework like [Vite](https://vitejs.dev) or [Next.js](https://nextjs.org) that takes away some of the complexity in building and testing a React application. You can find a broader selection of popular React-powered frameworks on the [React project's homepage](https://react.dev/learn/start-a-new-react-project). 18 | 19 | After completing the respective tool's recommended steps to initialize your project, simply add the SDK to your dependencies and you are ready to hack away! 20 | 21 | :::info 22 | 23 | You should of course familiarize yourself with the tool of your choice, but these commands have served us well in the past: 24 | 25 | 26 | 27 | ```bash 28 | yarn create vite my-kilt-app --template react-ts 29 | cd my-kilt-app 30 | yarn add @kiltprotocol/sdk-js 31 | ``` 32 | 33 | 34 | 35 | 36 | ```bash 37 | yarn create next-app my-kilt-app 38 | cd my-kilt-app 39 | yarn add @kiltprotocol/sdk-js 40 | ``` 41 | 42 | 43 | 44 | 45 | ::: 46 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/04_integrate/03_distillery.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: howto-integrate-distillery 3 | title: KILT Distillery 4 | --- 5 | 6 | Different types of projects can be bootstrapped using our [KILT distillery CLI](https://github.com/KILTprotocol/kilt-distillery-cli). 7 | 8 | Please read the README.md file for more information, but if you are impatient you can execute this command and follow the instructions: 9 | 10 | ```bash 11 | npx git+https://github.com/KILTprotocol/kilt-distillery-cli 12 | ``` 13 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/04_integrate/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Integrate the KILT SDK", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/04_integrate/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: howto-integrate-index 3 | title: How to Integrate 4 | --- 5 | 6 | Integrating with KILT is easy. 7 | If your project needs to integrate KILT in a frontend and/or a backend application, we've got you covered! 8 | 9 | These pages are dedicated to helping you set up a [NodeJS application](./01_nodejs.md) or [web app](./02_browser.md). 10 | 11 | We also introduce the [KILT distillery CLI tool](./03_distillery.md) which helps you quickly spin up your first KILT-based project. 12 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/05_troubleshoot.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: troubleshoot-sdk 3 | title: Troubleshoot 4 | --- 5 | 6 | Solutions and workarounds for common or unresolved issues. 7 | 8 | ## Webpack < 5 used to include polyfills 9 | 10 | ``` 11 | ERROR in ./node_modules/cbor/lib/commented.js 3:15-32 12 | Module not found: Error: Can't resolve 'stream' in 'node_modules/cbor/lib' 13 | 14 | BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. 15 | This is no longer the case. 16 | Verify if you need this module and configure a polyfill for it. 17 | ``` 18 | 19 | ### Solution 20 | 21 | The problem occurs because one of the dependecies you are using in your project (or used by a library you depend on) relies on NodeJS built-ins which are not available in a browser context. 22 | You should aim to identify and replace these dependencies with browser-compatible alternatives. 23 | 24 | You might see the above error when using older versions of the KILT SDK with `create-react-app`. Make sure that you are using `@kiltprotocol/sdk-js` version 0.33.0 and above, which work in a browser context out-of-the-box. 25 | 26 | If the affected dependencies cannot be removed or replaced, you may need to look into setting up polyfills for the required NodeJS built-ins. 27 | 28 | ## `redeclaration of import Buffer` 29 | 30 | ``` 31 | Uncaught SyntaxError: redeclaration of import Buffer 32 | ``` 33 | 34 | ### Solution 35 | 36 | Your project might be using polyfills for the NodeJS built-in `Buffer`, which can cause conflicts with some polkadot-js libraries such as `@polkadot/react-identicon`. You can try upgrading the SDK and its dependencies to their latest versions. It's possible that upgrading will allow you to drop these polyfills from your configuration. 37 | -------------------------------------------------------------------------------- /docs/develop/01_sdk/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "SDK", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/02_chain/01_introduction.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: introduction 3 | title: Introduction 4 | --- 5 | 6 | The section covers KILT chain specific topics. 7 | 8 | * Learn about the different [KILT pallets](./02_pallets/01_did.md) (still a WIP) 9 | * Learn about the different [KILT deployments](./03_deployments.md) 10 | * Learn how to run a [KILT full node](./04_fullnode.md) 11 | -------------------------------------------------------------------------------- /docs/develop/02_chain/02_pallets/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "KILT Pallets", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/02_chain/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Chain", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/03_workshop/01_welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: welcome 3 | title: 👋🏻 Welcome 4 | --- 5 | 6 | 7 | 8 | 9 | SDK version **0.35.0**. 10 | 11 | :::info What you can expect to learn 12 | 13 | 📦 **Topics**: [KILT SDK](https://github.com/KILTprotocol/sdk-js) essentials, basic credential workflow. 14 | This includes creating a CType and a claim, attesting a claim, and finally verifying the credential. 15 | 16 | ⏳ **Duration**: 15-45 minutes. 17 | 18 | 🤓 **Prerequisites**: 19 | 20 | - Basic JavaScript or TypeScript knowledge. 21 | - [Node.js](https://nodejs.org/) installed. Any stable LTS version >= 16.0. 22 | 23 | ❓ **Questions?** Join our [developer community channel](https://discord.gg/hX4pc8rdHS)! 24 | 25 | ::: 26 | 27 | ## Welcome, curious mind! 28 | 29 | In this tutorial, you will: 30 | 31 | ✔ Get familiar with the essential concepts in KILT: accounts, DIDs, CTypes, claims, credentials, and more. 32 | 33 | ✔ Use the KILT SDK to implement the basic flow of a KILT claim, from creation until verification. 34 | You'll create a claim as a Claimer, attest it as an Attester and verify it as a Verifier. 35 | 36 | ✔ Use the KILT SDK to write onto and read from the KILT blockchain. 37 | 38 | Ready? Let's go! 39 | -------------------------------------------------------------------------------- /docs/develop/03_workshop/04_attester/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "🏢 Attester", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/03_workshop/05_claimer/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "👤 Claimer", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/03_workshop/08_done.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: done 3 | title: 🚀 Done 4 | --- 5 | 6 | ## Congrats! 7 | 8 | Well done! 9 | You now understand the main actors in KILT, the `Claimers`, `Attesters` and `Verifiers`. 10 | 11 | You have also learned how to: 12 | 13 | - create accounts 14 | - create light and full DIDs 15 | - create claims and attestation requests 16 | - process requests and attest credentials 17 | - generate and sign credential presentations 18 | - receive and verify presentations 19 | 20 | ## Resources 21 | 22 | Here are some resources to help you continue your journey in the KILT ecosystem: 23 | 24 | - [Discord](https://discord.gg/5VZnPdTZMy) - DAO-inspired, outcome-focused community 25 | - [Element](https://matrix.to/#/%23kilt-general:matrix.org) - Technical, Governance, Treasury discussion 26 | -------------------------------------------------------------------------------- /docs/develop/03_workshop/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Workshop", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/04_specifications.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: specifications 3 | title: Technical Specifications 4 | --- 5 | 6 | :::note 7 | This section is a WIP. 8 | The end goal is for it to host all KILT specifications. 9 | ::: 10 | 11 | List of core specifications KILT has defined in an effort to standardize APIs and data structures across applications: 12 | 13 | - [KILT DID Method (GitHub repo)][kilt-did-method] 14 | - [KiltPublishedCredentialCollectionV1 Service Type (GitHub repo)][kilt-published-credential-collection-v1] 15 | - [Asset DID Method (GitHub repo)][asset-did-method] 16 | - [KiltTransferAssetRecipientV1 Service Type (GitHub repo)][kilt-transfer-asset-receipient-v1] 17 | 18 | List of extensions to the core KILT protocol that standardize communication with the core KILT components (e.g., API for wallets to present credentials): 19 | 20 | - [Wallet Credential API (GitHub repo)][kilt-wallet-credential-api] 21 | - [Wallet DIDSign API (GitHub repo)][kilt-wallet-didsign-api] 22 | 23 | [kilt-did-method]: https://github.com/KILTprotocol/spec-kilt-did 24 | [kilt-published-credential-collection-v1]: https://github.com/KILTprotocol/spec-KiltPublishedCredentialCollectionV1 25 | [asset-did-method]: https://github.com/KILTprotocol/spec-asset-did 26 | [kilt-transfer-asset-receipient-v1]: https://github.com/KILTprotocol/spec-KiltTransferAssetRecipientV1 27 | [kilt-wallet-credential-api]: https://github.com/KILTprotocol/spec-ext-credential-api 28 | [kilt-wallet-didsign-api]: https://github.com/KILTprotocol/spec-ext-didsign-api 29 | -------------------------------------------------------------------------------- /docs/develop/07_dApp/01_welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: welcome 3 | title: Overview 4 | --- 5 | 6 | This section expands on the [Credential API Specification](https://github.com/KILTprotocol/spec-ext-credential-api) and includes code examples to help you build a decentralized application (dapp). 7 | 8 | This documentation assumes that you already have a browser extension capable of exposing the credential API to your dapp. 9 | We suggest using Sporran: 10 | 11 | - [Sporran Full Version](https://github.com/KILT-Foundation/sporran-extension) 12 | - [Sporran Test Version for Peregrine](https://github.com/KILT-Foundation/sporran-extension/releases) 13 | - [Sporran Lite (Credentials only)](https://github.com/KILT-Foundation/sporran-extension/tree/sporran-lite) 14 | -------------------------------------------------------------------------------- /docs/develop/07_dApp/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "DApp", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/08_opendid/05_demo_project.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: demo_project 3 | title: Demo Project 4 | --- 5 | 6 | The example code at [demo-project](https://github.com/KILTprotocol/opendid/tree/main/demo-project) contains a minimal application that uses OpenDID. 7 | It's an [express](https://expressjs.com) application that exposes three things: 8 | 9 | - A login page that handles the dispatching of the user to the OpenDID service. 10 | - A callback page for one of the OpenID Connect flows supported to accept the token. 11 | - A protected resource that only authenticated users can access. 12 | 13 | For the demo application to work you need a running OpenDID Service and an identity wallet that follows [the Credential API spec](https://github.com/KILTprotocol/spec-ext-credential-api) (e.g. [Sporran](https://www.sporran.org/)) with a DID and Credential issued by the required attester specified in the `config.yaml` file (Default is SocialKYC). 14 | If you follow the steps in this section in order, you have all the necessary components for the demo application to run. 15 | 16 | Run the pre-configured demo application with the following command: 17 | 18 | ```bash 19 | docker run -d -it --rm \ 20 | --name demo-frontend \ 21 | -p 1606:1606 \ 22 | docker.io/kiltprotocol/opendid-demo 23 | ``` 24 | 25 | The demo page runs on _http://localhost:1606_. It pre-fills the Client ID value and offers login buttons to follow the implicit or authorization code flow. 26 | 27 | :::note 28 | You can set the JSON web token (JWT) secret can with the `TOKEN_SECRET` environment variable inside the docker container. It must match 29 | the one specified in the `config.yaml` file to correctly verify the `id_token`. The default is `super-secret-jwt-secret`. 30 | ::: 31 | -------------------------------------------------------------------------------- /docs/develop/08_opendid/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "OpenDID", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/09_polarpath/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Polar path", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/develop/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Develop", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/participate/01_staking/01_become_a_collator/02_hardware_requirements.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: hardware-requirements 3 | title: Minimum Hardware Requirements 4 | --- 5 | 6 | The KILT blockchain extrinsic weights were calculated using the following hardware: 7 | 8 | - **OS** - Ubuntu 20.04.2 9 | - **CPU** - AMD Ryzen 7 1700X 10 | - **Storage** - A NVMe solid-state drive. Should be reasonably-sized to deal with blockchain growth. Starting around 250GB will be okay for the next year of the KILT parachain and Polkadot Relay Chain, but it will mostly likely grow after that and will have to be re-evaluated on a regular basis. 11 | - **Memory** - 16GB 12 | 13 | Although the aforementioned hardware is by no means the minimum spec required, the new node *is recommended* to be as close as possible to these capabilities in all the categories. 14 | Having more performant hardware reduces the probability that the node will not be able to produce and propose a valid block on time during the allocated block production slot, missing out on the collating rewards. 15 | 16 | You can measure the performance of the new hardware by benchmarking it using [the steps described in the benchmarking section](../02_advanced_collator_section/06_benchmarking.md). 17 | -------------------------------------------------------------------------------- /docs/participate/01_staking/01_become_a_collator/_03_start_node_binary.mdx: -------------------------------------------------------------------------------- 1 | import Tabs from '@theme/Tabs'; 2 | import TabItem from '@theme/TabItem'; 3 | import styles from '@site/src/pages/styles.module.css'; 4 | 5 | Please select your target network: 6 | 7 |
8 | 12 | 13 | To join the Spiritnet network, run: 14 | 15 | ```bash= 16 | ./target/release/kilt-parachain \ 17 | --chain=spiritnet \ 18 | --runtime=spiritnet \ 19 | --rpc-port=9944 \ 20 | --rpc-cors=all \ 21 | --rpc-methods=unsafe \ 22 | --name="name of collator" \ 23 | --execution=wasm \ 24 | --listen-addr=/ip4/0.0.0.0/tcp/30333 \ 25 | --base-path=$HOME/data/parachain \ 26 | --keystore-path=$HOME/data/keystore \ 27 | --collator \ 28 | -- \ 29 | --chain=polkadot \ 30 | --listen-addr=/ip4/0.0.0.0/tcp/30334 \ 31 | --base-path=$HOME/data/relay \ 32 | --execution=wasm 33 | ``` 34 | 35 | 36 | 37 | To join the Peregrinenetwork, run: 38 | 39 | ```bash= 40 | ./target/release/kilt-parachain \ 41 | --chain=./dev-specs/kilt-parachain/peregrine-kilt.json \ 42 | --runtime=peregrine \ 43 | --rpc-port=9944 \ 44 | --rpc-cors=all \ 45 | --rpc-methods=unsafe \ 46 | --name="name of collator" \ 47 | --execution=wasm \ 48 | --listen-addr=/ip4/0.0.0.0/tcp/30333 \ 49 | --base-path=$HOME/data/parachain \ 50 | --keystore-path=$HOME/data/keystore \ 51 | --collator \ 52 | -- \ 53 | --chain=./dev-specs/kilt-parachain/peregrine-relay.json \ 54 | --listen-addr=/ip4/0.0.0.0/tcp/30334 \ 55 | --base-path=$HOME/data/relay \ 56 | --execution=wasm 57 | ``` 58 | 59 | 60 | 61 |
62 | -------------------------------------------------------------------------------- /docs/participate/01_staking/01_become_a_collator/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Become a Collator", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/participate/01_staking/02_advanced_collator_section/01_adjust_stake.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: adjust-stake 3 | title: Adjust Your Own Stake 4 | --- 5 | 6 | import Tabs from '@theme/Tabs'; 7 | import TabItem from '@theme/TabItem'; 8 | import StakingTxDisclaimer from '../_disclaimer_staking_tx.md'; 9 | 10 | A collator can increase or decrease their stake, always within the limits of the minimum and maximum allowed stake amounts. 11 | The corresponding extrinsics for these operations are `parachainStaking -> candidateStakeMore(more)` and `parachainStaking -> candidateStakeLess(less)`. 12 | 13 | 14 | 15 | 19 | 20 | 21 | ![](/img/chain/parachainStaking-candidateStakeMore.png) 22 | 23 | 1. Select your collator KILT address as the extrinsic submitter (the *using the selected account* field) 24 | 2. Select the extrinsic: `parachainStaking -> collatorStakeMore` 25 | 3. Choose the stake amount that you want to add or remove from your current stake (the *more* field). 26 | You can add up to the maximum of 200,000 KILT and your maximum available balance. 27 | 4. Sign and submit the extrinsic (the *Submit Transaction* button) 28 | 29 | 30 | 31 | 32 | ![](/img/chain/parachainStaking-candidateStakeLess.png) 33 | 34 | 1. Select the collators's KILT address as the extrinsic submitter (the *using the selected account* field) 35 | 2. Select the extrinsic: `parachainStaking -> collatorStakeLess` 36 | 3. Choose the desired stake amount which you want to remove from your current stake (the *less* field). 37 | You can reduce down to minimum collator amount (10,000 KILT), e.g., any value up to the difference of your current stake and the minimum will be accepted. 38 | 4. Sign and submit the extrinsic (the *Submit Transaction* button) 39 | 40 | 41 | -------------------------------------------------------------------------------- /docs/participate/01_staking/02_advanced_collator_section/03_collator_lifecycle.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: lifecycle 3 | title: Lifecycle of a Collator 4 | --- 5 | 6 | The following diagram visualizes the full lifecycle of a collator from owning free KILT to joining the collator candidate pool, initiating the exit, waiting for the stake to be unlockable and eventually unlocking their bond. 7 | It summarizes the previous [exit](./02_exit.md) section. 8 | 9 |
10 | 11 | ```mermaid 12 | flowchart TD 13 | A["Hold (at least) 10K KILT"] -->|join_candidates| B(Candidate) 14 | B --->|init_leave_candidates|I("Leaving Candidate\n(locked)") 15 | I ---> G{"2 Sessions (4h)\n passed?"} 16 | I -->|cancel_leave_candidates|B 17 | G -->|no|I 18 | G -->|yes|H("Leaving Candidate\n(unlocked)") 19 | H -->|execute_leave_candidates|J("Locked Balance") 20 | H -->|cancel_leave_candidates|B 21 | J --->K{"At least 7 days\npassed?"} 22 | K -->|yes|L("Balance with expired lock") 23 | K -->|no|J 24 | L -->|unlock_unstaked|A 25 | 26 | %% style assignment 27 | A:::unstakedFreeKilt 28 | B:::activeCollator 29 | I:::leavingLocked 30 | G:::leavingLocked 31 | H:::leavingUnlocked 32 | J:::leavingUnlocked 33 | K:::leavingUnlocked 34 | L:::stakedReleasableKilt 35 | 36 | %% style definition 37 | classDef leavingLocked fill:#FFF4BD, stroke:none, color:black; 38 | classDef leavingUnlocked fill:#F1C0B9, stroke:black, stroke-width:1px, color:black; 39 | classDef unstakedFreeKilt fill:#85D2D0, stroke:black, stroke-width:1px, color:black; 40 | classDef activeCollator fill:#94C973, stroke:#333, stroke-width:2px, color:black; 41 | classDef stakedReleasableKilt fill:#F37970, stroke:black, color:black; 42 | ``` 43 | 44 |
45 | -------------------------------------------------------------------------------- /docs/participate/01_staking/02_advanced_collator_section/05_bootnodes.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: bootnodes 3 | title: Bootnodes 4 | --- 5 | 6 | import Tabs from '@theme/Tabs'; 7 | import TabItem from '@theme/TabItem'; 8 | 9 | The bootnodes are required to connect to the peer-to-peer network and discover additional peers. 10 | The addresses are included in the chain spec, so there is no need to add them as a parameter to the start command. 11 | For the sake of completeness, the bootnodes are listed below: 12 | 13 | 17 | 18 | 19 | For **Spiritnet**, the parachain bootnodes are: 20 | 21 | ``` 22 | --bootnodes=/dns4/hetzner-1.kilt.io/tcp/30333/p2p/12D3KooWKU8ehzuKAzHEMCy4i4kpJtgCFBCYYhqcub4Y1HR8FRoT \ 23 | --bootnodes=/dns4/hetzner-2.kilt.io/tcp/30333/p2p/12D3KooWDJzJ7TRNKvE2DWXMSSsoKR5TgxsnNy3W1eCBPveX6g9i \ 24 | --bootnodes=/dns/kilt.boot.stake.plus/tcp/30332/wss/p2p/12D3KooWHZ6ftYNVQDm5gbHvtGgkPStaBBQBje8rrtxdH1jJonkW \ 25 | --bootnodes=dns4/boot.helikon.io/tcp/8570/p2p/12D3KooWGaE81VE2rzD5TbeRqpTgQwh2sWXMVfMJLBMHQH8AfoXu \ 26 | --bootnodes=/dns/kilt-polkadot-boot-ng.dwellir.com/tcp/443/wss/p2p/12D3KooWRLyHNCYbYMpQWWESNqyW925VP6vMesotaAXSVB3Efhv4 27 | ``` 28 | 29 | 30 | 31 | 32 | For **Peregrine**, the parachain bootnodes are: 33 | 34 | ``` 35 | --bootnodes=/dns4/eyrie-4.kilt.io/tcp/30371/p2p/12D3KooWALJtiCZzcUPVsCa5f5egGfQyFhPY67kKosDw95bJqK7M 36 | --bootnodes=/dns4/eyrie-5.kilt.io/tcp/30372/p2p/12D3KooWCRgcGtFRsvqxqgysiR6Ah9SAzUNkM12Ef9sy59ZEspSQ 37 | ``` 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /docs/participate/01_staking/02_advanced_collator_section/06_benchmarking.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: benchmarking 3 | title: Benchmark Your Collator 4 | --- 5 | 6 | To enable benchmarking, the collator must enable the benchmarking feature from a new build of the `kilt-parachain`. 7 | 8 | 9 | 10 | :::caution Don't use this binary for running the Collator! 11 | ```bash= 12 | cargo build --release -p kilt-parachain --features=runtime-benchmarks 13 | ``` 14 | ::: 15 | 16 | The benchmarks can be run to compare the server's hardware capabilities against the referenced hardware. 17 | At the moment, we have benchmarked the Spiritnet and Peregrine runtimes on an AMD Ryzen 7 1700X with 64GB RAM and an NVMe SSD. 18 | After executing the benchmarks on a server compare the weights to the official KILT weights. 19 | Your weight results should at least be similar to the official ones and the lower yours are, the better. 20 | 21 | The commands executed to benchmark the KILT runtimes can be found in the official benchmark files for both [Spiritnet](https://github.com/KILTprotocol/kilt-node/tree/master/runtimes/spiritnet/src/weights) and [Peregrine](https://github.com/KILTprotocol/kilt-node/tree/master/runtimes/peregrine/src/weights). 22 | 23 | Below is an example of benchmarking for the the `balances` pallet. 24 | 25 | ```bash= 26 | ./target/release/kilt-parachain \ 27 | benchmark \ 28 | --chain=spiritnet-dev \ 29 | --execution=wasm \ 30 | --wasm-execution=Compiled \ 31 | --heap-pages=4096 \ 32 | --extrinsic=* \ 33 | --pallet=pallet-balances \ 34 | --steps=50 \ 35 | --repeat=20 \ 36 | --output \ 37 | ./runtimes/spiritnet/src/weights/pallet_balances.rs \ 38 | --template \ 39 | ./.maintain/weight-template.hbs 40 | ``` -------------------------------------------------------------------------------- /docs/participate/01_staking/02_advanced_collator_section/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Advanced Collator Section", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/participate/01_staking/03_delegate/01_overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: overview 3 | title: Overview 4 | --- 5 | 6 | In the [KILT **L**imited **D**elegated **P**roof **o**f **S**take (LDPoS)](https://medium.com/kilt-protocol/the-continuing-evolution-of-kilt-protocol-limited-delegated-proof-of-stake-640403427c48) consensus, delegators play an important role (at least in the infancy of the network) to filter the pool of candidates for honest, trusted and well-performing collators. 7 | 8 | The requirements to become a delegator are much less than [those for collators](../01_become_a_collator/01_overview.md). 9 | You only need to stake a relatively low number of tokens and decide on a collator candidate. 10 | Once the collator you have backed with your stake authors a block and thus receives a reward, you and all the other delegators of this collator also receive a reward. 11 | 12 | The following sections will guide you through the process of becoming a delegator, adjusting your stake, revoking a delegation and unstaking your tokens. 13 | 14 | :::info 15 | The amount of delegators per collator is limited. 16 | Currently, each delegator can only stake to one collator per account; this may change if the community decides to enable multiple delegations per account. 17 | ::: 18 | -------------------------------------------------------------------------------- /docs/participate/01_staking/03_delegate/04_exit.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: exit 3 | title: Leave the Set of Delegators 4 | --- 5 | 6 | import StakingTxDisclaimer from '../_disclaimer_staking_tx.md'; 7 | 8 | A Delegator can revoke their delegation by calling `parachainStaking -> leaveDelegators`. 9 | As a result, you won't receive any rewards immediately after the transaction is successfully executed. 10 | 11 | - Your previously delegated amount will be prepared for unstaking. 12 | - You need to wait 7 days (in block time) before you can unlock your unstaked tokens, see the section [Unlock Unstaked](../05_unlock_unstaked.md) for more information. 13 | - Exiting does not count towards the limit of “1 delegation per round”. 14 | 15 | 16 | 17 | ![](/img/chain/parachainStaking-leaveDelegators.png) 18 | 19 | 1. Select the KILT address you delegated from as the extrinsic submitter (the *using the selected account* field) 20 | 2. Select the appropriate extrinsic: `parachainStaking -> leaveDelegators`. 21 | 3. Sign and submit the extrinsic (the *Submit Transaction* button) 22 | -------------------------------------------------------------------------------- /docs/participate/01_staking/03_delegate/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Delegate", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/participate/01_staking/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Staking", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/participate/01_staking/_disclaimer_staking_tx.md: -------------------------------------------------------------------------------- 1 | :::info 2 | You can either execute this transaction in Polkadot JS Apps or the [**KILT Stakeboard**](../../develop/05_builtonkilt.md#web-apps), which serves as an in-house developed Frontend for all KILT staking activity. 3 | Below, we outline the steps for Polkadot JS Apps. 4 | ::: 5 | 6 | In the Polkadot JS Apps ([wss://spiritnet.kilt.io](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer), or [wss://peregrine.kilt.io](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer)) go to `Developer -> Extrinsics -> Submission`. 7 | -------------------------------------------------------------------------------- /docs/participate/02_governance/02_remove_vote.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: remove_vote 3 | title: Remove a Vote 4 | --- 5 | 6 | If you happen to change your mind and want to remove a vote from an open referendum, you have to find the index of the referendum you voted on, remove your vote from that index and unlock your coins that are no longer locked up by this vote. 7 | 8 | ## Find the Referendum Index 9 | 10 | 1. Go to the [Democracy tab in Polkadot.JS Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fspiritnet.api.onfinality.io%2Fpublic-ws#/democracy) 11 | 2. Note the number next to the referendum you voted for 12 | 13 | ![](/img/chain/find-referendum-index.png) 14 | 15 | ## Remove the Vote 16 | Go to the [Extrinsic tab in Polkadot.JS Apps](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fspiritnet.api.onfinality.io%2Fpublic-ws#/extrinsics) 17 | 18 | 1. Select the account you used for voting 19 | 1. Select the `democracy` pallet 20 | 2. Select the `removeVote` extrinsic 21 | 3. Enter the index of the referendum 22 | 4. Sign and send the extrinsic 23 | 24 | ![](/img/chain/remove-vote.png) 25 | 26 | ## Unlock Expired Voting Locks 27 | 28 | Please refer to the "[Unlock coins after lockup expires](./03_unlock_coins.md)" guide. 29 | -------------------------------------------------------------------------------- /docs/participate/02_governance/03_unlock_coins.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: unlock_coins 3 | title: Remove Expired Voting Locks 4 | --- 5 | 6 | After the lockup time has been reached, a transaction is needed to clear the lock. 7 | Of note: this will also require a transaction fee. 8 | 9 | 1. Go to KILT Spiritnet on Polkadot.JS 10 | 2. Click the three dots on the right of your account. This opens up a pop-up. 11 | 3. Click “Clear expired democracy locks” 12 | 13 | ![](/img/chain/unlock-vote.jpg) 14 | 15 | Confirm the transaction. 16 | This will clear the lock. 17 | -------------------------------------------------------------------------------- /docs/participate/02_governance/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Governance", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /docs/participate/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Participate", 3 | "collapsible": true, 4 | "collapsed": true 5 | } 6 | -------------------------------------------------------------------------------- /markdown-link-check.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "replacementPatterns": [ 3 | { 4 | "pattern": "^@site/", 5 | "replacement": "{{BASEURL}}/" 6 | }, 7 | { 8 | "pattern": "^/img/", 9 | "replacement": "{{BASEURL}}/static/img/" 10 | } 11 | ], 12 | "aliveStatusCodes": [ 13 | 200, 14 | 403 15 | ], 16 | "ignorePatterns": [ 17 | { 18 | "pattern": "^#.+" 19 | }, 20 | { 21 | "pattern": "/(localhost)." 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /scripts/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "rules": { 8 | "eol-last": "error", 9 | "max-len": [ 10 | "error", 11 | 140 12 | ], 13 | "sort-imports": [ 14 | "error", 15 | { 16 | "ignoreCase": false, 17 | "ignoreDeclarationSort": false, 18 | "ignoreMemberSort": false, 19 | "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], 20 | "allowSeparatedGroups": true 21 | } 22 | ] 23 | }, 24 | "extends": [ 25 | "eslint:recommended", 26 | "plugin:@typescript-eslint/eslint-recommended", 27 | "plugin:@typescript-eslint/recommended", 28 | "prettier" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /scripts/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "trailingComma": "none", 4 | "singleQuote": true, 5 | "printWidth": 80 6 | } 7 | -------------------------------------------------------------------------------- /scripts/out/claim.json: -------------------------------------------------------------------------------- 1 | { 2 | "cTypeHash": "0xc22f85da01c18c1b48acf9556ac7167247ce253cc10373ea77f50fc91521d478", 3 | "contents": { 4 | "name": "Alice", 5 | "age": 29 6 | }, 7 | "owner": "did:kilt:4qWb21mMmWjbgsVuQPJ1f9VFQMbyZwDSFC5wTzJZC91ehVam" 8 | } 9 | -------------------------------------------------------------------------------- /scripts/out/ctype-schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "ipfs://bafybeiah66wbkhqbqn7idkostj2iqyan2tstc4tpqt65udlhimd7hcxjyq/", 3 | "title": "Drivers License by did:kilt:4t9FPVbcN42UMxt3Z2Y4Wx38qPL8bLduAB11gLZSwn5hVEfH", 4 | "additionalProperties": false, 5 | "properties": { 6 | "name": { 7 | "type": "string" 8 | }, 9 | "age": { 10 | "type": "integer" 11 | }, 12 | "id": { 13 | "type": "string" 14 | } 15 | }, 16 | "type": "object" 17 | } -------------------------------------------------------------------------------- /scripts/out/ctype.json: -------------------------------------------------------------------------------- 1 | { 2 | "$id": "kilt:ctype:0x4f1d68ac46daf4613181b33b16faaf10cf94879dc2246d7485dc2ccbb843641d", 3 | "$schema": "ipfs://bafybeiah66wbkhqbqn7idkostj2iqyan2tstc4tpqt65udlhimd7hcxjyq/", 4 | "additionalProperties": false, 5 | "properties": { 6 | "age": { 7 | "type": "integer" 8 | }, 9 | "id": { 10 | "type": "string" 11 | }, 12 | "name": { 13 | "type": "string" 14 | } 15 | }, 16 | "title": "Drivers License by did:kilt:4t9FPVbcN42UMxt3Z2Y4Wx38qPL8bLduAB11gLZSwn5hVEfH", 17 | "type": "object" 18 | } -------------------------------------------------------------------------------- /scripts/out/encrypted-message.json: -------------------------------------------------------------------------------- 1 | { 2 | "ciphertext": "0xde0ffa39b3cc4de956e65498aa6f5eafaa587441ee0682eef6b3dc3db5fd452be05d9d3b696b5ed8267addf86125d661aeff66cd234a2df144073efbc03001cf36f1c40af1a310a9acbd10974de000517b5712ea6f19649df88be14e92961d979203c56ddb5f9eb7fc50e8cba537b4db656739a91f0419f15d9e1aeaa6c6d40c494f5217b2c2505c6f07c4a4ac1d65e3ed2825c0a672bc54a0b17936aecda3b1611a2cf0c35c84f8af48081d92a9d9e965d61f9c5c60f2104236506a83801541c45b2413a849447f40d74f86c58f52e65e9125997b63ef2f289305e386dc3d97f65c68bc6a01d8e567fe1323d83b5a2ef22877f1aadf0a60873f423fb423c812e4e3cec958f515d7a73bf3309254622948beebed211c862567067858df2121d1678c0578e90600f9bb127d605f1a54a01a7f19b64108d1b5febf285e4dcf7d62c0765645699d7b41751aa89fbe9b8064ba2f202fea361b6e5a643e759acd779d58ab541061956dd7a0f8a8230c3ee87355bd2c391356df765752f0e0e937ac2f9412afc1e26588028a2973e4276a30ab853356cd4b0afb", 3 | "nonce": "0x010101010101010101010101010101010101010101010101", 4 | "senderKeyUri": "did:kilt:4qWb21mMmWjbgsVuQPJ1f9VFQMbyZwDSFC5wTzJZC91ehVam#0x6833db3ef3c37f865f769ac12b7c70e84d5d219622c941d3fa5199ac6be8ba8f", 5 | "receiverKeyUri": "did:kilt:4t9FPVbcN42UMxt3Z2Y4Wx38qPL8bLduAB11gLZSwn5hVEfH#0x04e74f9e54eb74179d3661aa2b3dc927b457c05d15b9ce0d50a9a3d58bcf9153" 6 | } 7 | -------------------------------------------------------------------------------- /scripts/out/public-credential.json: -------------------------------------------------------------------------------- 1 | { 2 | "claims": { 3 | "name": "Alice", 4 | "age": 29 5 | }, 6 | "cTypeHash": "0xc22f85da01c18c1b48acf9556ac7167247ce253cc10373ea77f50fc91521d478", 7 | "delegationId": null, 8 | "subject": "did:asset:eip155:1.erc721:0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb:1005" 9 | } 10 | -------------------------------------------------------------------------------- /scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "KILT Protocol", 3 | "name": "kilt-docs-scripts", 4 | "license": "MIT", 5 | "scripts": { 6 | "check-ts": "yarn tsc -p tsconfig.json --noEmit", 7 | "lint": "eslint . --ext .ts --format=codeframe", 8 | "lint:fix": "yarn lint --fix", 9 | "style": "prettier --check --config .prettierrc '**/*.ts'", 10 | "style:fix": "yarn style --write", 11 | "fix": "yarn lint:fix && yarn style:fix", 12 | "generate": "ts-node src/main.ts" 13 | }, 14 | "dependencies": { 15 | "@kiltprotocol/sdk-js": "0.36.0-rc.1" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "^17.0.21", 19 | "@typescript-eslint/eslint-plugin": "^5.13.0", 20 | "@typescript-eslint/parser": "^5.13.0", 21 | "eslint": "^8.10.0", 22 | "eslint-config-prettier": "^8.4.0", 23 | "eslint-formatter-codeframe": "^7.32.1", 24 | "eslint-plugin-import": "^2.25.4", 25 | "eslint-plugin-node": "^11.1.0", 26 | "eslint-plugin-prettier": "^4.0.0", 27 | "prettier": "^2.5.1", 28 | "ts-node": "^10.6.0", 29 | "typescript": "^4.7.0" 30 | }, 31 | "resolutions": { 32 | "@kiltprotocol/type-definitions": "1.11501.0-peregrine" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /scripts/src/publicCredentials.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/scripts/src/publicCredentials.ts -------------------------------------------------------------------------------- /scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "skipLibCheck": true, 5 | "target": "ES2020" 6 | } 7 | } -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | concepts: [ 3 | { 4 | type: 'autogenerated', 5 | dirName: 'concepts', 6 | }, 7 | ], 8 | staking: [ 9 | { 10 | type: 'autogenerated', 11 | dirName: 'participate/01_staking', 12 | }, 13 | ], 14 | governance: [ 15 | { 16 | type: 'autogenerated', 17 | dirName: 'participate/02_governance', 18 | }, 19 | ], 20 | chain: [ 21 | { 22 | type: 'autogenerated', 23 | dirName: 'develop/02_chain', 24 | }, 25 | ], 26 | workshop: [{ type: 'autogenerated', dirName: 'develop/03_workshop' }], 27 | dApp: [{ type: 'autogenerated', dirName: 'develop/07_dApp' }], 28 | opendid: [{ type: 'autogenerated', dirName: 'develop/08_opendid'}], 29 | 30 | sdk: [ 31 | { type: 'autogenerated', dirName: 'develop/01_sdk' }, 32 | { 33 | type: 'link', 34 | label: 'API Documentation', 35 | href: 'https://kiltprotocol.github.io/sdk-js/index.html', 36 | }, 37 | ], 38 | } 39 | -------------------------------------------------------------------------------- /src/components/LogoText/custom.module.css: -------------------------------------------------------------------------------- 1 | .sideImage { 2 | display: flex; 3 | } 4 | 5 | .sideImage > .sideImageL { 6 | margin: 10px; 7 | min-width: 180px; 8 | max-width: 180px; 9 | padding: 10px; 10 | } 11 | 12 | .sideImage > .sideImageR { 13 | margin: 10px; 14 | padding: 10px; 15 | } 16 | 17 | .sideImageImg { 18 | height: 150px; 19 | } 20 | 21 | @media screen and (max-width: 420px) { 22 | .sideImage { 23 | flex-direction: column; 24 | } 25 | 26 | .sideImage > .sideImageL { 27 | margin: 10px auto; 28 | min-width: 200px; 29 | max-width: 200px; 30 | } 31 | 32 | .sideImageL > a > img { 33 | min-width: 100%; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/components/LogoText/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import clsx from 'clsx' 3 | import styles from './custom.module.css' 4 | import ThemedImage from '@theme/ThemedImage' 5 | 6 | const LogoText = ({ children, width, linkTo, alt, srcLight, srcDark }) => { 7 | 8 | return ( 9 |
10 |
11 | 12 | 20 | 21 |
22 |
{children.props.children}
23 |
24 | ) 25 | } 26 | 27 | export default LogoText 28 | -------------------------------------------------------------------------------- /src/components/SnippetBlock/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import CodeBlock from '@theme/CodeBlock' 3 | 4 | const SnippetBlock = ({ 5 | children, 6 | funcName = 'main', 7 | leadingSpaces = 2, 8 | dropHead = 0, 9 | dropTail = 0, 10 | ...props 11 | }) => { 12 | const regex = new RegExp( 13 | `${funcName}\\((?:.|\\n|\\r)*?\\)(?::(?:.|\\n|\\r)*?)?\\s*{(?:\\n|\\r)*(?(?:.|\\n|\\r)+)\\}` 14 | ) 15 | const matched = children.toString().match(regex) ?? {} 16 | 17 | let code = '' 18 | if (!matched?.groups?.body) { 19 | code = children.toString() 20 | } else { 21 | const { body } = matched.groups 22 | const lines = body 23 | // Remove leading spaces 24 | .split(/\r?\n/) 25 | code = lines 26 | .map((line) => line.slice(leadingSpaces)) 27 | // Exclude start index. End index is already excluded by `slice` 28 | .slice(parseInt(dropHead), lines.length - parseInt(dropTail) - 1) 29 | .join('\n') 30 | } 31 | return {code} 32 | } 33 | 34 | export default SnippetBlock 35 | -------------------------------------------------------------------------------- /src/pages/styles.module.css: -------------------------------------------------------------------------------- 1 | /* stylelint-disable docusaurus/copyright-header */ 2 | 3 | /** 4 | * CSS files with the .module.css suffix will be treated as CSS modules 5 | * and scoped locally. 6 | */ 7 | 8 | .heroBanner { 9 | padding: 4rem 0; 10 | text-align: center; 11 | position: relative; 12 | overflow: hidden; 13 | } 14 | 15 | @media screen and (max-width: 966px) { 16 | .heroBanner { 17 | padding: 2rem; 18 | } 19 | } 20 | 21 | .buttons { 22 | display: flex; 23 | align-items: center; 24 | justify-content: center; 25 | } 26 | 27 | .features { 28 | display: flex; 29 | align-items: center; 30 | padding: 2rem 0; 31 | width: 100%; 32 | text-align: center; 33 | } 34 | 35 | .featureImage { 36 | height: 200px; 37 | width: 200px; 38 | } 39 | 40 | .featureLink { 41 | color: #000000; 42 | } 43 | 44 | html[data-theme='dark'] .featureLink { 45 | color: white; 46 | } 47 | -------------------------------------------------------------------------------- /src/theme/Admonition/Types.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import DefaultAdmonitionTypes from '@theme-original/Admonition/Types' 3 | import { nodeVersions } from '@site/src/versions' 4 | 5 | function VersionLabel(props) { 6 | const supportMatrix = {} 7 | const feature = props.title 8 | for (const [key, value] of Object.entries(nodeVersions)) { 9 | let version = key 10 | let featureArray = Object.values(value['features']) 11 | for (const [key, value] of Object.entries(featureArray)) { 12 | if (feature in value) { 13 | supportMatrix[version] = value 14 | } 15 | } 16 | } 17 | 18 | return ( 19 |
20 |
21 | {props.title} feature support 22 |
23 |
24 | {Object.entries(supportMatrix).map(([version, network]) => ( 25 |
  • 26 | {version} {network[feature]} 27 |
  • 28 | ))} 29 |
    30 |
    31 | ) 32 | } 33 | 34 | const AdmonitionTypes = { 35 | ...DefaultAdmonitionTypes, 36 | 'version-label': VersionLabel, 37 | } 38 | export default AdmonitionTypes 39 | -------------------------------------------------------------------------------- /src/utilities/archive.js: -------------------------------------------------------------------------------- 1 | // require modules 2 | const fs = require('fs'); 3 | const archiver = require('archiver'); 4 | const args = require('node-args'); 5 | const folders = args.folders.split(','); 6 | 7 | /** 8 | * accepts an array of folders, zips root js and json files 9 | * along with all js files in subdirectories, excluding node_modules 10 | * package script can accept a comma separated list of folders 11 | * @param {array} array of folders in code-examples to compress 12 | */ 13 | function archive(folders) { 14 | const directory = folders.pop(); 15 | if (!directory) process.exit(); 16 | const folder = `${__dirname}/../../code_examples/${directory}`; 17 | if (!fs.existsSync(folder)) throw Error(`no such folder ${folder}`); 18 | const output = fs.createWriteStream(`${__dirname}/../../static/${directory}.zip`); 19 | const archive = archiver('zip', { zlib: { level: 9 } }); 20 | archive.pipe(output); 21 | archive.glob('.', { pattern: ['**/*.ts', '*.json'], cwd: folder, skip: 'node_modules' }); 22 | archive.finalize(); 23 | output.on('end', () => archive(folders)); 24 | } 25 | 26 | archive(folders); 27 | -------------------------------------------------------------------------------- /src/versions.js: -------------------------------------------------------------------------------- 1 | export const nodeVersions = { 2 | '1.14.0':{ 3 | name: 'Polar Path', 4 | features: [ 5 | { polarPath: "Spiritnet" }, 6 | { polarPath: "Peregrine" }, 7 | ], 8 | }, 9 | '1.13.0':{ 10 | name: 'Dippy Duck', 11 | features: [ 12 | { DIP: "Spiritnet" }, 13 | { DIP: "Peregrine" }, 14 | { limitedReserveTransfers: "Spiritnet" }, 15 | { limitedReserveTransfers: "Peregrine" }, 16 | ], 17 | }, 18 | '1.12.1':{ 19 | name: 'Migration Madness', 20 | features: [{ DIP: "Peregrine" }], 21 | }, 22 | '1.11.1':{ 23 | name: 'Multisig Marvel', 24 | features: [], 25 | }, 26 | } 27 | 28 | export const sdkVersions = [] 29 | 30 | // Ref: https://github.com/KILTprotocol/kilt-node/releases 31 | -------------------------------------------------------------------------------- /static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/.nojekyll -------------------------------------------------------------------------------- /static/CNAME: -------------------------------------------------------------------------------- 1 | dev.kilt.io -------------------------------------------------------------------------------- /static/img/catbox.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /static/img/chain.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain.jpg -------------------------------------------------------------------------------- /static/img/chain/author-hasKey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/author-hasKey.png -------------------------------------------------------------------------------- /static/img/chain/author-rotateKeys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/author-rotateKeys.png -------------------------------------------------------------------------------- /static/img/chain/cast-vote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/cast-vote.png -------------------------------------------------------------------------------- /static/img/chain/chain-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/chain-menu.png -------------------------------------------------------------------------------- /static/img/chain/chain-selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/chain-selection.png -------------------------------------------------------------------------------- /static/img/chain/find-referendum-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/find-referendum-index.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-batch-incrementCollatorRewards-claimRewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-batch-incrementCollatorRewards-claimRewards.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-batch-incrementDelegatorRewards-claimRewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-batch-incrementDelegatorRewards-claimRewards.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-cancelLeaveCandidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-cancelLeaveCandidates.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-candidateStakeLess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-candidateStakeLess.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-candidateStakeMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-candidateStakeMore.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-claimRewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-claimRewards.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-delegatorStakeLess.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-delegatorStakeLess.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-delegatorStakeMore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-delegatorStakeMore.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-executeLeaveCandidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-executeLeaveCandidates.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-getUnclaimedStakingRewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-getUnclaimedStakingRewards.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-incrementCollatorRewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-incrementCollatorRewards.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-incrementDelegatorRewards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-incrementDelegatorRewards.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-initLeaveCandidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-initLeaveCandidates.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-joinCandidates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-joinCandidates.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-joinDelegators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-joinDelegators.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-leaveDelegators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-leaveDelegators.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-revokeDelegation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-revokeDelegation.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-topCandidates1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-topCandidates1.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-topCandidates2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-topCandidates2.png -------------------------------------------------------------------------------- /static/img/chain/parachainStaking-unlockUnstaked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/parachainStaking-unlockUnstaked.png -------------------------------------------------------------------------------- /static/img/chain/remove-vote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/remove-vote.png -------------------------------------------------------------------------------- /static/img/chain/session-key-file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/session-key-file.png -------------------------------------------------------------------------------- /static/img/chain/session-setKeys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/session-setKeys.png -------------------------------------------------------------------------------- /static/img/chain/session-validators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/session-validators.png -------------------------------------------------------------------------------- /static/img/chain/tipping-extrinsic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/tipping-extrinsic.png -------------------------------------------------------------------------------- /static/img/chain/tipping-navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/tipping-navigation.png -------------------------------------------------------------------------------- /static/img/chain/unlock-vote.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/unlock-vote.jpg -------------------------------------------------------------------------------- /static/img/chain/vote-conviction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/vote-conviction.png -------------------------------------------------------------------------------- /static/img/chain/vote-sign-sporran.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/chain/vote-sign-sporran.png -------------------------------------------------------------------------------- /static/img/concepts/credentials/overview.drawio: -------------------------------------------------------------------------------- 1 | 3VjZbtswEPwaP7rQER1+dJSkRZEWAVL0eCpocSWzpbQGRSVxv75USN224yJK68aAAWm4WpI7OyPaMzfKHt4Ksll/QAp85lipYHTmXswcx1ZfA9yyX2BAy6Alo1D0AiUil2zTB2PMc4hlDyNC4H0/bENS6AEJcjqKuI0JhxH6hVG51mjoBC3+Dli6rme2/YUeyUgdbHZSrAnF+w7kXs7cSCBKfZU9RMCrytR10c9d7RltFiYgl8c8IErr6/voPPkYW98zmH+LMubMXZ3ljvDSbNgsVm7rCgBVBTG3KOQaU8wJv2zRc4FlTqGaxlJ3bcw14kaBtgJ/gJRbwy4pJSpoLTNuRvWc1UR792agAksRw4EN1T1CRAryQJzTMKD6EjADKbbqOQGcSHbXXwcxPZQ2cW2Z1YWp9B9U3R6XPeKEZcXO4l+TlVJMr2CEszRX17GqDwgF3IGQTHXt0gxkjFLNDRTsF1k95qvY2SDL5eN+vPOZd9EU3+jHRLZdWyWGh7207G+qcW1Nlrn1xlYfnWvby3x09U3ym2oznRBMkkKxPqSnWcMzGNtNmKr9kDEl8011WWZ8GUvskvNI5A0WTDKsSFqhlJjtYE9WuunyjaXkLIeoMbmKyoRxHiGvplATu5RAmMQKL6TAn9AZ8eMQVklD9ROU2gfZC6w+cb65v2/N0TXQuuOLddj0Ujo7ZcN6hsEMWrzmy+7Xv3lP1im08Zmnum+DQaIhkaNE2mlHiSYTlDdS1FJKKOQr8UDdl3tlpDzQDbxTdz1nD0enZHtJAn680/ZosFhZ1jS254Sn5nv2iIIT8r0jDmrBi/ijs/D6tuYd54+T2dpYMp9E+Xpc7bBKlKs54WLKk11/fSbn3PH6CV7w3Of/C5kVqkvlsvr1WnUCJ0XB4hq+YrwOg5zWQTnmoBEzbv0Pah2Y6rFiVZsm206Y6fxjp3FN+7StohNO2zjByAhulGIhfzVW4D9hBU7oBX3ZPtMLmjTh31L/mMPPIFjCTun8Qz0I6dmu80/orFzfn+b8Yw+lWr9npz//qNv2TzHNZPu/oXv5Gw== -------------------------------------------------------------------------------- /static/img/concepts/credentials/overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/concepts/credentials/overview.png -------------------------------------------------------------------------------- /static/img/concepts/credentials/overview_dark.drawio: -------------------------------------------------------------------------------- 1 | 7Vhrb5swFP01+ZiJRyHkY0LbTVM3Veq0x6fJgQvxanBmTNv018/GNo+QpJlCu3QbUhQ4vlzMPeceW4zcMHt4y9Bq+YHGQEaOlTIcj9zzkePY4qeBG/wIGrQ0WuIYik4gp5RwvOqCEc1ziHgHQ4zR+27YCqXQARJK4l7ETYQI9NAvOOZLhQbOpMHfAU6X5sm2P1UjCxTdpoyWuU4/clw7sKc2UsMZMrn0ixZLFNP7FuRejNyQUcrVWfYQApGFM2VT913uGK3nzSDnh9zASuvr+3CefIys7xmMv4UZdsauynKHSAnmNarJ8rUpEMSiXvqSMr6kKc0RuWjQeVUEkI+xxFUTc0XpSoC2AH8A52tNPio5FdCSZ0SPErQAMq/rGVJCmRjKaS7TJzTnBhJFvqwOgRec0VvYNqLeQU58Z600VNCSRbCnQEaSiKXA98Q5NaOiDYBmwNla3MeAII7vuvNAWrJpHdfQJk40c7/Bot2nMSQIZ8VWMq9ktbsEIILTXJxHoj4gqjm/A8axaJKZHshwHCuuocCPaFHlk2yvKM559T7efOSd7yazaY/djHY6XT+kaSA5J3jYyehuffdp0VnG1htbHCrXupP5YOJ08mtZh1YITZJCCGaT2XoOR5C9pWV9wnVZq/qZyvo/S+kuoq5uUh1tyE/lf6UTQblOIWaksqjRnn6Eia3kaZmRWcRpWyqVrK5pgTmmUjILyjnNtmiJS1doq4+WnOBcdLJxeCmsBBPS0kiMIEiibV3vRwEsknqyT6jE3iuIidXVgq+v75uVwdXQsrUomLDhG/vsX7LjI+xzowsN/3aXz3rTYVIoW9d3tdfOjUSbwuglUutIL9FgPe/1mn7GORT8v8OrFtnZ0cLh3Yl36p7uDOrpShqvwNSTBPxoq6nHk+nCsoYxdSc4NVe3exT8xa5+wCZ78izu70y9rml7h7n/YKbd7+pPrDxNz569rGfvb1jh2U4wHXJX3p2fzjl2vG6CZ9yz+3+i4wshcD6T30ikiAgqChwZ+BITEwZ5bIK0GQhEj1v/onFsrBeH+oYoIlq3wnQTHvoYV8uxkZ5KOKwQJz1PuhbmAflJutIL7yT9J1zJCbxJ10GOtKU6TfBSRtSn/5iN5mdgOMGvYKMZexDEZ9tcKXAWru8Ps9G0N43DbECG32iKy+bLsRJH8+3dvfgF -------------------------------------------------------------------------------- /static/img/concepts/credentials/overview_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/concepts/credentials/overview_dark.png -------------------------------------------------------------------------------- /static/img/concepts/did/did-lookup-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/concepts/did/did-lookup-dark.png -------------------------------------------------------------------------------- /static/img/concepts/did/did-lookup-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/concepts/did/did-lookup-light.png -------------------------------------------------------------------------------- /static/img/concepts/distributed_trust/coming-soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/concepts/distributed_trust/coming-soon.png -------------------------------------------------------------------------------- /static/img/concepts/distributed_trust/delegation-hierarchies.drawio: -------------------------------------------------------------------------------- 1 | 7VrbcpswEP0aP6aDuAU/JnGaTKft5DLTOn1TjAzqYERl2cb9+kogATIYO+MQk9RPQWdXtz2r3c2OB9bVLL2hMAm/ER9FA9Pw04E1GpgmMIHF/whkLRFg2DkSUOxLrAQe8V8kQUOiC+yjuabICIkYTnRwQuIYTZiGQUrJSlebkkjfNYEBqgGPExjV0Z/YZ2GOeuZ5id8iHIRqZ+AOc8kMKmV5k3kIfbKqQNb1wLqihLD8a5ZeoUhYT9kln/d5i7Q4GEUx22cC/TE6I6tJ4Lh3Xjq7/X4/JtGZWmbO1urGyOcGkENCWUgCEsPoukQvKVnEPhLLGnxU6nwlJOEg4OBvxNhasgkXjHAoZLNISlGK2VhM/+TI0VNFMkrlytlgLQf166qjkwWdoJY7SqoYpAFiLXpAeqYwQGUHac0bRGaI0TVXoCiCDC91D4HS0YJCr+SCf0g6XkKN+V6o4YzQdWWSGD5VZeW0bPSGlBq9olQeewmjhdxpYLoRv8Dls0a0+2chosLllMTsbJ5RdcEVgJekmdmUnH8F4u8FY2jOEOU6llqRH/BZyWuOVLqJYHYVYoYeE5iZfMUDue4SS0QZ5hHxIsJBzDEmXCk7m/Qi4LWRKaajtNX6Umrbki6VLDw5XpWRF3jylYaVqDs0OiLMayBsw5QBt2Wy/+WLTAWf1QpGq1EsoBvF2tMmwOjKKKDBKLnP4dLhXDgTXpLBWY5TiJIrJ63OyZ8CrSGNj6P+DJS+cM1Xek/FMfM19X3mCYwP2kfIKnvk67mbFur0Gdc9t/Uh7H7Lx/NLc6tf7u0QdqtDbHWHDVp4pZeIzxClkGdfrpIgivkluUcV6J2CzN3UTXGKVG0MuiBNSk091Dj1UOMadUYt75M37IhTqztORyhCAWTow7M63Mmq98asDvdNq4eUGS/OtI6zkWnBscsPdYAuC0anPwVjq68cnnleg6bl9NfqYQ0WbvDw9GV8f8P/txo3VokfOfE0PLX9aNz69MC59vLs4yce0JR5jh+jLKt3McruPkbZPY9RhbP0OEi5pyC1J4/vKUoNa+Y99Qj1NsXOHmHPur7GidFDGT3vF6P9rCSK5mpvmq1vUEiYPS8kzHdQSGxv/54KCZ3HfhYSjaR22DvtaZ+tA1q9nbR22GhrpPX/a5/uoLW9U+qYOoNFQ7wTCvmw/PVHJqv8iMa6/gc= -------------------------------------------------------------------------------- /static/img/delegated-attestation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/delegated-attestation.png -------------------------------------------------------------------------------- /static/img/delegation-attestation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/delegation-attestation.png -------------------------------------------------------------------------------- /static/img/demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/demo.jpg -------------------------------------------------------------------------------- /static/img/expert_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/img/expert_dark_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/expert_dark_preview.png -------------------------------------------------------------------------------- /static/img/expert_light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/img/faucet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/faucet.jpg -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/infrastructure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/infrastructure.jpg -------------------------------------------------------------------------------- /static/img/phone_hand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/phone_hand.jpg -------------------------------------------------------------------------------- /static/img/telemetry.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KILTprotocol/docs/c2cc21c91a3a03c5ab7b1e076c6ae6c81419816a/static/img/telemetry.jpg --------------------------------------------------------------------------------