From 5a14df7c4faf484fbc12f0a5d95b58aa6dd80903 Mon Sep 17 00:00:00 2001 From: gh-actions Date: Thu, 13 Jun 2024 07:53:16 +0000 Subject: [PATCH] Deploy website - based on 66cf879e7a386baf285fe70531d995a4428db4d0 --- 404.html | 6 +- ...c8c02.143c9373.js => 021c8c02.6fca3a8c.js} | 2 +- assets/js/03ee7140.9f4ed2b5.js | 1 + ...85178.ebc72665.js => 05485178.4426cb50.js} | 2 +- ...b4add.4823f7de.js => 076b4add.9290b1f7.js} | 2 +- ...8c159.873b8dd4.js => 0928c159.8e18f7ca.js} | 2 +- ...2e877.95810bef.js => 0bf2e877.57ec51a7.js} | 2 +- ...84741.214af855.js => 0d584741.29bd6181.js} | 2 +- ...1655b.f9b6ebfa.js => 0dc1655b.29a39d46.js} | 2 +- ...f4b3b.812c14d8.js => 107f4b3b.8e19fd56.js} | 2 +- ...1f88a.3ef55582.js => 1291f88a.64862138.js} | 2 +- ...46d7d.a362b8ee.js => 13646d7d.8d300a47.js} | 2 +- ...6a7ba.dc3849fd.js => 16a6a7ba.107b3a6c.js} | 2 +- ...fc417.a8664556.js => 1c5fc417.cf9f5c3b.js} | 2 +- ...3658d.27016eb6.js => 1e03658d.3e627196.js} | 2 +- ...cf5e0.5779a0c8.js => 1e1cf5e0.ea8cc707.js} | 2 +- ...8a1b9.b4b7eec5.js => 1f78a1b9.fd6d5dad.js} | 2 +- ...78811.69dbf8ae.js => 23178811.cff3f5ff.js} | 2 +- ...8d77a.a51d9997.js => 23f8d77a.59c1ca7b.js} | 2 +- ...0a579.ac37e3b0.js => 2500a579.e45c4c2f.js} | 2 +- ...6e90b.b536d636.js => 2936e90b.47cc57ab.js} | 2 +- ...1f863.ea795549.js => 29f1f863.cceab445.js} | 2 +- ...3795b.3d98a6c6.js => 2d03795b.ac9be6b5.js} | 2 +- ...1ba6c.8f4d004d.js => 2d31ba6c.2e1a3cb7.js} | 2 +- ...97b7b.b3b510e4.js => 2e697b7b.3b9c5490.js} | 2 +- ...5209f.ed926877.js => 3185209f.ef39d14e.js} | 2 +- ...16672.e0532c83.js => 33516672.13872234.js} | 2 +- ...90033.d433db5b.js => 36090033.999a92d7.js} | 2 +- ...d6ba7.ef0e8d73.js => 36dd6ba7.b11b609b.js} | 2 +- ...0d695.89809d58.js => 36f0d695.8611a324.js} | 2 +- ...9f46f.40ef1a70.js => 3969f46f.db301e5e.js} | 2 +- assets/js/3a3bc2e2.dd74f647.js | 1 + ...e0ba5.c45b6189.js => 408e0ba5.55348fb3.js} | 2 +- ...e17fa.e7823a6e.js => 433e17fa.d25abf64.js} | 2 +- ...e04f4.c9118201.js => 436e04f4.e121c2fc.js} | 2 +- ...ce34b.b25ca499.js => 452ce34b.8e340388.js} | 2 +- ...ad316.34f6e50f.js => 544ad316.082144b2.js} | 2 +- ...b69d2.2fa02640.js => 561b69d2.26ea8f4e.js} | 2 +- ...b7aeb.4882c06d.js => 59fb7aeb.fc29ed17.js} | 2 +- ...0d0fa.9d01ffdf.js => 5a60d0fa.ca0109e4.js} | 2 +- assets/js/5af6f4bd.97215a2f.js | 1 + ...4c2a9.f3c40860.js => 5ed4c2a9.832c2a5c.js} | 2 +- ...31a04.3f193387.js => 67a31a04.724d2b99.js} | 2 +- ...9b2e6.e6c8c9f3.js => 6869b2e6.8a6df8e4.js} | 2 +- ...9de3a.903c87df.js => 69e9de3a.e55038e8.js} | 2 +- ...c945e.8d81f8ac.js => 6c2c945e.862df09c.js} | 2 +- ...f0c72.35b92468.js => 6dbf0c72.b0ea4037.js} | 2 +- ...5962d.7e0ea864.js => 6fd5962d.5c196d2d.js} | 2 +- ...5ba4c.8368bd23.js => 7025ba4c.0c22071e.js} | 2 +- ...0f9b2.d0ec26df.js => 7090f9b2.df5fe2d3.js} | 2 +- ...96408.006643f2.js => 72396408.7ee7a8ef.js} | 2 +- ...b5a4f.c12bb331.js => 75eb5a4f.ae69c3b7.js} | 2 +- ...e7414.b565e908.js => 784e7414.937fd63a.js} | 2 +- ...d7fb8.af08c090.js => 787d7fb8.42860fa1.js} | 2 +- ...6cd29.3278c6f7.js => 7b06cd29.94356888.js} | 2 +- ...7f8e3.574eabce.js => 7c37f8e3.3f081d5a.js} | 2 +- ...958d5.62039be9.js => 7c5958d5.f41855b4.js} | 2 +- ...092aa.594fe4c5.js => 82d092aa.0b06be92.js} | 2 +- ...fd642.8d941507.js => 86efd642.6a156908.js} | 2 +- ...538c7.77ddfe84.js => 875538c7.aabb66de.js} | 2 +- ...a18c9.94b533f0.js => 886a18c9.f24fec95.js} | 2 +- ...ceeee.e6db4e43.js => 88dceeee.116c7225.js} | 2 +- ...3d6fd.7918bdd0.js => 8983d6fd.aa48a40c.js} | 2 +- ...c1172.32d6f27c.js => 898c1172.a3c1ef0b.js} | 2 +- ...e067a.12845ce8.js => 8b4e067a.94018ee3.js} | 2 +- assets/js/8e0c7ef4.0de78cf1.js | 1 + ...b832c.de981826.js => 8e9b832c.ec90488d.js} | 2 +- ...fdcc4.9b7dd06d.js => 91ffdcc4.39f654d1.js} | 2 +- assets/js/935f2afb.728ee181.js | 1 - assets/js/935f2afb.85ff5c3f.js | 1 + ...b6178.de2c613f.js => 953b6178.85b49e63.js} | 2 +- assets/js/97432a9d.a5d6aa4f.js | 1 + ...2e26d.308fdd81.js => 97a2e26d.39189474.js} | 2 +- ...f2427.f9d0c3ac.js => 9d9f2427.9f3acff4.js} | 2 +- ...01397.4486851f.js => 9ea01397.09f06f51.js} | 2 +- ...34096.1135e618.js => 9eb34096.315e1a1e.js} | 2 +- ...91c7e.b37f7393.js => 9f891c7e.020af191.js} | 2 +- ...e69e6.b9045aed.js => 9ffe69e6.098f3116.js} | 2 +- ...857e0.cf88c5dc.js => a10857e0.2765861b.js} | 2 +- ...07c93.2ce0041a.js => a1607c93.592c16c5.js} | 2 +- ...92b3a.2a762624.js => a4c92b3a.e8c77d0a.js} | 2 +- ...8543f.afe24c3f.js => a578543f.db185869.js} | 2 +- ...53640.7966050c.js => a6153640.d38feca4.js} | 2 +- ...7c7cb.b69ba5b0.js => a9c7c7cb.dd54e147.js} | 2 +- ...45ca5.f69a5f4d.js => ae345ca5.82dc3682.js} | 2 +- assets/js/afa31ce4.dabeed25.js | 1 + ...56169.81d2a64a.js => afb56169.8e9ed8b6.js} | 2 +- ...16f56.29139edf.js => afc16f56.a363ca31.js} | 2 +- ...5aa24.c935c2c8.js => b345aa24.4d2623c1.js} | 2 +- ...8d35f.30abdf38.js => ba98d35f.e661451f.js} | 2 +- ...bf226.3d931823.js => bbabf226.9aeeb1fc.js} | 2 +- ...830f0.04c4aa4d.js => bc7830f0.8f670026.js} | 2 +- ...099e9.fb8453bc.js => bd8099e9.e770b661.js} | 2 +- ...86f32.b25f8d20.js => bdc86f32.bdf7537c.js} | 2 +- ...21a0f.130bd480.js => be821a0f.d528cd62.js} | 2 +- ...e7b7d.92289f94.js => bf4e7b7d.9100a801.js} | 2 +- ...734e5.499cb6fc.js => bfe734e5.592693f5.js} | 2 +- ...77fcf.04ab2026.js => c0877fcf.8f21c08c.js} | 2 +- ...df8ce.5ea164eb.js => c1edf8ce.adeae358.js} | 2 +- ...e4ef9.c56db97c.js => c62e4ef9.8745fbf8.js} | 2 +- ...0b07d.2cdc4432.js => c9b0b07d.15dce6cd.js} | 2 +- ...542e7.79802b73.js => c9c542e7.1c6576f2.js} | 2 +- ...d6ae6.7828eb06.js => ce6d6ae6.582d4679.js} | 2 +- ...6879e.98e89b26.js => d1b6879e.b9db55cf.js} | 2 +- ...7a52a.1a58b68f.js => d317a52a.c85ed09f.js} | 2 +- ...94416.ac5d9421.js => d7494416.9e056598.js} | 2 +- ...dfd98.bb2db584.js => d9adfd98.103f8afc.js} | 2 +- ...36f18.25929b3d.js => ddd36f18.e39e26be.js} | 2 +- ...b593b.e5d7a2e8.js => e33b593b.a3faab74.js} | 2 +- ...adc61.3c37e33c.js => e4badc61.a6d7b905.js} | 2 +- ...e623e.d9f9176b.js => e89e623e.b1a19113.js} | 2 +- ...42e9e.fa4f6772.js => e9042e9e.be819edf.js} | 2 +- ...93640.2f5f07a5.js => ea293640.e12306b4.js} | 2 +- ...11d1f.554f036a.js => eba11d1f.90af8697.js} | 2 +- ...caa6d.4f8a9b3f.js => efecaa6d.dd8d51d6.js} | 2 +- ...e0f53.1ebd8408.js => f2ae0f53.d2a53694.js} | 2 +- ...8d87a.07d336f0.js => f558d87a.250eedc6.js} | 2 +- ...09bf7.2d3d2403.js => f7709bf7.9fc8db2a.js} | 2 +- assets/js/main.16c1522b.js | 2 - assets/js/main.eff93a2a.js | 2 + ...CENSE.txt => main.eff93a2a.js.LICENSE.txt} | 0 assets/js/runtime~main.95fd9271.js | 1 + assets/js/runtime~main.b4c4f126.js | 1 - .../nested-ctypes/index.html | 8 +- .../terms-and-quotes/index.html | 8 +- docs/concepts/asset-dids/index.html | 8 +- .../credentials/attestation/index.html | 8 +- docs/concepts/credentials/claiming/index.html | 8 +- docs/concepts/credentials/ctypes/index.html | 8 +- docs/concepts/credentials/overview/index.html | 8 +- .../credentials/public-credentials/index.html | 8 +- .../credentials/verification/index.html | 8 +- docs/concepts/did/index.html | 8 +- docs/concepts/dip/consumer/index.html | 8 +- docs/concepts/dip/dapp-developer/index.html | 8 +- .../concepts/dip/dip-accounts-kilt/index.html | 8 +- docs/concepts/dip/provider/index.html | 8 +- docs/concepts/dip/what-is-dip/index.html | 8 +- docs/concepts/distributed_trust/index.html | 8 +- docs/concepts/glossary/index.html | 8 +- docs/concepts/messaging/index.html | 8 +- docs/concepts/web3names/index.html | 8 +- docs/concepts/what-is-kilt/index.html | 8 +- docs/develop/builtonkilt/index.html | 8 +- docs/develop/chain/deployments/index.html | 8 +- docs/develop/chain/fullnode-setup/index.html | 8 +- docs/develop/chain/introduction/index.html | 8 +- .../chain/pallets/pallet-did/index.html | 8 +- docs/develop/contribute/index.html | 8 +- docs/develop/dApp/dapp-verifier/index.html | 8 +- docs/develop/dApp/session/index.html | 8 +- docs/develop/dApp/welcome/index.html | 8 +- .../dApp/well-known-did-config/index.html | 8 +- docs/develop/opendid/advanced/index.html | 31 ++++++ docs/develop/opendid/demo_project/index.html | 26 +++++ docs/develop/opendid/flow/index.html | 40 +++++++ .../opendid/integrate_opendid/index.html | 61 +++++++++++ .../opendid/opendid_service/index.html | 103 ++++++++++++++++++ .../opendid/what-is-opendid/index.html | 30 +++++ docs/develop/sdk/chain_setup/index.html | 8 +- .../peregrine-chain-setup/index.html | 8 +- .../chain_setup/prod-chain-setup/index.html | 8 +- .../standalone-chain-setup/index.html | 8 +- .../account_linking/account-link/index.html | 8 +- .../account_linking/account-name/index.html | 8 +- .../account_linking/account-unlink/index.html | 8 +- .../claiming/attestation-creation/index.html | 8 +- .../claiming/attestation-removal/index.html | 8 +- .../claiming/attestation-request/index.html | 8 +- .../claiming/ctype-creation/index.html | 8 +- .../claiming/presentation-creation/index.html | 8 +- .../presentation-verification/index.html | 8 +- .../sdk/cookbook/dids/did-export/index.html | 8 +- .../sdk/cookbook/dids/did-query/index.html | 8 +- .../cookbook/dids/did-signature/index.html | 8 +- .../cookbook/dids/full-did-batch/index.html | 8 +- .../dids/full-did-creation/index.html | 8 +- .../cookbook/dids/full-did-delete/index.html | 8 +- .../cookbook/dids/full-did-update/index.html | 8 +- .../cookbook/dids/key-generation/index.html | 8 +- .../dids/light-did-creation/index.html | 8 +- .../messaging/messaging_book/index.html | 8 +- .../messaging/replay_protection/index.html | 8 +- .../public-credential-issuance/index.html | 8 +- .../public-credential-retrieval/index.html | 8 +- .../public-credential-revocation/index.html | 8 +- .../sdk/cookbook/signCallback/index.html | 8 +- .../cookbook/upgrading_to_v0_29/index.html | 8 +- .../v29-backward-compatibility/index.html | 8 +- .../web3names/credential-query/index.html | 8 +- .../web3names/web3name-claim/index.html | 8 +- .../web3names/web3name-query/index.html | 8 +- .../web3names/web3name-release/index.html | 8 +- .../howto-integrate-browser/index.html | 8 +- .../howto-integrate-distillery/index.html | 8 +- .../howto-integrate-nodejs/index.html | 8 +- docs/develop/sdk/integrate/index.html | 8 +- docs/develop/sdk/quickstart/index.html | 8 +- docs/develop/sdk/troubleshoot-sdk/index.html | 8 +- docs/develop/specifications/index.html | 8 +- docs/develop/workshop/attestation/index.html | 8 +- .../workshop/attester/account/index.html | 8 +- .../workshop/attester/ctype/index.html | 8 +- docs/develop/workshop/attester/did/index.html | 8 +- docs/develop/workshop/attester/index.html | 8 +- docs/develop/workshop/claimer/did/index.html | 8 +- docs/develop/workshop/claimer/index.html | 8 +- .../workshop/claimer/request/index.html | 8 +- docs/develop/workshop/done/index.html | 8 +- docs/develop/workshop/overview/index.html | 8 +- docs/develop/workshop/setup/index.html | 8 +- docs/develop/workshop/verification/index.html | 8 +- docs/develop/workshop/welcome/index.html | 8 +- .../content-creation-guidelines/index.html | 8 +- .../governance/remove_vote/index.html | 8 +- .../governance/unlock_coins/index.html | 8 +- docs/participate/governance/vote/index.html | 8 +- .../adjust-stake/index.html | 8 +- .../benchmarking/index.html | 8 +- .../bootnodes/index.html | 8 +- .../advanced_collator_section/exit/index.html | 8 +- .../lifecycle/index.html | 8 +- .../monitoring/index.html | 8 +- .../hardware-requirements/index.html | 8 +- .../staking/become_a_collator/join/index.html | 8 +- .../become_a_collator/overview/index.html | 8 +- .../become_a_collator/session-keys/index.html | 8 +- .../become_a_collator/setup-node/index.html | 8 +- .../staking/claim-rewards/index.html | 8 +- .../staking/delegate/adjust-stake/index.html | 8 +- .../staking/delegate/exit/index.html | 8 +- .../staking/delegate/join/index.html | 8 +- .../staking/delegate/lifecycle/index.html | 8 +- .../staking/delegate/overview/index.html | 8 +- .../staking/troubleshooting/index.html | 8 +- .../staking/unlock-unstaked/index.html | 8 +- docs/participate/treasury-proposal/index.html | 8 +- docs/participate/treasury-tip/index.html | 8 +- index.html | 6 +- search/index.html | 6 +- sitemap.xml | 2 +- 241 files changed, 856 insertions(+), 559 deletions(-) rename assets/js/{021c8c02.143c9373.js => 021c8c02.6fca3a8c.js} (98%) create mode 100644 assets/js/03ee7140.9f4ed2b5.js rename assets/js/{05485178.ebc72665.js => 05485178.4426cb50.js} (98%) rename assets/js/{076b4add.4823f7de.js => 076b4add.9290b1f7.js} (98%) rename assets/js/{0928c159.873b8dd4.js => 0928c159.8e18f7ca.js} (98%) rename assets/js/{0bf2e877.95810bef.js => 0bf2e877.57ec51a7.js} (99%) rename assets/js/{0d584741.214af855.js => 0d584741.29bd6181.js} (94%) rename assets/js/{0dc1655b.f9b6ebfa.js => 0dc1655b.29a39d46.js} (98%) rename assets/js/{107f4b3b.812c14d8.js => 107f4b3b.8e19fd56.js} (85%) rename assets/js/{1291f88a.3ef55582.js => 1291f88a.64862138.js} (99%) rename assets/js/{13646d7d.a362b8ee.js => 13646d7d.8d300a47.js} (99%) rename assets/js/{16a6a7ba.dc3849fd.js => 16a6a7ba.107b3a6c.js} (97%) rename assets/js/{1c5fc417.a8664556.js => 1c5fc417.cf9f5c3b.js} (98%) rename assets/js/{1e03658d.27016eb6.js => 1e03658d.3e627196.js} (96%) rename assets/js/{1e1cf5e0.5779a0c8.js => 1e1cf5e0.ea8cc707.js} (99%) rename assets/js/{1f78a1b9.b4b7eec5.js => 1f78a1b9.fd6d5dad.js} (97%) rename assets/js/{23178811.69dbf8ae.js => 23178811.cff3f5ff.js} (99%) rename assets/js/{23f8d77a.a51d9997.js => 23f8d77a.59c1ca7b.js} (86%) rename assets/js/{2500a579.ac37e3b0.js => 2500a579.e45c4c2f.js} (99%) rename assets/js/{2936e90b.b536d636.js => 2936e90b.47cc57ab.js} (99%) rename assets/js/{29f1f863.ea795549.js => 29f1f863.cceab445.js} (96%) rename assets/js/{2d03795b.3d98a6c6.js => 2d03795b.ac9be6b5.js} (98%) rename assets/js/{2d31ba6c.8f4d004d.js => 2d31ba6c.2e1a3cb7.js} (95%) rename assets/js/{2e697b7b.b3b510e4.js => 2e697b7b.3b9c5490.js} (95%) rename assets/js/{3185209f.ed926877.js => 3185209f.ef39d14e.js} (93%) rename assets/js/{33516672.e0532c83.js => 33516672.13872234.js} (93%) rename assets/js/{36090033.d433db5b.js => 36090033.999a92d7.js} (99%) rename assets/js/{36dd6ba7.ef0e8d73.js => 36dd6ba7.b11b609b.js} (98%) rename assets/js/{36f0d695.89809d58.js => 36f0d695.8611a324.js} (98%) rename assets/js/{3969f46f.40ef1a70.js => 3969f46f.db301e5e.js} (99%) create mode 100644 assets/js/3a3bc2e2.dd74f647.js rename assets/js/{408e0ba5.c45b6189.js => 408e0ba5.55348fb3.js} (98%) rename assets/js/{433e17fa.e7823a6e.js => 433e17fa.d25abf64.js} (98%) rename assets/js/{436e04f4.c9118201.js => 436e04f4.e121c2fc.js} (99%) rename assets/js/{452ce34b.b25ca499.js => 452ce34b.8e340388.js} (96%) rename assets/js/{544ad316.34f6e50f.js => 544ad316.082144b2.js} (96%) rename assets/js/{561b69d2.2fa02640.js => 561b69d2.26ea8f4e.js} (99%) rename assets/js/{59fb7aeb.4882c06d.js => 59fb7aeb.fc29ed17.js} (99%) rename assets/js/{5a60d0fa.9d01ffdf.js => 5a60d0fa.ca0109e4.js} (98%) create mode 100644 assets/js/5af6f4bd.97215a2f.js rename assets/js/{5ed4c2a9.f3c40860.js => 5ed4c2a9.832c2a5c.js} (99%) rename assets/js/{67a31a04.3f193387.js => 67a31a04.724d2b99.js} (98%) rename assets/js/{6869b2e6.e6c8c9f3.js => 6869b2e6.8a6df8e4.js} (99%) rename assets/js/{69e9de3a.903c87df.js => 69e9de3a.e55038e8.js} (98%) rename assets/js/{6c2c945e.8d81f8ac.js => 6c2c945e.862df09c.js} (96%) rename assets/js/{6dbf0c72.35b92468.js => 6dbf0c72.b0ea4037.js} (98%) rename assets/js/{6fd5962d.7e0ea864.js => 6fd5962d.5c196d2d.js} (97%) rename assets/js/{7025ba4c.8368bd23.js => 7025ba4c.0c22071e.js} (92%) rename assets/js/{7090f9b2.d0ec26df.js => 7090f9b2.df5fe2d3.js} (99%) rename assets/js/{72396408.006643f2.js => 72396408.7ee7a8ef.js} (99%) rename assets/js/{75eb5a4f.c12bb331.js => 75eb5a4f.ae69c3b7.js} (99%) rename assets/js/{784e7414.b565e908.js => 784e7414.937fd63a.js} (99%) rename assets/js/{787d7fb8.af08c090.js => 787d7fb8.42860fa1.js} (92%) rename assets/js/{7b06cd29.3278c6f7.js => 7b06cd29.94356888.js} (76%) rename assets/js/{7c37f8e3.574eabce.js => 7c37f8e3.3f081d5a.js} (99%) rename assets/js/{7c5958d5.62039be9.js => 7c5958d5.f41855b4.js} (99%) rename assets/js/{82d092aa.594fe4c5.js => 82d092aa.0b06be92.js} (99%) rename assets/js/{86efd642.8d941507.js => 86efd642.6a156908.js} (98%) rename assets/js/{875538c7.77ddfe84.js => 875538c7.aabb66de.js} (98%) rename assets/js/{886a18c9.94b533f0.js => 886a18c9.f24fec95.js} (97%) rename assets/js/{88dceeee.e6db4e43.js => 88dceeee.116c7225.js} (97%) rename assets/js/{8983d6fd.7918bdd0.js => 8983d6fd.aa48a40c.js} (99%) rename assets/js/{898c1172.32d6f27c.js => 898c1172.a3c1ef0b.js} (98%) rename assets/js/{8b4e067a.12845ce8.js => 8b4e067a.94018ee3.js} (99%) create mode 100644 assets/js/8e0c7ef4.0de78cf1.js rename assets/js/{8e9b832c.de981826.js => 8e9b832c.ec90488d.js} (98%) rename assets/js/{91ffdcc4.9b7dd06d.js => 91ffdcc4.39f654d1.js} (98%) delete mode 100644 assets/js/935f2afb.728ee181.js create mode 100644 assets/js/935f2afb.85ff5c3f.js rename assets/js/{953b6178.de2c613f.js => 953b6178.85b49e63.js} (99%) create mode 100644 assets/js/97432a9d.a5d6aa4f.js rename assets/js/{97a2e26d.308fdd81.js => 97a2e26d.39189474.js} (98%) rename assets/js/{9d9f2427.f9d0c3ac.js => 9d9f2427.9f3acff4.js} (99%) rename assets/js/{9ea01397.4486851f.js => 9ea01397.09f06f51.js} (98%) rename assets/js/{9eb34096.1135e618.js => 9eb34096.315e1a1e.js} (97%) rename assets/js/{9f891c7e.b37f7393.js => 9f891c7e.020af191.js} (98%) rename assets/js/{9ffe69e6.b9045aed.js => 9ffe69e6.098f3116.js} (97%) rename assets/js/{a10857e0.cf88c5dc.js => a10857e0.2765861b.js} (96%) rename assets/js/{a1607c93.2ce0041a.js => a1607c93.592c16c5.js} (99%) rename assets/js/{a4c92b3a.2a762624.js => a4c92b3a.e8c77d0a.js} (96%) rename assets/js/{a578543f.afe24c3f.js => a578543f.db185869.js} (98%) rename assets/js/{a6153640.7966050c.js => a6153640.d38feca4.js} (98%) rename assets/js/{a9c7c7cb.b69ba5b0.js => a9c7c7cb.dd54e147.js} (96%) rename assets/js/{ae345ca5.f69a5f4d.js => ae345ca5.82dc3682.js} (94%) create mode 100644 assets/js/afa31ce4.dabeed25.js rename assets/js/{afb56169.81d2a64a.js => afb56169.8e9ed8b6.js} (99%) rename assets/js/{afc16f56.29139edf.js => afc16f56.a363ca31.js} (96%) rename assets/js/{b345aa24.c935c2c8.js => b345aa24.4d2623c1.js} (99%) rename assets/js/{ba98d35f.30abdf38.js => ba98d35f.e661451f.js} (99%) rename assets/js/{bbabf226.3d931823.js => bbabf226.9aeeb1fc.js} (99%) rename assets/js/{bc7830f0.04c4aa4d.js => bc7830f0.8f670026.js} (98%) rename assets/js/{bd8099e9.fb8453bc.js => bd8099e9.e770b661.js} (98%) rename assets/js/{bdc86f32.b25f8d20.js => bdc86f32.bdf7537c.js} (98%) rename assets/js/{be821a0f.130bd480.js => be821a0f.d528cd62.js} (98%) rename assets/js/{bf4e7b7d.92289f94.js => bf4e7b7d.9100a801.js} (98%) rename assets/js/{bfe734e5.499cb6fc.js => bfe734e5.592693f5.js} (97%) rename assets/js/{c0877fcf.04ab2026.js => c0877fcf.8f21c08c.js} (99%) rename assets/js/{c1edf8ce.5ea164eb.js => c1edf8ce.adeae358.js} (95%) rename assets/js/{c62e4ef9.c56db97c.js => c62e4ef9.8745fbf8.js} (98%) rename assets/js/{c9b0b07d.2cdc4432.js => c9b0b07d.15dce6cd.js} (96%) rename assets/js/{c9c542e7.79802b73.js => c9c542e7.1c6576f2.js} (98%) rename assets/js/{ce6d6ae6.7828eb06.js => ce6d6ae6.582d4679.js} (99%) rename assets/js/{d1b6879e.98e89b26.js => d1b6879e.b9db55cf.js} (99%) rename assets/js/{d317a52a.1a58b68f.js => d317a52a.c85ed09f.js} (98%) rename assets/js/{d7494416.ac5d9421.js => d7494416.9e056598.js} (87%) rename assets/js/{d9adfd98.bb2db584.js => d9adfd98.103f8afc.js} (99%) rename assets/js/{ddd36f18.25929b3d.js => ddd36f18.e39e26be.js} (98%) rename assets/js/{e33b593b.e5d7a2e8.js => e33b593b.a3faab74.js} (98%) rename assets/js/{e4badc61.3c37e33c.js => e4badc61.a6d7b905.js} (99%) rename assets/js/{e89e623e.d9f9176b.js => e89e623e.b1a19113.js} (99%) rename assets/js/{e9042e9e.fa4f6772.js => e9042e9e.be819edf.js} (98%) rename assets/js/{ea293640.2f5f07a5.js => ea293640.e12306b4.js} (98%) rename assets/js/{eba11d1f.554f036a.js => eba11d1f.90af8697.js} (98%) rename assets/js/{efecaa6d.4f8a9b3f.js => efecaa6d.dd8d51d6.js} (99%) rename assets/js/{f2ae0f53.1ebd8408.js => f2ae0f53.d2a53694.js} (97%) rename assets/js/{f558d87a.07d336f0.js => f558d87a.250eedc6.js} (98%) rename assets/js/{f7709bf7.2d3d2403.js => f7709bf7.9fc8db2a.js} (99%) delete mode 100644 assets/js/main.16c1522b.js create mode 100644 assets/js/main.eff93a2a.js rename assets/js/{main.16c1522b.js.LICENSE.txt => main.eff93a2a.js.LICENSE.txt} (100%) create mode 100644 assets/js/runtime~main.95fd9271.js delete mode 100644 assets/js/runtime~main.b4c4f126.js create mode 100644 docs/develop/opendid/advanced/index.html create mode 100644 docs/develop/opendid/demo_project/index.html create mode 100644 docs/develop/opendid/flow/index.html create mode 100644 docs/develop/opendid/integrate_opendid/index.html create mode 100644 docs/develop/opendid/opendid_service/index.html create mode 100644 docs/develop/opendid/what-is-opendid/index.html diff --git a/404.html b/404.html index 227518364..4e8f13127 100644 --- a/404.html +++ b/404.html @@ -4,10 +4,10 @@ Page Not Found | KILT Protocol - - + + -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/assets/js/021c8c02.143c9373.js b/assets/js/021c8c02.6fca3a8c.js similarity index 98% rename from assets/js/021c8c02.143c9373.js rename to assets/js/021c8c02.6fca3a8c.js index 9121c3985..507095f03 100644 --- a/assets/js/021c8c02.143c9373.js +++ b/assets/js/021c8c02.6fca3a8c.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5584],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},35828:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>d,default:()=>f,frontMatter:()=>c,metadata:()=>h,toc:()=>u});var i=n(17624),a=n(4552),s=n(96020),r=n(61268),o=n(87768);const l="import { config as envConfig } from 'dotenv'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\nimport { generateAccount } from './generateAccount'\nimport { generateCredential } from '../claimer/generateCredential'\nimport { generateKeypairs } from './generateKeypairs'\nimport { generateLightDid } from '../claimer/generateLightDid'\n\nexport async function attestCredential(\n attesterAccount: Kilt.KiltKeyringPair,\n attesterDid: Kilt.DidUri,\n credential: Kilt.ICredential\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Get CType and root hash from the provided credential.\n const { cTypeHash, claimHash } = Kilt.Attestation.fromCredentialAndDid(\n credential,\n attesterDid\n )\n\n // Create the tx and authorize it.\n const tx = api.tx.attestation.add(claimHash, cTypeHash, null)\n const extrinsic = api.tx.did.dispatchAs(attesterAccount.address, tx)\n\n // Submit the tx to write the attestation to the chain.\n console.log('Attester -> create attestation...')\n await Kilt.Blockchain.signAndSubmitTx(extrinsic, attesterAccount)\n}\n\nexport async function attestingFlow(\n claimerDid: Kilt.DidUri,\n attesterAccount: Kilt.KiltKeyringPair,\n attesterDid: Kilt.DidUri,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n // First the claimer.\n const credential = generateCredential(claimerDid, {\n age: 27,\n name: 'Mia Musterfrau'\n })\n\n // ... send the request to the attester\n\n // The attester checks the attributes and attests the provided credential.\n await attestCredential(attesterAccount, attesterDid, credential)\n\n // Return the generated credential.\n return credential\n}\n\n// Don't execute if this is imported by another file.\nif (require.main === module) {\n ;(async () => {\n envConfig()\n\n try {\n await Kilt.connect(process.env.WSS_ADDRESS as string)\n\n const attesterAccountMnemonic = process.env\n .ATTESTER_ACCOUNT_MNEMONIC as string\n const { account: attesterAccount } = generateAccount(\n attesterAccountMnemonic\n )\n\n const attesterDidMnemonic = process.env.ATTESTER_DID_MNEMONIC as string\n const { authentication, assertionMethod } =\n generateKeypairs(attesterDidMnemonic)\n const attesterDidUri = Kilt.Did.getFullDidUriFromKey(authentication)\n\n const claimerDidMnemonic = process.env.CLAIMER_DID_MNEMONIC as string\n const claimerDid = await generateLightDid(claimerDidMnemonic)\n\n const credential = await attestingFlow(\n claimerDid.uri,\n attesterAccount,\n attesterDidUri,\n async ({ data }) => ({\n signature: assertionMethod.sign(data),\n keyType: assertionMethod.type\n })\n )\n console.log('The claimer build their credential and now has to store it.')\n console.log('Add the following to your .env file. ')\n console.log(`CLAIMER_CREDENTIAL='${JSON.stringify(credential)}'`)\n } catch (e) {\n console.log('Error while going throw attesting workflow')\n throw e\n }\n })()\n}\n",c={id:"attestation",title:"\ud83e\uddfe Attestation"},d=void 0,h={id:"develop/workshop/attestation",title:"\ud83e\uddfe Attestation",description:"This section covers how the Attester receives and processes a Credential and how you can:",source:"@site/docs/develop/03_workshop/06_attestation.md",sourceDirName:"develop/03_workshop",slug:"/develop/workshop/attestation",permalink:"/docs/develop/workshop/attestation",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/03_workshop/06_attestation.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:6,frontMatter:{id:"attestation",title:"\ud83e\uddfe Attestation"},sidebar:"workshop",previous:{title:"Request an Attestation",permalink:"/docs/develop/workshop/claimer/request"},next:{title:"\ud83e\udd1d Verification",permalink:"/docs/develop/workshop/verification"}},p={},u=[{value:"Attest a Credential",id:"attest-a-credential",level:2},{value:"Run",id:"run",level:2},{value:"Summary",id:"summary",level:2}];function m(e){const t={code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["This section covers how the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," receives and processes a ",(0,i.jsx)(t.code,{children:"Credential"})," and how you can:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Attest or deny it"}),"\n",(0,i.jsx)(t.li,{children:"Store the attestation information on the chain"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"attest-a-credential",children:"Attest a Credential"}),"\n",(0,i.jsx)(s.c,{fileName:"attester/attestCredential",children:l}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"attestCredential"})," function loads the account and DID of the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," and issues an attestation for the credential received from the ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"}),".\nThe credential is valid from the time an Attester attests it on chain until the time it is revoked."]}),"\n",(0,i.jsxs)(t.p,{children:["In the ",(0,i.jsx)(t.code,{children:"attestingFlow"})," function, the ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"})," generates the demo credential and sends it to the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"}),".\nThe ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," checks the attributes and either attests or denies the attestation if the attributes are invalid.\nOnce the attestation is written on the chain, the Attester can share all or part of the attested credentials with verifiers."]}),"\n",(0,i.jsx)(t.h2,{id:"run",children:"Run"}),"\n",(0,i.jsx)(t.p,{children:"Run the code from the command line:"}),"\n",(0,i.jsxs)(r.c,{groupId:"ts-js-choice",children:[(0,i.jsx)(o.c,{value:"ts",label:"Typescript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"yarn ts-node attester/attestCredential.ts\n"})})}),(0,i.jsx)(o.c,{value:"js",label:"Javascript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"node attester/attestCredential.js\n"})})})]}),"\n",(0,i.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,i.jsxs)(t.p,{children:["Your job as an ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," is complete. You've attested a credential and written the attestation hash onto the chain."]}),"\n",(0,i.jsx)(t.p,{children:"Let's move on to set up the Verifier!"})]})}function f(e={}){const{wrapper:t}={...(0,a.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(m,{...e})}):m(e)}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>u});var i=n(11504),a=n(28264),s=n(46352),r=n(58440),o=n(14300),l=n(28168),c=n(61268),d=n(87768),h=n(1608),p=n(17624);const u=e=>{let{children:t,fileName:n,...u}=e;const m=t,[f,g]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:v}}}=(0,a.c)(),x=(0,i.useMemo)((()=>{const{code:e}=(0,s.transform)(m,{plugins:["transform-typescript"],retainLines:!0});return e}),[m]);(0,i.useEffect)((()=>{r.E9(x,{parser:"babel",plugins:[o.c,l.cp],...v}).then(g)}),[v,x]);const j=[{fileName:n?`${n}.ts`:void 0,fileContents:m,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:f,fileID:"js",fileLabel:"Javascript"}];return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)(c.c,{groupId:"ts-js-choice",children:j.map((e=>(0,p.jsx)(d.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,p.jsx)(h.c,{...u,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5584],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},35828:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>d,default:()=>f,frontMatter:()=>c,metadata:()=>h,toc:()=>u});var i=n(17624),a=n(4552),s=n(96020),r=n(61268),o=n(87768);const l="import { config as envConfig } from 'dotenv'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\nimport { generateAccount } from './generateAccount'\nimport { generateCredential } from '../claimer/generateCredential'\nimport { generateKeypairs } from './generateKeypairs'\nimport { generateLightDid } from '../claimer/generateLightDid'\n\nexport async function attestCredential(\n attesterAccount: Kilt.KiltKeyringPair,\n attesterDid: Kilt.DidUri,\n credential: Kilt.ICredential\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Get CType and root hash from the provided credential.\n const { cTypeHash, claimHash } = Kilt.Attestation.fromCredentialAndDid(\n credential,\n attesterDid\n )\n\n // Create the tx and authorize it.\n const tx = api.tx.attestation.add(claimHash, cTypeHash, null)\n const extrinsic = api.tx.did.dispatchAs(attesterAccount.address, tx)\n\n // Submit the tx to write the attestation to the chain.\n console.log('Attester -> create attestation...')\n await Kilt.Blockchain.signAndSubmitTx(extrinsic, attesterAccount)\n}\n\nexport async function attestingFlow(\n claimerDid: Kilt.DidUri,\n attesterAccount: Kilt.KiltKeyringPair,\n attesterDid: Kilt.DidUri,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n // First the claimer.\n const credential = generateCredential(claimerDid, {\n age: 27,\n name: 'Mia Musterfrau'\n })\n\n // ... send the request to the attester\n\n // The attester checks the attributes and attests the provided credential.\n await attestCredential(attesterAccount, attesterDid, credential)\n\n // Return the generated credential.\n return credential\n}\n\n// Don't execute if this is imported by another file.\nif (require.main === module) {\n ;(async () => {\n envConfig()\n\n try {\n await Kilt.connect(process.env.WSS_ADDRESS as string)\n\n const attesterAccountMnemonic = process.env\n .ATTESTER_ACCOUNT_MNEMONIC as string\n const { account: attesterAccount } = generateAccount(\n attesterAccountMnemonic\n )\n\n const attesterDidMnemonic = process.env.ATTESTER_DID_MNEMONIC as string\n const { authentication, assertionMethod } =\n generateKeypairs(attesterDidMnemonic)\n const attesterDidUri = Kilt.Did.getFullDidUriFromKey(authentication)\n\n const claimerDidMnemonic = process.env.CLAIMER_DID_MNEMONIC as string\n const claimerDid = await generateLightDid(claimerDidMnemonic)\n\n const credential = await attestingFlow(\n claimerDid.uri,\n attesterAccount,\n attesterDidUri,\n async ({ data }) => ({\n signature: assertionMethod.sign(data),\n keyType: assertionMethod.type\n })\n )\n console.log('The claimer build their credential and now has to store it.')\n console.log('Add the following to your .env file. ')\n console.log(`CLAIMER_CREDENTIAL='${JSON.stringify(credential)}'`)\n } catch (e) {\n console.log('Error while going throw attesting workflow')\n throw e\n }\n })()\n}\n",c={id:"attestation",title:"\ud83e\uddfe Attestation"},d=void 0,h={id:"develop/workshop/attestation",title:"\ud83e\uddfe Attestation",description:"This section covers how the Attester receives and processes a Credential and how you can:",source:"@site/docs/develop/03_workshop/06_attestation.md",sourceDirName:"develop/03_workshop",slug:"/develop/workshop/attestation",permalink:"/docs/develop/workshop/attestation",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/03_workshop/06_attestation.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:6,frontMatter:{id:"attestation",title:"\ud83e\uddfe Attestation"},sidebar:"workshop",previous:{title:"Request an Attestation",permalink:"/docs/develop/workshop/claimer/request"},next:{title:"\ud83e\udd1d Verification",permalink:"/docs/develop/workshop/verification"}},p={},u=[{value:"Attest a Credential",id:"attest-a-credential",level:2},{value:"Run",id:"run",level:2},{value:"Summary",id:"summary",level:2}];function m(e){const t={code:"code",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["This section covers how the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," receives and processes a ",(0,i.jsx)(t.code,{children:"Credential"})," and how you can:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Attest or deny it"}),"\n",(0,i.jsx)(t.li,{children:"Store the attestation information on the chain"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"attest-a-credential",children:"Attest a Credential"}),"\n",(0,i.jsx)(s.c,{fileName:"attester/attestCredential",children:l}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"attestCredential"})," function loads the account and DID of the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," and issues an attestation for the credential received from the ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"}),".\nThe credential is valid from the time an Attester attests it on chain until the time it is revoked."]}),"\n",(0,i.jsxs)(t.p,{children:["In the ",(0,i.jsx)(t.code,{children:"attestingFlow"})," function, the ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"})," generates the demo credential and sends it to the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"}),".\nThe ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," checks the attributes and either attests or denies the attestation if the attributes are invalid.\nOnce the attestation is written on the chain, the Attester can share all or part of the attested credentials with verifiers."]}),"\n",(0,i.jsx)(t.h2,{id:"run",children:"Run"}),"\n",(0,i.jsx)(t.p,{children:"Run the code from the command line:"}),"\n",(0,i.jsxs)(r.c,{groupId:"ts-js-choice",children:[(0,i.jsx)(o.c,{value:"ts",label:"Typescript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"yarn ts-node attester/attestCredential.ts\n"})})}),(0,i.jsx)(o.c,{value:"js",label:"Javascript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"node attester/attestCredential.js\n"})})})]}),"\n",(0,i.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,i.jsxs)(t.p,{children:["Your job as an ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," is complete. You've attested a credential and written the attestation hash onto the chain."]}),"\n",(0,i.jsx)(t.p,{children:"Let's move on to set up the Verifier!"})]})}function f(e={}){const{wrapper:t}={...(0,a.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(m,{...e})}):m(e)}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>u});var i=n(11504),a=n(28264),s=n(46352),r=n(58440),o=n(14300),l=n(28168),c=n(61268),d=n(87768),h=n(1608),p=n(17624);const u=e=>{let{children:t,fileName:n,...u}=e;const m=t,[f,g]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:v}}}=(0,a.c)(),x=(0,i.useMemo)((()=>{const{code:e}=(0,s.transform)(m,{plugins:["transform-typescript"],retainLines:!0});return e}),[m]);(0,i.useEffect)((()=>{r.E9(x,{parser:"babel",plugins:[o.c,l.cp],...v}).then(g)}),[v,x]);const j=[{fileName:n?`${n}.ts`:void 0,fileContents:m,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:f,fileID:"js",fileLabel:"Javascript"}];return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)(c.c,{groupId:"ts-js-choice",children:j.map((e=>(0,p.jsx)(d.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,p.jsx)(h.c,{...u,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/03ee7140.9f4ed2b5.js b/assets/js/03ee7140.9f4ed2b5.js new file mode 100644 index 000000000..817d18cfe --- /dev/null +++ b/assets/js/03ee7140.9f4ed2b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5028],{98800:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>a,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var t=i(17624),d=i(4552);const o={id:"integrate_opendid",title:"Integrate OpenDID"},c=void 0,l={id:"develop/opendid/integrate_opendid",title:"Integrate OpenDID",description:"OpenDID follows the OpenID Connect 1.0 Specification and implements both the implicit flow",source:"@site/docs/develop/08_opendid/04_integrate_opendid.md",sourceDirName:"develop/08_opendid",slug:"/develop/opendid/integrate_opendid",permalink:"/docs/develop/opendid/integrate_opendid",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/08_opendid/04_integrate_opendid.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:4,frontMatter:{id:"integrate_opendid",title:"Integrate OpenDID"},sidebar:"opendid",previous:{title:"Run OpenDID Service",permalink:"/docs/develop/opendid/opendid_service"},next:{title:"Demo Project",permalink:"/docs/develop/opendid/demo_project"}},r={},s=[{value:"Authorization code flow",id:"authorization-code-flow",level:2},{value:"Implicit flow",id:"implicit-flow",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,d.M)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["OpenDID follows the ",(0,t.jsx)(n.a,{href:"https://openid.net/specs/openid-connect-core-1_0.html#Introduction",children:"OpenID Connect 1.0 Specification"})," and implements both the ",(0,t.jsx)(n.a,{href:"https://openid.net/specs/openid-connect-core-1_0.html#ImplicitFlowSteps",children:"implicit flow"}),"\nand the ",(0,t.jsx)(n.a,{href:"https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth",children:"authorization code flow"}),".\nRead the ",(0,t.jsx)(n.a,{href:"/docs/develop/opendid/demo_project",children:"demo project guide"})," for an example of integrating OpenDID."]}),"\n",(0,t.jsx)(n.h2,{id:"authorization-code-flow",children:"Authorization code flow"}),"\n",(0,t.jsxs)(n.p,{children:["Initiate the flow by redirecting to the ",(0,t.jsx)(n.strong,{children:"GET"})," ",(0,t.jsx)(n.code,{children:"/api/v1/authorize"})," endpoint on the OpenDID service and setting the following query URL-encoded parameters:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"response_type"}),": set value to ",(0,t.jsx)(n.code,{children:"code"})," to indicate Authorization Code Flow."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"client_id"}),": The client ID set in the ",(0,t.jsx)(n.code,{children:"config.yaml"})," file."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"redirect_uri"}),": OpenDID redirects to this URL after authentication."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"scope"}),": set value to ",(0,t.jsx)(n.code,{children:"openid"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"state"}),": set to a secure random number."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"nonce"}),": optional value, set to a secure random number."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"GET /api/v1/authorize?\n response_type=code&\n client_id=example-client&\n redirect_uri=http://localhost:1606/callback.html&\n scope=openid&\n state=rkw49cbvd4azu5dsln1xbl&\n nonce=vedur4om49ei8w91jt7wt HTTP/1.1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After successful authentication, the OpenDID service redirects back to the provided ",(0,t.jsx)(n.code,{children:"redirect_uri"})," with ",(0,t.jsx)(n.code,{children:"code"})," and ",(0,t.jsx)(n.code,{children:"state"})," query parameters."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"/callback.html?\n code=lwDS1ZpQBwR4Vdm53_L8bWpUJ1mx9A0mA_-86dubTqzqzwGazx1RyLX4Z_qf&\n state=rkw49cbvd4azu5dsln1xbl\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can retrieve the ",(0,t.jsx)(n.code,{children:"id_token"})," by calling the ",(0,t.jsx)(n.strong,{children:"POST"})," ",(0,t.jsx)(n.code,{children:"/api/v1/token"})," and providing the following values in the form serialization:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"code"}),": code value returned from ",(0,t.jsx)(n.code,{children:"authorize"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"grant_type"}),": set value to ",(0,t.jsx)(n.code,{children:"authorization_code"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"redirect_uri"}),": the same ",(0,t.jsx)(n.code,{children:"redirect_uri"})," used in ",(0,t.jsx)(n.code,{children:"authorize"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"client_id"}),": the client ID set in the ",(0,t.jsx)(n.code,{children:"config.yaml"})," file."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"client_secret"}),": the client secret value set in the ",(0,t.jsx)(n.code,{children:"config.yaml"})," file."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"POST /api/v1/token HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\n\ncode=lwDS1ZpQBwR4Vdm53_L8bWpUJ1mx9A0mA_-86dubTqzqzwGazx1RyLX4Z_qf&\ngrant_type=authorization_code&\nredirect_uri=http%3A%2F%2Flocalhost%3A1606%2Fcallback.html&\nclient_id=example-client&\nclient_secret=insecure_client_secret\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The OpenDID service returns the ",(0,t.jsx)(n.code,{children:"id_token"})," in the response body serialized as a JSON object."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "access_token": "SsFhhSBMWsLeDMxVUVGreKARNwYxMZtGFfBr0-ZiH6iondSmwPRvQDqkG6Fh",\n "token_type": "bearer",\n "refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4MTYwNjQsImlhdCI6MTcxNjgxNTQ2NCwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXV0aGVudGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoidmVkdXI0b200OWVpOHc5MWp0N3d0In0.yOmE_9jWKcAu8LpjVx7IsFyOOvlKbgo2oC4Imf-qrLY",\n "id_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4MTU1MjQsImlhdCI6MTcxNjgxNTQ2NCwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXBwbGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoidmVkdXI0b200OWVpOHc5MWp0N3d0In0.YlRE9EGnSExQCb5m2iy4__58PZJlZdCZMsSvsuW4oj8"\n}\n'})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["In full-stack applications, calling the ",(0,t.jsx)(n.code,{children:"token"})," endpoint is usually done through the back end to improve security."]})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"id_token"})," is a bearer JSON web token (JWT) signed by the JWT key-pair specified in the ",(0,t.jsx)(n.code,{children:"config.yaml"})," file of the OpenDID service.\nYou must verify this using the JWT public key, for example, by the back end of the Web app."]}),"\n",(0,t.jsx)(n.h2,{id:"implicit-flow",children:"Implicit flow"}),"\n",(0,t.jsxs)(n.p,{children:["Initiate the flow by redirecting to the ",(0,t.jsx)(n.strong,{children:"GET"})," ",(0,t.jsx)(n.code,{children:"/api/v1/authorize"})," endpoint on the OpenDID Service and setting the following query parameters:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"response_type"}),": set value to ",(0,t.jsx)(n.code,{children:"id_token"})," to indicate Implicit Flow."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"client_id"}),": The client ID set in the config.yaml file."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"redirect_uri"}),": OpenDID redirects to this URL after authentication."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"scope"}),": set value to ",(0,t.jsx)(n.code,{children:"openid"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"state"}),": set to a secure random number."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"nonce"}),": optional value, set to a secure random number."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"GET /api/v1/authorize?\n response_type=id_token&\n client_id=example-client&\n redirect_uri=http://localhost:1606/callback.html&\n scope=openid&\n state=o0fl4c9gwylymzw5f4ik&\n nonce=ia7sa06ungxdfzaqphk2 HTTP/1.1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["After successful authentication, OpenDID redirects back to the provided ",(0,t.jsx)(n.code,{children:"redirect_uri"})," with ",(0,t.jsx)(n.code,{children:"id_token"})," and ",(0,t.jsx)(n.code,{children:"state"}),"\n",(0,t.jsx)(n.strong,{children:"fragment components"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"/callback.html#\n id_token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4ODQ5MDYsImlhdCI6MTcxNjg4NDg0NiwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXBwbGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoiOTFzN2ZnZDZvcjR3c2NkdGVtcXQifQ.xTy3Oyc5e-vlP10mGy0f9GqNU4LV97s77s-l7w5EwF0&\n refresh_token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4ODU0NDYsImlhdCI6MTcxNjg4NDg0NiwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXV0aGVudGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoiOTFzN2ZnZDZvcjR3c2NkdGVtcXQifQ.87UHGid3OotxO8Wpfuw-1sc5fsQJVt5gc2cqp9dVHiw&\n state=nitctpl7nmqcpvob7xthrw&\n token_type=bearer\n"})})]})}function a(e={}){const{wrapper:n}={...(0,d.M)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},4552:(e,n,i)=>{i.d(n,{I:()=>l,M:()=>c});var t=i(11504);const d={},o=t.createContext(d);function c(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:c(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05485178.ebc72665.js b/assets/js/05485178.4426cb50.js similarity index 98% rename from assets/js/05485178.ebc72665.js rename to assets/js/05485178.4426cb50.js index f21bd8aa6..37b7a8915 100644 --- a/assets/js/05485178.ebc72665.js +++ b/assets/js/05485178.4426cb50.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2612],{22556:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var i=n(17624),o=n(4552),s=n(77440);const a={id:"exit",title:"Leave the Collator Candidate Pool"},c=void 0,r={id:"participate/staking/advanced_collator_section/exit",title:"Leave the Collator Candidate Pool",description:"If you intend to stop collating or stop being a collator candidate, you have to go through three stages until your staked tokens are unlocked and your collator state is purged from the chain.",source:"@site/docs/participate/01_staking/02_advanced_collator_section/02_exit.md",sourceDirName:"participate/01_staking/02_advanced_collator_section",slug:"/participate/staking/advanced_collator_section/exit",permalink:"/docs/participate/staking/advanced_collator_section/exit",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/02_advanced_collator_section/02_exit.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:2,frontMatter:{id:"exit",title:"Leave the Collator Candidate Pool"},sidebar:"staking",previous:{title:"Adjust Your Own Stake",permalink:"/docs/participate/staking/advanced_collator_section/adjust-stake"},next:{title:"Lifecycle of a Collator",permalink:"/docs/participate/staking/advanced_collator_section/lifecycle"}},l={},d=[{value:"Initiate the Exit Request",id:"initiate-the-exit-request",level:2},{value:"Execute the Exit Request",id:"execute-the-exit-request",level:2},{value:"Cancel the Exit Request",id:"cancel-the-exit-request",level:2},{value:"Unlock Your Stake",id:"unlock-your-stake",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,o.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"If you intend to stop collating or stop being a collator candidate, you have to go through three stages until your staked tokens are unlocked and your collator state is purged from the chain."}),"\n",(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["Unfortunately, exiting is not a simple process for security reasons.\nSince a picture paints a thousand words, you can find a visualization of this process in the following ",(0,i.jsx)(t.a,{href:"/docs/participate/staking/advanced_collator_section/lifecycle",children:(0,i.jsx)(t.strong,{children:"lifecycle section"})}),"."]})}),"\n",(0,i.jsx)(t.h2,{id:"initiate-the-exit-request",children:"Initiate the Exit Request"}),"\n",(0,i.jsxs)(t.p,{children:["First, signal your intent by calling ",(0,i.jsx)(t.code,{children:"parachainStaking -> initLeaveCandidates"}),".\nYou will then be removed from the ",(0,i.jsx)(t.code,{children:"CandidatePool"})," and your state switches from ",(0,i.jsx)(t.code,{children:"Active"})," to ",(0,i.jsx)(t.code,{children:"Leaving(leaveRound)"}),", where ",(0,i.jsx)(t.code,{children:"leaveRound"})," reflects the number of sessions that have to elapse before you can definitely leave the set of collators.\nYou still need to stay online and build blocks for the current and next sessions.\nSince each session lasts 2 hours, ",(0,i.jsx)(t.strong,{children:"the maximum amount of time you will need to wait is 4 hours"}),".\nOf course, you will continue to receive rewards for the blocks your collating node will author.\nA leaving candidate cannot be selected as an active collator for the sessions from this point on.\nMoreover, you cannot receive new delegations and existing delegations cannot be adjusted.\nHowever, delegations can still be revoked."]}),"\n",(0,i.jsx)(s.cp,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(85512).c+"",width:"2000",height:"932"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Select your collator KILT address as the extrinsic submitter (the ",(0,i.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,i.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,i.jsx)(t.code,{children:"parachainStaking -> initLeaveCandidates"})]}),"\n",(0,i.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,i.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"execute-the-exit-request",children:"Execute the Exit Request"}),"\n",(0,i.jsxs)(t.p,{children:["Once the current and next sessions have elapsed (which can take at most 4 hours), you can call ",(0,i.jsx)(t.code,{children:"executeLeaveCandidate"})," to remove all of your ",(0,i.jsx)(t.code,{children:"Candidate"})," associated storage.\nYou should be certain that you wish to leave as there is no turning back afterwards.\nIf you wish to become a candidate at a later stage, you will have to apply again and will not have your former delegations."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(65004).c+"",width:"2012",height:"1192"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Select one of your KILT addresses with sufficient funds to pay for the transaction fee (~5 milli KILT) as the extrinsic submitter (the ",(0,i.jsx)(t.em,{children:"using the selected account"})," field)\n",(0,i.jsx)(t.em,{children:"NOTE: Of course, you can chose your collator account."})]}),"\n",(0,i.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,i.jsx)(t.code,{children:"parachainStaking -> executeLeaveCandidates"})]}),"\n",(0,i.jsxs)(t.li,{children:["Select the ",(0,i.jsx)(t.code,{children:"Id"})," option (the ",(0,i.jsx)(t.em,{children:"MultiAddress (LookupSource) field"}),")"]}),"\n",(0,i.jsxs)(t.li,{children:["Select the collator account (the ",(0,i.jsx)(t.em,{children:"Id: AccountId"})," field)"]}),"\n",(0,i.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,i.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"cancel-the-exit-request",children:"Cancel the Exit Request"}),"\n",(0,i.jsxs)(t.p,{children:["You still have not completed your exit request, you can still cancel it by calling ",(0,i.jsx)(t.code,{children:"cancelLeaveCandidates"}),", which will succeed if the ",(0,i.jsx)(t.code,{children:"CandidatePool"})," is not already full.\nUpon interruption of your exit procedure, your state switches back to ",(0,i.jsx)(t.code,{children:"Active"})," and you maintain all the previous delegations, since everything has remained untouched in the meantime.\nMoreover, if you are one of the top staked candidates, you will automatically become a collator again at the end of the second round from this point, which can take as long as 4 hours in the worst case."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(46428).c+"",width:"2000",height:"934"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Select your collator KILT address as the extrinsic submitter (the ",(0,i.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,i.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,i.jsx)(t.code,{children:"parachainStaking -> cancelLeaveCandidates"})]}),"\n",(0,i.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,i.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"unlock-your-stake",children:"Unlock Your Stake"}),"\n",(0,i.jsxs)(t.p,{children:["If you have executed the exit request you cannot immediately unlock your previously staked tokens.\nThere is a delay of 7 days in block time before you can free them by calling ",(0,i.jsx)(t.code,{children:"unlockUnstaked"}),".\nSee ",(0,i.jsx)(t.a,{href:"/docs/participate/staking/unlock-unstaked",children:"here"})," for a step-by-step tutorial."]})]})}function u(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},77440:(e,t,n)=>{n.d(t,{cp:()=>a});var i=n(17624),o=n(4552);function s(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",strong:"strong",...(0,o.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["You can either execute this transaction in Polkadot JS Apps or the ",(0,i.jsx)(t.a,{href:"/docs/develop/builtonkilt#web-apps",children:(0,i.jsx)(t.strong,{children:"KILT Stakeboard"})}),", which serves as an in-house developed Frontend for all KILT staking activity.\nBelow, we outline the steps for Polkadot JS Apps.\nThe process for KILT Stakeboard is described in detail in the ",(0,i.jsx)(t.a,{href:"https://support.kilt.io/support/solutions/80000442174",children:(0,i.jsx)(t.strong,{children:"BOTLabs Trusted Entity support hub"})}),"."]})}),"\n",(0,i.jsxs)(t.p,{children:["In the Polkadot JS Apps (",(0,i.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer",children:"wss://spiritnet.kilt.io"}),", or ",(0,i.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer",children:"wss://peregrine.kilt.io"}),") go to ",(0,i.jsx)(t.code,{children:"Developer -> Extrinsics -> Submission"}),"."]})]})}function a(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},46428:(e,t,n)=>{n.d(t,{c:()=>i});const i=n.p+"assets/images/parachainStaking-cancelLeaveCandidates-7dc88ad70b6b395e39189aee23201ba0.png"},65004:(e,t,n)=>{n.d(t,{c:()=>i});const i=n.p+"assets/images/parachainStaking-executeLeaveCandidates-549cdc719f2c60175061bc5b7aec6cdf.png"},85512:(e,t,n)=>{n.d(t,{c:()=>i});const i=n.p+"assets/images/parachainStaking-initLeaveCandidates-ab23450503d384e61292174bf839ecfe.png"},4552:(e,t,n)=>{n.d(t,{I:()=>c,M:()=>a});var i=n(11504);const o={},s=i.createContext(o);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2612],{22556:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var i=n(17624),o=n(4552),s=n(77440);const a={id:"exit",title:"Leave the Collator Candidate Pool"},c=void 0,r={id:"participate/staking/advanced_collator_section/exit",title:"Leave the Collator Candidate Pool",description:"If you intend to stop collating or stop being a collator candidate, you have to go through three stages until your staked tokens are unlocked and your collator state is purged from the chain.",source:"@site/docs/participate/01_staking/02_advanced_collator_section/02_exit.md",sourceDirName:"participate/01_staking/02_advanced_collator_section",slug:"/participate/staking/advanced_collator_section/exit",permalink:"/docs/participate/staking/advanced_collator_section/exit",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/02_advanced_collator_section/02_exit.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:2,frontMatter:{id:"exit",title:"Leave the Collator Candidate Pool"},sidebar:"staking",previous:{title:"Adjust Your Own Stake",permalink:"/docs/participate/staking/advanced_collator_section/adjust-stake"},next:{title:"Lifecycle of a Collator",permalink:"/docs/participate/staking/advanced_collator_section/lifecycle"}},l={},d=[{value:"Initiate the Exit Request",id:"initiate-the-exit-request",level:2},{value:"Execute the Exit Request",id:"execute-the-exit-request",level:2},{value:"Cancel the Exit Request",id:"cancel-the-exit-request",level:2},{value:"Unlock Your Stake",id:"unlock-your-stake",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,o.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"If you intend to stop collating or stop being a collator candidate, you have to go through three stages until your staked tokens are unlocked and your collator state is purged from the chain."}),"\n",(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["Unfortunately, exiting is not a simple process for security reasons.\nSince a picture paints a thousand words, you can find a visualization of this process in the following ",(0,i.jsx)(t.a,{href:"/docs/participate/staking/advanced_collator_section/lifecycle",children:(0,i.jsx)(t.strong,{children:"lifecycle section"})}),"."]})}),"\n",(0,i.jsx)(t.h2,{id:"initiate-the-exit-request",children:"Initiate the Exit Request"}),"\n",(0,i.jsxs)(t.p,{children:["First, signal your intent by calling ",(0,i.jsx)(t.code,{children:"parachainStaking -> initLeaveCandidates"}),".\nYou will then be removed from the ",(0,i.jsx)(t.code,{children:"CandidatePool"})," and your state switches from ",(0,i.jsx)(t.code,{children:"Active"})," to ",(0,i.jsx)(t.code,{children:"Leaving(leaveRound)"}),", where ",(0,i.jsx)(t.code,{children:"leaveRound"})," reflects the number of sessions that have to elapse before you can definitely leave the set of collators.\nYou still need to stay online and build blocks for the current and next sessions.\nSince each session lasts 2 hours, ",(0,i.jsx)(t.strong,{children:"the maximum amount of time you will need to wait is 4 hours"}),".\nOf course, you will continue to receive rewards for the blocks your collating node will author.\nA leaving candidate cannot be selected as an active collator for the sessions from this point on.\nMoreover, you cannot receive new delegations and existing delegations cannot be adjusted.\nHowever, delegations can still be revoked."]}),"\n",(0,i.jsx)(s.cp,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(85512).c+"",width:"2000",height:"932"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Select your collator KILT address as the extrinsic submitter (the ",(0,i.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,i.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,i.jsx)(t.code,{children:"parachainStaking -> initLeaveCandidates"})]}),"\n",(0,i.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,i.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"execute-the-exit-request",children:"Execute the Exit Request"}),"\n",(0,i.jsxs)(t.p,{children:["Once the current and next sessions have elapsed (which can take at most 4 hours), you can call ",(0,i.jsx)(t.code,{children:"executeLeaveCandidate"})," to remove all of your ",(0,i.jsx)(t.code,{children:"Candidate"})," associated storage.\nYou should be certain that you wish to leave as there is no turning back afterwards.\nIf you wish to become a candidate at a later stage, you will have to apply again and will not have your former delegations."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(65004).c+"",width:"2012",height:"1192"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Select one of your KILT addresses with sufficient funds to pay for the transaction fee (~5 milli KILT) as the extrinsic submitter (the ",(0,i.jsx)(t.em,{children:"using the selected account"})," field)\n",(0,i.jsx)(t.em,{children:"NOTE: Of course, you can chose your collator account."})]}),"\n",(0,i.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,i.jsx)(t.code,{children:"parachainStaking -> executeLeaveCandidates"})]}),"\n",(0,i.jsxs)(t.li,{children:["Select the ",(0,i.jsx)(t.code,{children:"Id"})," option (the ",(0,i.jsx)(t.em,{children:"MultiAddress (LookupSource) field"}),")"]}),"\n",(0,i.jsxs)(t.li,{children:["Select the collator account (the ",(0,i.jsx)(t.em,{children:"Id: AccountId"})," field)"]}),"\n",(0,i.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,i.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"cancel-the-exit-request",children:"Cancel the Exit Request"}),"\n",(0,i.jsxs)(t.p,{children:["You still have not completed your exit request, you can still cancel it by calling ",(0,i.jsx)(t.code,{children:"cancelLeaveCandidates"}),", which will succeed if the ",(0,i.jsx)(t.code,{children:"CandidatePool"})," is not already full.\nUpon interruption of your exit procedure, your state switches back to ",(0,i.jsx)(t.code,{children:"Active"})," and you maintain all the previous delegations, since everything has remained untouched in the meantime.\nMoreover, if you are one of the top staked candidates, you will automatically become a collator again at the end of the second round from this point, which can take as long as 4 hours in the worst case."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(46428).c+"",width:"2000",height:"934"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Select your collator KILT address as the extrinsic submitter (the ",(0,i.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,i.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,i.jsx)(t.code,{children:"parachainStaking -> cancelLeaveCandidates"})]}),"\n",(0,i.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,i.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"unlock-your-stake",children:"Unlock Your Stake"}),"\n",(0,i.jsxs)(t.p,{children:["If you have executed the exit request you cannot immediately unlock your previously staked tokens.\nThere is a delay of 7 days in block time before you can free them by calling ",(0,i.jsx)(t.code,{children:"unlockUnstaked"}),".\nSee ",(0,i.jsx)(t.a,{href:"/docs/participate/staking/unlock-unstaked",children:"here"})," for a step-by-step tutorial."]})]})}function u(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},77440:(e,t,n)=>{n.d(t,{cp:()=>a});var i=n(17624),o=n(4552);function s(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",strong:"strong",...(0,o.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["You can either execute this transaction in Polkadot JS Apps or the ",(0,i.jsx)(t.a,{href:"/docs/develop/builtonkilt#web-apps",children:(0,i.jsx)(t.strong,{children:"KILT Stakeboard"})}),", which serves as an in-house developed Frontend for all KILT staking activity.\nBelow, we outline the steps for Polkadot JS Apps.\nThe process for KILT Stakeboard is described in detail in the ",(0,i.jsx)(t.a,{href:"https://support.kilt.io/support/solutions/80000442174",children:(0,i.jsx)(t.strong,{children:"BOTLabs Trusted Entity support hub"})}),"."]})}),"\n",(0,i.jsxs)(t.p,{children:["In the Polkadot JS Apps (",(0,i.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer",children:"wss://spiritnet.kilt.io"}),", or ",(0,i.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer",children:"wss://peregrine.kilt.io"}),") go to ",(0,i.jsx)(t.code,{children:"Developer -> Extrinsics -> Submission"}),"."]})]})}function a(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(s,{...e})}):s(e)}},46428:(e,t,n)=>{n.d(t,{c:()=>i});const i=n.p+"assets/images/parachainStaking-cancelLeaveCandidates-7dc88ad70b6b395e39189aee23201ba0.png"},65004:(e,t,n)=>{n.d(t,{c:()=>i});const i=n.p+"assets/images/parachainStaking-executeLeaveCandidates-549cdc719f2c60175061bc5b7aec6cdf.png"},85512:(e,t,n)=>{n.d(t,{c:()=>i});const i=n.p+"assets/images/parachainStaking-initLeaveCandidates-ab23450503d384e61292174bf839ecfe.png"},4552:(e,t,n)=>{n.d(t,{I:()=>c,M:()=>a});var i=n(11504);const o={},s=i.createContext(o);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/076b4add.4823f7de.js b/assets/js/076b4add.9290b1f7.js similarity index 98% rename from assets/js/076b4add.4823f7de.js rename to assets/js/076b4add.9290b1f7.js index 412f26aa0..882793227 100644 --- a/assets/js/076b4add.4823f7de.js +++ b/assets/js/076b4add.9290b1f7.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2068],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},14548:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>h,toc:()=>p});var i=n(17624),s=n(4552),o=(n(1608),n(96020)),a=(n(73484),n(61268)),c=n(87768);const r="import * as Kilt from '@kiltprotocol/sdk-js'\nimport { config as envConfig } from 'dotenv'\nimport { generateAccount } from './generateAccount'\n\nexport async function createFullDid(\n creatorAccount: Kilt.KiltKeyringPair & {\n type: 'ed25519' | 'sr25519' | 'ecdsa'\n }\n): Promise<{\n fullDid: Kilt.DidDocument\n}> {\n const api = Kilt.ConfigService.get('api')\n\n const verificationMethod = Kilt.Did.publicKeyToChain(creatorAccount)\n\n const txs = [\n api.tx.did.createFromAccount(verificationMethod),\n api.tx.did.dispatchAs(\n creatorAccount.address,\n api.tx.did.setAttestationKey(verificationMethod)\n )\n ]\n\n console.log('Creating DID from account\u2026')\n await Kilt.Blockchain.signAndSubmitTx(\n api.tx.utility.batch(txs),\n creatorAccount\n )\n const didUri = Kilt.Did.getFullDidUriFromKey(creatorAccount)\n const encodedFullDid = await api.call.did.query(Kilt.Did.toChain(didUri))\n const { document: didDocument } = Kilt.Did.linkedInfoFromChain(encodedFullDid)\n\n if (!didDocument) {\n throw new Error('Full DID was not successfully created.')\n }\n\n return { fullDid: didDocument }\n}\n\n// Don't execute if this is imported by another file.\nif (require.main === module) {\n ;(async () => {\n envConfig()\n\n try {\n await Kilt.connect(process.env.WSS_ADDRESS as string)\n\n // Load attester account\n const accountMnemonic = process.env.ATTESTER_ACCOUNT_MNEMONIC as string\n const { account } = generateAccount(accountMnemonic)\n const { fullDid } = await createFullDid(account)\n\n console.log('\\nsave following to .env to continue\\n')\n console.error(`ATTESTER_DID_URI=\"${fullDid.uri}\"\\n`)\n } catch (e) {\n console.log('Error while creating attester DID')\n throw e\n }\n })()\n}\n",d={id:"did",title:"DID"},l=void 0,h={id:"develop/workshop/attester/did",title:"DID",description:"The next step is to generate a KILT decentralized identifier (DID) using the account you created for the Attester in the previous step.",source:"@site/docs/develop/03_workshop/04_attester/02_did.md",sourceDirName:"develop/03_workshop/04_attester",slug:"/develop/workshop/attester/did",permalink:"/docs/develop/workshop/attester/did",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/03_workshop/04_attester/02_did.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:2,frontMatter:{id:"did",title:"DID"},sidebar:"workshop",previous:{title:"Account",permalink:"/docs/develop/workshop/attester/account"},next:{title:"CType",permalink:"/docs/develop/workshop/attester/ctype"}},u={},p=[{value:"Light and full DIDs",id:"light-and-full-dids",level:2},{value:"What's the difference between a DID and an account?",id:"whats-the-difference-between-a-did-and-an-account",level:2},{value:"Create a DID",id:"create-a-did",level:2},{value:"Write DID to chain",id:"write-did-to-chain",level:3},{value:"Run the code",id:"run-the-code",level:2}];function D(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["The next step is to generate a KILT decentralized identifier (DID) using the account you created for the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," in ",(0,i.jsx)(t.a,{href:"/docs/develop/workshop/attester/account",children:"the previous step"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"A DID may represent any entity, such as a person, an organization, or a machine."}),"\n",(0,i.jsx)(t.p,{children:"A DID is a string uniquely identifying each KILT user.\nYou can store information about a DID on the KILT chain, which is useful for different use cases."}),"\n",(0,i.jsx)(t.p,{children:"One use case is messaging.\nYou could store a public encryption key and a service on chain, and a user can query both using a DID.\nOther users can now encrypt messages using your public encryption key and send a message to your service."}),"\n",(0,i.jsx)(t.h2,{id:"light-and-full-dids",children:"Light and full DIDs"}),"\n",(0,i.jsxs)(t.p,{children:["Kilt supports two DID types: ",(0,i.jsx)(t.strong,{children:"light"})," and ",(0,i.jsx)(t.strong,{children:"full"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["There are differences between the two types, but the most crucial is that you can use a light DID offline, but a full DID needs access to the blockchain to work.\nRead the ",(0,i.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/dids/light-did-creation",children:"DID documentation"})," to learn more about the difference between the light and full types."]}),"\n",(0,i.jsxs)(t.admonition,{title:"KILT DID",type:"info",children:[(0,i.jsx)(t.p,{children:"A DID supports four different key types:"}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["An ",(0,i.jsx)(t.em,{children:"authentication key pair"}),", used to sign claims and present authenticated credentials"]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.em,{children:"key-agreement key pair"}),", used to encrypt/decrypt messages"]}),"\n",(0,i.jsxs)(t.li,{children:["An ",(0,i.jsx)(t.em,{children:"assertion-method key pair"}),", used to write CTypes and attestations on chain"]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.em,{children:"capability-delegation key pair"}),", used to write delegations on chain"]}),"\n"]}),(0,i.jsx)(t.p,{children:"You can replace keys over time, e.g., if a key becomes compromised."})]}),"\n",(0,i.jsx)(t.h2,{id:"whats-the-difference-between-a-did-and-an-account",children:"What's the difference between a DID and an account?"}),"\n",(0,i.jsx)(t.p,{children:"A DID and an account sound quite similar, but there are some differences:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"You record both to chain"}),"\n",(0,i.jsx)(t.li,{children:"You can have a DID without an account"}),"\n",(0,i.jsx)(t.li,{children:"You can have an account without a DID"}),"\n",(0,i.jsx)(t.li,{children:"Only an account can pay deposits and fees and attest claims"}),"\n",(0,i.jsx)(t.li,{children:"DIDs don't hold any coins"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"In summary, you register a DID on the blockchain by an account submitting the DID creation transaction and paying the fees."}),"\n",(0,i.jsx)(t.h2,{id:"create-a-did",children:"Create a DID"}),"\n",(0,i.jsxs)(t.p,{children:["As an ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," needs to interact with the chain, you must create a full DID."]}),"\n",(0,i.jsx)(t.h3,{id:"write-did-to-chain",children:"Write DID to chain"}),"\n",(0,i.jsxs)(t.p,{children:["The KILT SDK provides multiple methods to create DIDs, this workshop highlights the ",(0,i.jsx)(t.code,{children:"createFromAccount"})," method, that creates a DID from any pre-existing substrate-compatible account."]}),"\n",(0,i.jsx)(t.admonition,{title:"Bring your own account",type:"info",children:(0,i.jsxs)(t.p,{children:["This workshop assumes you followed the ",(0,i.jsx)(t.a,{href:"/docs/develop/workshop/attester/account",children:"create account step"}),", but if you have a pre-existing account, you can use that instead."]})}),"\n",(0,i.jsx)(t.p,{children:"Create and submit the extrinsic (aka transaction) that registers the DID."}),"\n",(0,i.jsx)(o.c,{fileName:"attester/generateDid",children:r}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"publicKeyToChain"})," helper method returns a public key of the correct type."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"txs"})," array holds the two transactions containing the extrinsics needed to submit to the chain for the Attester's DID creation."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"createFromAccount"})," method takes the authenticated key of the account to attach the DID to, and the ",(0,i.jsx)(t.code,{children:"setAttestationKey"})," method takes the same parameter to set the attestation key the DID needs and uses."]}),"\n",(0,i.jsxs)(t.p,{children:["An Attester account needs to have an attestation key to write CTypes and attestations on chain. Use the ",(0,i.jsx)(t.code,{children:"setAttestationKey"})," method to set this. For this example transaction, the Attester account uses the ",(0,i.jsx)(t.code,{children:"dispatchAs"})," proxy method to assign the attestation key to the same account. However, you can also use this method to assign the attestation key to another account."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"signAndSubmitTx"})," method then takes those transactions and submits them as a batch to the chain."]}),"\n",(0,i.jsx)(t.h2,{id:"run-the-code",children:"Run the code"}),"\n",(0,i.jsx)(t.p,{children:"Now run the code with:"}),"\n",(0,i.jsxs)(a.c,{groupId:"ts-js-choice",children:[(0,i.jsx)(c.c,{value:"ts",label:"Typescript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"yarn ts-node ./attester/generateDid.ts\n"})})}),(0,i.jsx)(c.c,{value:"js",label:"Javascript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"node ./attester/generateDid.js\n"})})})]}),"\n",(0,i.jsxs)(t.p,{children:["Once you have run the script, the output should provide you with the ",(0,i.jsx)(t.code,{children:"ATTESTER_DID_MNEMONIC"})," and ",(0,i.jsx)(t.code,{children:"ATTESTER_DID_URI"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"The output should look like the following, but not identical since the code creates the DIDs from your account:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:'ATTESTER_DID_MNEMONIC="beyond large galaxy\u2026\nATTESTER_DID_URI="did:kilt:4ohMvUHsyeD\u2026"\n'})}),"\n",(0,i.jsxs)(t.p,{children:["Save the values in the ",(0,i.jsx)(t.code,{children:".env"})," file, which should now look like the following:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-env",metastring:'title=".env"',children:'WSS_ADDRESS=wss://peregrine.kilt.io\n\nATTESTER_ACCOUNT_MNEMONIC="warrior icon use cry...\nATTESTER_ACCOUNT_ADDRESS=4ohMvUHsyeDhMVZF...\nATTESTER_DID_MNEMONIC="beyond large galaxy...\nATTESTER_DID_URI="did:kilt:4ohMvUHsyeD..."\n'})}),"\n",(0,i.jsx)(t.p,{children:"Well done - You've generated a full DID! The next step is to create a CType!"})]})}function m(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(D,{...e})}):D(e)}},73484:(e,t,n)=>{"use strict";n.d(t,{c:()=>o});n(11504);var i=n(1608),s=n(17624);const o=e=>{let{children:t,funcName:n="main",leadingSpaces:o=2,dropHead:a=0,dropTail:c=0,...r}=e;const d=new RegExp(`${n}\\((?:.|\\n|\\r)*?\\)(?::(?:.|\\n|\\r)*?)?\\s*{(?:\\n|\\r)*(?(?:.|\\n|\\r)+)\\}`),l=t.toString().match(d)??{};let h="";if(l?.groups?.body){const{body:e}=l.groups,t=e.split(/\r?\n/);h=t.map((e=>e.slice(o))).slice(parseInt(a),t.length-parseInt(c)-1).join("\n")}else h=t.toString();return(0,s.jsx)(i.c,{...r,children:h})}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>p});var i=n(11504),s=n(28264),o=n(46352),a=n(58440),c=n(14300),r=n(28168),d=n(61268),l=n(87768),h=n(1608),u=n(17624);const p=e=>{let{children:t,fileName:n,...p}=e;const D=t,[m,f]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:x}}}=(0,s.c)(),g=(0,i.useMemo)((()=>{const{code:e}=(0,o.transform)(D,{plugins:["transform-typescript"],retainLines:!0});return e}),[D]);(0,i.useEffect)((()=>{a.E9(g,{parser:"babel",plugins:[c.c,r.cp],...x}).then(f)}),[x,g]);const y=[{fileName:n?`${n}.ts`:void 0,fileContents:D,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:m,fileID:"js",fileLabel:"Javascript"}];return(0,u.jsx)(u.Fragment,{children:(0,u.jsx)(d.c,{groupId:"ts-js-choice",children:y.map((e=>(0,u.jsx)(l.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,u.jsx)(h.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2068],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},14548:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>h,toc:()=>p});var i=n(17624),s=n(4552),o=(n(1608),n(96020)),a=(n(73484),n(61268)),c=n(87768);const r="import * as Kilt from '@kiltprotocol/sdk-js'\nimport { config as envConfig } from 'dotenv'\nimport { generateAccount } from './generateAccount'\n\nexport async function createFullDid(\n creatorAccount: Kilt.KiltKeyringPair & {\n type: 'ed25519' | 'sr25519' | 'ecdsa'\n }\n): Promise<{\n fullDid: Kilt.DidDocument\n}> {\n const api = Kilt.ConfigService.get('api')\n\n const verificationMethod = Kilt.Did.publicKeyToChain(creatorAccount)\n\n const txs = [\n api.tx.did.createFromAccount(verificationMethod),\n api.tx.did.dispatchAs(\n creatorAccount.address,\n api.tx.did.setAttestationKey(verificationMethod)\n )\n ]\n\n console.log('Creating DID from account\u2026')\n await Kilt.Blockchain.signAndSubmitTx(\n api.tx.utility.batch(txs),\n creatorAccount\n )\n const didUri = Kilt.Did.getFullDidUriFromKey(creatorAccount)\n const encodedFullDid = await api.call.did.query(Kilt.Did.toChain(didUri))\n const { document: didDocument } = Kilt.Did.linkedInfoFromChain(encodedFullDid)\n\n if (!didDocument) {\n throw new Error('Full DID was not successfully created.')\n }\n\n return { fullDid: didDocument }\n}\n\n// Don't execute if this is imported by another file.\nif (require.main === module) {\n ;(async () => {\n envConfig()\n\n try {\n await Kilt.connect(process.env.WSS_ADDRESS as string)\n\n // Load attester account\n const accountMnemonic = process.env.ATTESTER_ACCOUNT_MNEMONIC as string\n const { account } = generateAccount(accountMnemonic)\n const { fullDid } = await createFullDid(account)\n\n console.log('\\nsave following to .env to continue\\n')\n console.error(`ATTESTER_DID_URI=\"${fullDid.uri}\"\\n`)\n } catch (e) {\n console.log('Error while creating attester DID')\n throw e\n }\n })()\n}\n",d={id:"did",title:"DID"},l=void 0,h={id:"develop/workshop/attester/did",title:"DID",description:"The next step is to generate a KILT decentralized identifier (DID) using the account you created for the Attester in the previous step.",source:"@site/docs/develop/03_workshop/04_attester/02_did.md",sourceDirName:"develop/03_workshop/04_attester",slug:"/develop/workshop/attester/did",permalink:"/docs/develop/workshop/attester/did",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/03_workshop/04_attester/02_did.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:2,frontMatter:{id:"did",title:"DID"},sidebar:"workshop",previous:{title:"Account",permalink:"/docs/develop/workshop/attester/account"},next:{title:"CType",permalink:"/docs/develop/workshop/attester/ctype"}},u={},p=[{value:"Light and full DIDs",id:"light-and-full-dids",level:2},{value:"What's the difference between a DID and an account?",id:"whats-the-difference-between-a-did-and-an-account",level:2},{value:"Create a DID",id:"create-a-did",level:2},{value:"Write DID to chain",id:"write-did-to-chain",level:3},{value:"Run the code",id:"run-the-code",level:2}];function D(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["The next step is to generate a KILT decentralized identifier (DID) using the account you created for the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," in ",(0,i.jsx)(t.a,{href:"/docs/develop/workshop/attester/account",children:"the previous step"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"A DID may represent any entity, such as a person, an organization, or a machine."}),"\n",(0,i.jsx)(t.p,{children:"A DID is a string uniquely identifying each KILT user.\nYou can store information about a DID on the KILT chain, which is useful for different use cases."}),"\n",(0,i.jsx)(t.p,{children:"One use case is messaging.\nYou could store a public encryption key and a service on chain, and a user can query both using a DID.\nOther users can now encrypt messages using your public encryption key and send a message to your service."}),"\n",(0,i.jsx)(t.h2,{id:"light-and-full-dids",children:"Light and full DIDs"}),"\n",(0,i.jsxs)(t.p,{children:["Kilt supports two DID types: ",(0,i.jsx)(t.strong,{children:"light"})," and ",(0,i.jsx)(t.strong,{children:"full"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["There are differences between the two types, but the most crucial is that you can use a light DID offline, but a full DID needs access to the blockchain to work.\nRead the ",(0,i.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/dids/light-did-creation",children:"DID documentation"})," to learn more about the difference between the light and full types."]}),"\n",(0,i.jsxs)(t.admonition,{title:"KILT DID",type:"info",children:[(0,i.jsx)(t.p,{children:"A DID supports four different key types:"}),(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["An ",(0,i.jsx)(t.em,{children:"authentication key pair"}),", used to sign claims and present authenticated credentials"]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.em,{children:"key-agreement key pair"}),", used to encrypt/decrypt messages"]}),"\n",(0,i.jsxs)(t.li,{children:["An ",(0,i.jsx)(t.em,{children:"assertion-method key pair"}),", used to write CTypes and attestations on chain"]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.em,{children:"capability-delegation key pair"}),", used to write delegations on chain"]}),"\n"]}),(0,i.jsx)(t.p,{children:"You can replace keys over time, e.g., if a key becomes compromised."})]}),"\n",(0,i.jsx)(t.h2,{id:"whats-the-difference-between-a-did-and-an-account",children:"What's the difference between a DID and an account?"}),"\n",(0,i.jsx)(t.p,{children:"A DID and an account sound quite similar, but there are some differences:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"You record both to chain"}),"\n",(0,i.jsx)(t.li,{children:"You can have a DID without an account"}),"\n",(0,i.jsx)(t.li,{children:"You can have an account without a DID"}),"\n",(0,i.jsx)(t.li,{children:"Only an account can pay deposits and fees and attest claims"}),"\n",(0,i.jsx)(t.li,{children:"DIDs don't hold any coins"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"In summary, you register a DID on the blockchain by an account submitting the DID creation transaction and paying the fees."}),"\n",(0,i.jsx)(t.h2,{id:"create-a-did",children:"Create a DID"}),"\n",(0,i.jsxs)(t.p,{children:["As an ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," needs to interact with the chain, you must create a full DID."]}),"\n",(0,i.jsx)(t.h3,{id:"write-did-to-chain",children:"Write DID to chain"}),"\n",(0,i.jsxs)(t.p,{children:["The KILT SDK provides multiple methods to create DIDs, this workshop highlights the ",(0,i.jsx)(t.code,{children:"createFromAccount"})," method, that creates a DID from any pre-existing substrate-compatible account."]}),"\n",(0,i.jsx)(t.admonition,{title:"Bring your own account",type:"info",children:(0,i.jsxs)(t.p,{children:["This workshop assumes you followed the ",(0,i.jsx)(t.a,{href:"/docs/develop/workshop/attester/account",children:"create account step"}),", but if you have a pre-existing account, you can use that instead."]})}),"\n",(0,i.jsx)(t.p,{children:"Create and submit the extrinsic (aka transaction) that registers the DID."}),"\n",(0,i.jsx)(o.c,{fileName:"attester/generateDid",children:r}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"publicKeyToChain"})," helper method returns a public key of the correct type."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"txs"})," array holds the two transactions containing the extrinsics needed to submit to the chain for the Attester's DID creation."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"createFromAccount"})," method takes the authenticated key of the account to attach the DID to, and the ",(0,i.jsx)(t.code,{children:"setAttestationKey"})," method takes the same parameter to set the attestation key the DID needs and uses."]}),"\n",(0,i.jsxs)(t.p,{children:["An Attester account needs to have an attestation key to write CTypes and attestations on chain. Use the ",(0,i.jsx)(t.code,{children:"setAttestationKey"})," method to set this. For this example transaction, the Attester account uses the ",(0,i.jsx)(t.code,{children:"dispatchAs"})," proxy method to assign the attestation key to the same account. However, you can also use this method to assign the attestation key to another account."]}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"signAndSubmitTx"})," method then takes those transactions and submits them as a batch to the chain."]}),"\n",(0,i.jsx)(t.h2,{id:"run-the-code",children:"Run the code"}),"\n",(0,i.jsx)(t.p,{children:"Now run the code with:"}),"\n",(0,i.jsxs)(a.c,{groupId:"ts-js-choice",children:[(0,i.jsx)(c.c,{value:"ts",label:"Typescript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"yarn ts-node ./attester/generateDid.ts\n"})})}),(0,i.jsx)(c.c,{value:"js",label:"Javascript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"node ./attester/generateDid.js\n"})})})]}),"\n",(0,i.jsxs)(t.p,{children:["Once you have run the script, the output should provide you with the ",(0,i.jsx)(t.code,{children:"ATTESTER_DID_MNEMONIC"})," and ",(0,i.jsx)(t.code,{children:"ATTESTER_DID_URI"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"The output should look like the following, but not identical since the code creates the DIDs from your account:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:'ATTESTER_DID_MNEMONIC="beyond large galaxy\u2026\nATTESTER_DID_URI="did:kilt:4ohMvUHsyeD\u2026"\n'})}),"\n",(0,i.jsxs)(t.p,{children:["Save the values in the ",(0,i.jsx)(t.code,{children:".env"})," file, which should now look like the following:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-env",metastring:'title=".env"',children:'WSS_ADDRESS=wss://peregrine.kilt.io\n\nATTESTER_ACCOUNT_MNEMONIC="warrior icon use cry...\nATTESTER_ACCOUNT_ADDRESS=4ohMvUHsyeDhMVZF...\nATTESTER_DID_MNEMONIC="beyond large galaxy...\nATTESTER_DID_URI="did:kilt:4ohMvUHsyeD..."\n'})}),"\n",(0,i.jsx)(t.p,{children:"Well done - You've generated a full DID! The next step is to create a CType!"})]})}function m(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(D,{...e})}):D(e)}},73484:(e,t,n)=>{"use strict";n.d(t,{c:()=>o});n(11504);var i=n(1608),s=n(17624);const o=e=>{let{children:t,funcName:n="main",leadingSpaces:o=2,dropHead:a=0,dropTail:c=0,...r}=e;const d=new RegExp(`${n}\\((?:.|\\n|\\r)*?\\)(?::(?:.|\\n|\\r)*?)?\\s*{(?:\\n|\\r)*(?(?:.|\\n|\\r)+)\\}`),l=t.toString().match(d)??{};let h="";if(l?.groups?.body){const{body:e}=l.groups,t=e.split(/\r?\n/);h=t.map((e=>e.slice(o))).slice(parseInt(a),t.length-parseInt(c)-1).join("\n")}else h=t.toString();return(0,s.jsx)(i.c,{...r,children:h})}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>p});var i=n(11504),s=n(28264),o=n(46352),a=n(58440),c=n(14300),r=n(28168),d=n(61268),l=n(87768),h=n(1608),u=n(17624);const p=e=>{let{children:t,fileName:n,...p}=e;const D=t,[m,f]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:x}}}=(0,s.c)(),g=(0,i.useMemo)((()=>{const{code:e}=(0,o.transform)(D,{plugins:["transform-typescript"],retainLines:!0});return e}),[D]);(0,i.useEffect)((()=>{a.E9(g,{parser:"babel",plugins:[c.c,r.cp],...x}).then(f)}),[x,g]);const y=[{fileName:n?`${n}.ts`:void 0,fileContents:D,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:m,fileID:"js",fileLabel:"Javascript"}];return(0,u.jsx)(u.Fragment,{children:(0,u.jsx)(d.c,{groupId:"ts-js-choice",children:y.map((e=>(0,u.jsx)(l.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,u.jsx)(h.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/0928c159.873b8dd4.js b/assets/js/0928c159.8e18f7ca.js similarity index 98% rename from assets/js/0928c159.873b8dd4.js rename to assets/js/0928c159.8e18f7ca.js index 6308f8622..47153d212 100644 --- a/assets/js/0928c159.873b8dd4.js +++ b/assets/js/0928c159.8e18f7ca.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6032],{75704:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=s(17624),r=s(4552),i=s(61964);const o={id:"overview",title:"Overview"},c=void 0,a={id:"concepts/credentials/overview",title:"Overview",description:"Credentials consist of a set of claims which belong to a Claimer, are attested by an Attester and can be verified by Verifiers.",source:"@site/docs/concepts/05_credentials/01_overview.md",sourceDirName:"concepts/05_credentials",slug:"/concepts/credentials/overview",permalink:"/docs/concepts/credentials/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/05_credentials/01_overview.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:1,frontMatter:{id:"overview",title:"Overview"},sidebar:"concepts",previous:{title:"AssetDIDs",permalink:"/docs/concepts/asset-dids"},next:{title:"CTypes",permalink:"/docs/concepts/credentials/ctypes"}},l={},d=[];function h(e){const t={a:"a",li:"li",ol:"ol",p:"p",strong:"strong",...(0,r.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Credentials"})," consist of a set of claims which belong to a ",(0,n.jsx)(t.strong,{children:"Claimer"}),", are attested by an ",(0,n.jsx)(t.strong,{children:"Attester"})," and can be verified by ",(0,n.jsx)(t.strong,{children:"Verifiers"}),"."]}),"\n",(0,n.jsx)("center",{children:(0,n.jsx)(i.c,{alt:"Credential Overview Diagram",sources:{light:"/img/concepts/credentials/overview.png",dark:"/img/concepts/credentials/overview_dark.png"}})}),"\n",(0,n.jsx)(t.p,{children:"To get a credential, a Claimer needs to go through following process:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Find a ",(0,n.jsx)(t.strong,{children:"CType"})," a claim should be based on. Potential Attesters and Verifiers might advertise this information themselves."]}),"\n",(0,n.jsxs)(t.li,{children:["Make a ",(0,n.jsx)(t.strong,{children:"claim"})," containing a set of properties about themselves."]}),"\n",(0,n.jsxs)(t.li,{children:["Potentially request and receive ",(0,n.jsx)(t.strong,{children:"Terms"})," and agree on a ",(0,n.jsx)(t.strong,{children:"Quote"})," with the potential Attester."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Request an attestation"})," from the Attester."]}),"\n",(0,n.jsxs)(t.li,{children:["Wait for the claims to be ",(0,n.jsx)(t.strong,{children:"attested"})," by the Attester."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Once attested, the claims are considered to be a valid credential."}),"\n",(0,n.jsx)(t.p,{children:"To verify a credential, a Claimer can generate a presentation of it to a Verifier, with the following process:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["The Verifier may request a ",(0,n.jsx)(t.strong,{children:"credential"})," as the first step, along with with properties to reveal from such Credential."]}),"\n",(0,n.jsxs)(t.li,{children:["The Claimer selectively ",(0,n.jsx)(t.strong,{children:"discloses"})," the requested properties and signs the generated presentation."]}),"\n",(0,n.jsxs)(t.li,{children:["The Verifier ",(0,n.jsx)(t.strong,{children:"checks"})," the presentation structure, content and signature, and decides whether they trust the Attester of the presented credential."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Each step is described in more detail in the next sections."}),"\n",(0,n.jsxs)(t.p,{children:["If you want to learn about how implement the above flow in a dapp that interacts with a browser extension, please refer to the ",(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-credential-api",children:"Credential API specification"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},4552:(e,t,s)=>{s.d(t,{I:()=>c,M:()=>o});var n=s(11504);const r={},i=n.createContext(r);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6032],{75704:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=s(17624),r=s(4552),i=s(61964);const o={id:"overview",title:"Overview"},c=void 0,a={id:"concepts/credentials/overview",title:"Overview",description:"Credentials consist of a set of claims which belong to a Claimer, are attested by an Attester and can be verified by Verifiers.",source:"@site/docs/concepts/05_credentials/01_overview.md",sourceDirName:"concepts/05_credentials",slug:"/concepts/credentials/overview",permalink:"/docs/concepts/credentials/overview",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/05_credentials/01_overview.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:1,frontMatter:{id:"overview",title:"Overview"},sidebar:"concepts",previous:{title:"AssetDIDs",permalink:"/docs/concepts/asset-dids"},next:{title:"CTypes",permalink:"/docs/concepts/credentials/ctypes"}},l={},d=[];function h(e){const t={a:"a",li:"li",ol:"ol",p:"p",strong:"strong",...(0,r.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Credentials"})," consist of a set of claims which belong to a ",(0,n.jsx)(t.strong,{children:"Claimer"}),", are attested by an ",(0,n.jsx)(t.strong,{children:"Attester"})," and can be verified by ",(0,n.jsx)(t.strong,{children:"Verifiers"}),"."]}),"\n",(0,n.jsx)("center",{children:(0,n.jsx)(i.c,{alt:"Credential Overview Diagram",sources:{light:"/img/concepts/credentials/overview.png",dark:"/img/concepts/credentials/overview_dark.png"}})}),"\n",(0,n.jsx)(t.p,{children:"To get a credential, a Claimer needs to go through following process:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Find a ",(0,n.jsx)(t.strong,{children:"CType"})," a claim should be based on. Potential Attesters and Verifiers might advertise this information themselves."]}),"\n",(0,n.jsxs)(t.li,{children:["Make a ",(0,n.jsx)(t.strong,{children:"claim"})," containing a set of properties about themselves."]}),"\n",(0,n.jsxs)(t.li,{children:["Potentially request and receive ",(0,n.jsx)(t.strong,{children:"Terms"})," and agree on a ",(0,n.jsx)(t.strong,{children:"Quote"})," with the potential Attester."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Request an attestation"})," from the Attester."]}),"\n",(0,n.jsxs)(t.li,{children:["Wait for the claims to be ",(0,n.jsx)(t.strong,{children:"attested"})," by the Attester."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Once attested, the claims are considered to be a valid credential."}),"\n",(0,n.jsx)(t.p,{children:"To verify a credential, a Claimer can generate a presentation of it to a Verifier, with the following process:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["The Verifier may request a ",(0,n.jsx)(t.strong,{children:"credential"})," as the first step, along with with properties to reveal from such Credential."]}),"\n",(0,n.jsxs)(t.li,{children:["The Claimer selectively ",(0,n.jsx)(t.strong,{children:"discloses"})," the requested properties and signs the generated presentation."]}),"\n",(0,n.jsxs)(t.li,{children:["The Verifier ",(0,n.jsx)(t.strong,{children:"checks"})," the presentation structure, content and signature, and decides whether they trust the Attester of the presented credential."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Each step is described in more detail in the next sections."}),"\n",(0,n.jsxs)(t.p,{children:["If you want to learn about how implement the above flow in a dapp that interacts with a browser extension, please refer to the ",(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-credential-api",children:"Credential API specification"}),"."]})]})}function p(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},4552:(e,t,s)=>{s.d(t,{I:()=>c,M:()=>o});var n=s(11504);const r={},i=n.createContext(r);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bf2e877.95810bef.js b/assets/js/0bf2e877.57ec51a7.js similarity index 99% rename from assets/js/0bf2e877.95810bef.js rename to assets/js/0bf2e877.57ec51a7.js index a248f3bcb..33ff1bcc0 100644 --- a/assets/js/0bf2e877.95810bef.js +++ b/assets/js/0bf2e877.57ec51a7.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4216],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},41756:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>g,toc:()=>p});var s=n(17624),r=n(4552),i=n(96020);const a="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function generateRequestCredentialMessage(\n senderUri: Kilt.DidUri,\n receiverUri: Kilt.DidUri,\n cTypeHash: Kilt.CTypeHash\n) {\n // Creating a challenge to submit to the receiver\n const challenge = Kilt.Utils.UUID.generate()\n\n // Sender uri is checked if it is a valid URI\n Kilt.Did.validateUri(senderUri)\n // Receiver uri is checked if it is a valid URI\n Kilt.Did.validateUri(receiverUri)\n\n // The content of the 'request-credential' message\n // It includes a CType that is being requested, this can be for attestation or verification\n // The sender is the trusted attester in the scenario\n const requestCredentialContent = {\n cTypeHash: cTypeHash,\n trustedAttesters: [senderUri]\n }\n\n const messageBody: Kilt.IRequestCredential = {\n type: 'request-credential',\n content: { cTypes: [requestCredentialContent], challenge: challenge }\n }\n\n // The message will throw an Error if invalid\n const message = Kilt.Message.fromBody(messageBody, senderUri, receiverUri)\n\n console.log(`Generated message: ${JSON.stringify(message, null, 4)}`)\n\n return message\n}\n",c="import * as Kilt from '@kiltprotocol/sdk-js'\nimport { useEncryptionCallback } from '../signCallback/useEncryptionCallback'\n\nexport async function encryptMessage(\n message: Kilt.IMessage,\n senderUri: Kilt.DidUri,\n receiverUri: Kilt.DidUri,\n keyAgreement: Kilt.KiltEncryptionKeypair\n): Promise {\n const { document: senderDocument } = await Kilt.Did.resolve(senderUri)\n\n const { document: receiverDocument } = await Kilt.Did.resolve(receiverUri)\n\n const receiverKeyAgreementUri =\n `${receiverUri}${receiverDocument.keyAgreement?.[0].id}` as Kilt.DidResourceUri\n const senderKeyAgreeementUri =\n `${senderUri}${senderDocument.keyAgreement?.[0].id}` as Kilt.DidResourceUri\n // encrypt the message\n const encryptedMessage = await Kilt.Message.encrypt(\n message,\n useEncryptionCallback({\n keyAgreement,\n keyAgreementUri: senderKeyAgreeementUri\n }),\n receiverKeyAgreementUri\n )\n\n console.log(`Encrypted Message: ${JSON.stringify(encryptedMessage, null, 4)}`)\n\n return encryptedMessage\n}\n",o="import * as Kilt from '@kiltprotocol/sdk-js'\nimport { useDecryptionCallback } from '../signCallback/useDecryptionCallback'\n\nexport async function decryptMessage(\n encryptedMessage: Kilt.IEncryptedMessage,\n keyAgreement: Kilt.KiltEncryptionKeypair\n): Promise {\n // Decrypting the message to retrieve the content\n const decryptedMessage = await Kilt.Message.decrypt(\n encryptedMessage,\n useDecryptionCallback(keyAgreement)\n )\n\n // Verifying this is a properly-formatted message\n Kilt.Message.verify(decryptedMessage)\n\n console.log(`Decrypted Message: ${JSON.stringify(decryptedMessage, null, 4)}`)\n\n // Checking if the message type matches the expected checks\n if (decryptedMessage.body.type !== 'request-credential') {\n throw new Error('Not the correct body type')\n }\n\n // Destructing the message to receive the cTypes array to see what credentials\n // Are valid for the given request\n const { cTypes } = decryptedMessage.body.content\n\n const { cTypeHash, trustedAttesters } = cTypes[0]\n\n // The receiver can check if they have a valid credential that matches the cTypeHash\n console.log('The sent cType hash :', cTypeHash)\n\n // The trusted attesters is an array that includes the list of trusted entities\n // The receiver can check if they have a given credential from the trusted list\n console.log(`A list of trusted attesters DID :${trustedAttesters}`)\n\n return decryptedMessage\n}\n",d={id:"messaging_book",title:"Generate a Message"},l=void 0,g={id:"develop/sdk/cookbook/messaging/messaging_book",title:"Generate a Message",description:"KILT defines a unicast messaging protocol",source:"@site/docs/develop/01_sdk/02_cookbook/06_messaging/01_messaging.md",sourceDirName:"develop/01_sdk/02_cookbook/06_messaging",slug:"/develop/sdk/cookbook/messaging/messaging_book",permalink:"/docs/develop/sdk/cookbook/messaging/messaging_book",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/06_messaging/01_messaging.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:1,frontMatter:{id:"messaging_book",title:"Generate a Message"},sidebar:"sdk",previous:{title:"Revoke (and remove) Public Credentials",permalink:"/docs/develop/sdk/cookbook/public_credentials/public-credential-revocation"},next:{title:"Protect Against Replay Attacks",permalink:"/docs/develop/sdk/cookbook/messaging/replay_protection"}},h={},p=[{value:"Encryption",id:"encryption",level:2},{value:"Decryption",id:"decryption",level:2}];function y(e){const t={a:"a",code:"code",h2:"h2",p:"p",...(0,r.M)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["KILT defines a ",(0,s.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Unicast",children:"unicast"})," messaging protocol"]}),"\n",(0,s.jsxs)(t.p,{children:["Each of the messages sent is encrypted using the ",(0,s.jsx)(t.a,{href:"https://www.w3.org/TR/did-core/#key-agreement",children:"DID key agreement key"}),".\nA message consists of the sender's DID URI, the receiver's DID URI, the message type and the body.\nThere are multiple different message types, each of them with a different structure and containing different information.\nIn this example we are going to build a ",(0,s.jsx)(t.code,{children:"request-credential"})," message.\nThe message structure is checked and validated on by the KILT SDK to ensure the users are sending correctly structured messages."]}),"\n",(0,s.jsxs)(t.p,{children:["The following example here will generate a message by constructing the message content.\nThe message content includes a valid ",(0,s.jsx)(t.code,{children:"cTypeHash"})," and a list of ",(0,s.jsx)(t.code,{children:"trusted attesters"}),".\nThe message requires a ",(0,s.jsx)(t.code,{children:"messageBody"}),", sender and receiver uri."]}),"\n",(0,s.jsx)(i.c,{children:a}),"\n",(0,s.jsx)(t.h2,{id:"encryption",children:"Encryption"}),"\n",(0,s.jsxs)(t.p,{children:["The messages data are encrypted and decrypted using ",(0,s.jsx)(t.a,{href:"https://github.com/dchest/tweetnacl-js",children:"nacl's"})," 'x25519-xsalsa20-poly1305' algorithm, which provides repudiable authenticated encryption based on an x25519 key agreement protocol.\nThe DID holds keys for the encryption and decryption.\nThe key is called ",(0,s.jsx)(t.code,{children:"KeyAgreement"})," keys.\nThey may also be known as encryption keys."]}),"\n",(0,s.jsx)(t.p,{children:"The content of the object is converted from a serialized string to a byte array, which is passed into the callback function along with the sender's DID and key agreement public key of the receiver."}),"\n",(0,s.jsx)(t.p,{children:"The following example here will take a generated message and encrypt the message for the receiver to decrypt later."}),"\n",(0,s.jsx)(i.c,{children:c}),"\n",(0,s.jsx)(t.p,{children:"The encrypted data is converted into a hex string which is known as the ciphertext along with the nonce that was generated during encryption."}),"\n",(0,s.jsx)(t.h2,{id:"decryption",children:"Decryption"}),"\n",(0,s.jsx)(t.p,{children:"The decryption takes the encrypted message and decyphers its content.\nThe following example here will take a encrypted message and decrypt using the private key of the receiver.\nOnce decrypted, it checks the content is a valid message.\nThe decrypted data can be used for additional steps.\nAfter decrypting, the receiver may wish to present a credential from the trusted attester list with a given CType."}),"\n",(0,s.jsx)(i.c,{children:o})]})}function m(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(y,{...e})}):y(e)}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>p});var s=n(11504),r=n(28264),i=n(46352),a=n(58440),c=n(14300),o=n(28168),d=n(61268),l=n(87768),g=n(1608),h=n(17624);const p=e=>{let{children:t,fileName:n,...p}=e;const y=t,[m,u]=(0,s.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:f}}}=(0,r.c)(),k=(0,s.useMemo)((()=>{const{code:e}=(0,i.transform)(y,{plugins:["transform-typescript"],retainLines:!0});return e}),[y]);(0,s.useEffect)((()=>{a.E9(k,{parser:"babel",plugins:[c.c,o.cp],...f}).then(u)}),[f,k]);const v=[{fileName:n?`${n}.ts`:void 0,fileContents:y,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:m,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(d.c,{groupId:"ts-js-choice",children:v.map((e=>(0,h.jsx)(l.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,h.jsx)(g.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4216],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},41756:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>g,toc:()=>p});var s=n(17624),r=n(4552),i=n(96020);const a="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function generateRequestCredentialMessage(\n senderUri: Kilt.DidUri,\n receiverUri: Kilt.DidUri,\n cTypeHash: Kilt.CTypeHash\n) {\n // Creating a challenge to submit to the receiver\n const challenge = Kilt.Utils.UUID.generate()\n\n // Sender uri is checked if it is a valid URI\n Kilt.Did.validateUri(senderUri)\n // Receiver uri is checked if it is a valid URI\n Kilt.Did.validateUri(receiverUri)\n\n // The content of the 'request-credential' message\n // It includes a CType that is being requested, this can be for attestation or verification\n // The sender is the trusted attester in the scenario\n const requestCredentialContent = {\n cTypeHash: cTypeHash,\n trustedAttesters: [senderUri]\n }\n\n const messageBody: Kilt.IRequestCredential = {\n type: 'request-credential',\n content: { cTypes: [requestCredentialContent], challenge: challenge }\n }\n\n // The message will throw an Error if invalid\n const message = Kilt.Message.fromBody(messageBody, senderUri, receiverUri)\n\n console.log(`Generated message: ${JSON.stringify(message, null, 4)}`)\n\n return message\n}\n",c="import * as Kilt from '@kiltprotocol/sdk-js'\nimport { useEncryptionCallback } from '../signCallback/useEncryptionCallback'\n\nexport async function encryptMessage(\n message: Kilt.IMessage,\n senderUri: Kilt.DidUri,\n receiverUri: Kilt.DidUri,\n keyAgreement: Kilt.KiltEncryptionKeypair\n): Promise {\n const { document: senderDocument } = await Kilt.Did.resolve(senderUri)\n\n const { document: receiverDocument } = await Kilt.Did.resolve(receiverUri)\n\n const receiverKeyAgreementUri =\n `${receiverUri}${receiverDocument.keyAgreement?.[0].id}` as Kilt.DidResourceUri\n const senderKeyAgreeementUri =\n `${senderUri}${senderDocument.keyAgreement?.[0].id}` as Kilt.DidResourceUri\n // encrypt the message\n const encryptedMessage = await Kilt.Message.encrypt(\n message,\n useEncryptionCallback({\n keyAgreement,\n keyAgreementUri: senderKeyAgreeementUri\n }),\n receiverKeyAgreementUri\n )\n\n console.log(`Encrypted Message: ${JSON.stringify(encryptedMessage, null, 4)}`)\n\n return encryptedMessage\n}\n",o="import * as Kilt from '@kiltprotocol/sdk-js'\nimport { useDecryptionCallback } from '../signCallback/useDecryptionCallback'\n\nexport async function decryptMessage(\n encryptedMessage: Kilt.IEncryptedMessage,\n keyAgreement: Kilt.KiltEncryptionKeypair\n): Promise {\n // Decrypting the message to retrieve the content\n const decryptedMessage = await Kilt.Message.decrypt(\n encryptedMessage,\n useDecryptionCallback(keyAgreement)\n )\n\n // Verifying this is a properly-formatted message\n Kilt.Message.verify(decryptedMessage)\n\n console.log(`Decrypted Message: ${JSON.stringify(decryptedMessage, null, 4)}`)\n\n // Checking if the message type matches the expected checks\n if (decryptedMessage.body.type !== 'request-credential') {\n throw new Error('Not the correct body type')\n }\n\n // Destructing the message to receive the cTypes array to see what credentials\n // Are valid for the given request\n const { cTypes } = decryptedMessage.body.content\n\n const { cTypeHash, trustedAttesters } = cTypes[0]\n\n // The receiver can check if they have a valid credential that matches the cTypeHash\n console.log('The sent cType hash :', cTypeHash)\n\n // The trusted attesters is an array that includes the list of trusted entities\n // The receiver can check if they have a given credential from the trusted list\n console.log(`A list of trusted attesters DID :${trustedAttesters}`)\n\n return decryptedMessage\n}\n",d={id:"messaging_book",title:"Generate a Message"},l=void 0,g={id:"develop/sdk/cookbook/messaging/messaging_book",title:"Generate a Message",description:"KILT defines a unicast messaging protocol",source:"@site/docs/develop/01_sdk/02_cookbook/06_messaging/01_messaging.md",sourceDirName:"develop/01_sdk/02_cookbook/06_messaging",slug:"/develop/sdk/cookbook/messaging/messaging_book",permalink:"/docs/develop/sdk/cookbook/messaging/messaging_book",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/06_messaging/01_messaging.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:1,frontMatter:{id:"messaging_book",title:"Generate a Message"},sidebar:"sdk",previous:{title:"Revoke (and remove) Public Credentials",permalink:"/docs/develop/sdk/cookbook/public_credentials/public-credential-revocation"},next:{title:"Protect Against Replay Attacks",permalink:"/docs/develop/sdk/cookbook/messaging/replay_protection"}},h={},p=[{value:"Encryption",id:"encryption",level:2},{value:"Decryption",id:"decryption",level:2}];function y(e){const t={a:"a",code:"code",h2:"h2",p:"p",...(0,r.M)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["KILT defines a ",(0,s.jsx)(t.a,{href:"https://en.wikipedia.org/wiki/Unicast",children:"unicast"})," messaging protocol"]}),"\n",(0,s.jsxs)(t.p,{children:["Each of the messages sent is encrypted using the ",(0,s.jsx)(t.a,{href:"https://www.w3.org/TR/did-core/#key-agreement",children:"DID key agreement key"}),".\nA message consists of the sender's DID URI, the receiver's DID URI, the message type and the body.\nThere are multiple different message types, each of them with a different structure and containing different information.\nIn this example we are going to build a ",(0,s.jsx)(t.code,{children:"request-credential"})," message.\nThe message structure is checked and validated on by the KILT SDK to ensure the users are sending correctly structured messages."]}),"\n",(0,s.jsxs)(t.p,{children:["The following example here will generate a message by constructing the message content.\nThe message content includes a valid ",(0,s.jsx)(t.code,{children:"cTypeHash"})," and a list of ",(0,s.jsx)(t.code,{children:"trusted attesters"}),".\nThe message requires a ",(0,s.jsx)(t.code,{children:"messageBody"}),", sender and receiver uri."]}),"\n",(0,s.jsx)(i.c,{children:a}),"\n",(0,s.jsx)(t.h2,{id:"encryption",children:"Encryption"}),"\n",(0,s.jsxs)(t.p,{children:["The messages data are encrypted and decrypted using ",(0,s.jsx)(t.a,{href:"https://github.com/dchest/tweetnacl-js",children:"nacl's"})," 'x25519-xsalsa20-poly1305' algorithm, which provides repudiable authenticated encryption based on an x25519 key agreement protocol.\nThe DID holds keys for the encryption and decryption.\nThe key is called ",(0,s.jsx)(t.code,{children:"KeyAgreement"})," keys.\nThey may also be known as encryption keys."]}),"\n",(0,s.jsx)(t.p,{children:"The content of the object is converted from a serialized string to a byte array, which is passed into the callback function along with the sender's DID and key agreement public key of the receiver."}),"\n",(0,s.jsx)(t.p,{children:"The following example here will take a generated message and encrypt the message for the receiver to decrypt later."}),"\n",(0,s.jsx)(i.c,{children:c}),"\n",(0,s.jsx)(t.p,{children:"The encrypted data is converted into a hex string which is known as the ciphertext along with the nonce that was generated during encryption."}),"\n",(0,s.jsx)(t.h2,{id:"decryption",children:"Decryption"}),"\n",(0,s.jsx)(t.p,{children:"The decryption takes the encrypted message and decyphers its content.\nThe following example here will take a encrypted message and decrypt using the private key of the receiver.\nOnce decrypted, it checks the content is a valid message.\nThe decrypted data can be used for additional steps.\nAfter decrypting, the receiver may wish to present a credential from the trusted attester list with a given CType."}),"\n",(0,s.jsx)(i.c,{children:o})]})}function m(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(y,{...e})}):y(e)}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>p});var s=n(11504),r=n(28264),i=n(46352),a=n(58440),c=n(14300),o=n(28168),d=n(61268),l=n(87768),g=n(1608),h=n(17624);const p=e=>{let{children:t,fileName:n,...p}=e;const y=t,[m,u]=(0,s.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:f}}}=(0,r.c)(),k=(0,s.useMemo)((()=>{const{code:e}=(0,i.transform)(y,{plugins:["transform-typescript"],retainLines:!0});return e}),[y]);(0,s.useEffect)((()=>{a.E9(k,{parser:"babel",plugins:[c.c,o.cp],...f}).then(u)}),[f,k]);const v=[{fileName:n?`${n}.ts`:void 0,fileContents:y,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:m,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(d.c,{groupId:"ts-js-choice",children:v.map((e=>(0,h.jsx)(l.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,h.jsx)(g.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/0d584741.214af855.js b/assets/js/0d584741.29bd6181.js similarity index 94% rename from assets/js/0d584741.214af855.js rename to assets/js/0d584741.29bd6181.js index 85162831e..46a16c9d0 100644 --- a/assets/js/0d584741.214af855.js +++ b/assets/js/0d584741.29bd6181.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6676],{96400:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var o=n(17624),r=n(4552);const i={id:"howto-integrate-index",title:"How to Integrate"},s=void 0,d={id:"develop/sdk/integrate/howto-integrate-index",title:"How to Integrate",description:"Integrating with KILT is easy.",source:"@site/docs/develop/01_sdk/04_integrate/index.md",sourceDirName:"develop/01_sdk/04_integrate",slug:"/develop/sdk/integrate/",permalink:"/docs/develop/sdk/integrate/",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/04_integrate/index.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",frontMatter:{id:"howto-integrate-index",title:"How to Integrate"},sidebar:"sdk",previous:{title:"Connect to Spiritnet",permalink:"/docs/develop/sdk/chain_setup/prod-chain-setup"},next:{title:"NodeJS",permalink:"/docs/develop/sdk/integrate/howto-integrate-nodejs"}},a={},c=[];function p(e){const t={a:"a",p:"p",...(0,r.M)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.p,{children:"Integrating with KILT is easy.\nIf your project needs to integrate KILT in a frontend and/or a backend application, we've got you covered!"}),"\n",(0,o.jsxs)(t.p,{children:["These pages are dedicated to helping you set up a ",(0,o.jsx)(t.a,{href:"/docs/develop/sdk/integrate/howto-integrate-nodejs",children:"NodeJS application"})," or ",(0,o.jsx)(t.a,{href:"/docs/develop/sdk/integrate/howto-integrate-browser",children:"web app"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["We also introduce the ",(0,o.jsx)(t.a,{href:"/docs/develop/sdk/integrate/howto-integrate-distillery",children:"KILT distillery CLI tool"})," which helps you quickly spin up your first KILT-based project."]})]})}function l(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>d,M:()=>s});var o=n(11504);const r={},i=o.createContext(r);function s(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[6676],{96400:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var o=n(17624),r=n(4552);const i={id:"howto-integrate-index",title:"How to Integrate"},s=void 0,d={id:"develop/sdk/integrate/howto-integrate-index",title:"How to Integrate",description:"Integrating with KILT is easy.",source:"@site/docs/develop/01_sdk/04_integrate/index.md",sourceDirName:"develop/01_sdk/04_integrate",slug:"/develop/sdk/integrate/",permalink:"/docs/develop/sdk/integrate/",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/04_integrate/index.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",frontMatter:{id:"howto-integrate-index",title:"How to Integrate"},sidebar:"sdk",previous:{title:"Connect to Spiritnet",permalink:"/docs/develop/sdk/chain_setup/prod-chain-setup"},next:{title:"NodeJS",permalink:"/docs/develop/sdk/integrate/howto-integrate-nodejs"}},a={},c=[];function p(e){const t={a:"a",p:"p",...(0,r.M)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.p,{children:"Integrating with KILT is easy.\nIf your project needs to integrate KILT in a frontend and/or a backend application, we've got you covered!"}),"\n",(0,o.jsxs)(t.p,{children:["These pages are dedicated to helping you set up a ",(0,o.jsx)(t.a,{href:"/docs/develop/sdk/integrate/howto-integrate-nodejs",children:"NodeJS application"})," or ",(0,o.jsx)(t.a,{href:"/docs/develop/sdk/integrate/howto-integrate-browser",children:"web app"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["We also introduce the ",(0,o.jsx)(t.a,{href:"/docs/develop/sdk/integrate/howto-integrate-distillery",children:"KILT distillery CLI tool"})," which helps you quickly spin up your first KILT-based project."]})]})}function l(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>d,M:()=>s});var o=n(11504);const r={},i=o.createContext(r);function s(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0dc1655b.f9b6ebfa.js b/assets/js/0dc1655b.29a39d46.js similarity index 98% rename from assets/js/0dc1655b.f9b6ebfa.js rename to assets/js/0dc1655b.29a39d46.js index 9cf3d0ed7..6a2e051fe 100644 --- a/assets/js/0dc1655b.f9b6ebfa.js +++ b/assets/js/0dc1655b.29a39d46.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1780],{14308:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=t(17624),o=t(4552);const r={},s="Decentralized Identity Provider (DIP) provider consumer pallet",c={id:"concepts/dip/consumer",title:"Decentralized Identity Provider (DIP) provider consumer pallet",description:"This pallet is a core component of the Decentralized Identity Provider protocol.",source:"@site/docs/concepts/07_dip/03_consumer.md",sourceDirName:"concepts/07_dip",slug:"/concepts/dip/consumer",permalink:"/docs/concepts/dip/consumer",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/07_dip/03_consumer.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:3,frontMatter:{},sidebar:"concepts",previous:{title:"Provider pallet",permalink:"/docs/concepts/dip/provider"},next:{title:"Enabling DIP for user accounts on the KILT blockchain",permalink:"/docs/concepts/dip/dip-accounts-kilt"}},a={},d=[{value:"The Config trait",id:"the-config-trait",level:2},{value:"Storage",id:"storage",level:2},{value:"Origin",id:"origin",level:2},{value:"Calls (bullet numbers represent each call's encoded index)",id:"calls-bullet-numbers-represent-each-calls-encoded-index",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"decentralized-identity-provider-dip-provider-consumer-pallet",children:"Decentralized Identity Provider (DIP) provider consumer pallet"}),"\n",(0,n.jsxs)(i.p,{children:["This pallet is a core component of the Decentralized Identity Provider protocol.\nIt enables entities with an identity on a connected Substrate-based chain (provider) to use those identities on the chain this pallet is deployed (consumers) without requiring those entities to set up a new identity locally.\nA consumer chain is ",(0,n.jsx)(i.em,{children:"connected"})," to a provider if there is a way for the consumer chain to verify state proofs about parts of the state of the provider chain."]}),"\n",(0,n.jsxs)(i.p,{children:["A cross-chain transaction with DIP assumes the entity submitting the transaction has already generated a cross-chain identity commitment on the provider chain, by interacting with the DIP provider pallet on the provider chain.\nWith a generated identity commitment, a cross-chain transaction flow for a generic entity ",(0,n.jsx)(i.code,{children:"A"})," works as follows:"]}),"\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"A"})," generates a state proof proving the state of the identity commitment on the provider chain."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"A"})," generates any additional information required for an identity proof to be successfully verified by the consumer runtime."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"A"}),", using their account ",(0,n.jsx)(i.code,{children:"AccC"})," on the consumer chain, calls the ",(0,n.jsx)(i.code,{children:"dispatch_as"})," extrinsic by providing its identifier on the provider chain, the generated proof, and the ",(0,n.jsx)(i.code,{children:"Call"})," to be dispatched on the consumer chain.","\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsx)(i.li,{children:"This pallet verifies if the proof is correct, if not it returns an error."}),"\n",(0,n.jsxs)(i.li,{children:["This pallet dispatches the provided ",(0,n.jsx)(i.code,{children:"Call"})," with a new origin created by this pallet, returning any errors the dispatch action returns. The origin contains the information revealed in the proof, the identifier of the acting subject and the account ",(0,n.jsx)(i.code,{children:"AccC"})," dispatching the transaction."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(i.p,{children:["The pallet is agnostic over the chain-specific definition of ",(0,n.jsx)(i.em,{children:"identity proof verifier"})," and ",(0,n.jsx)(i.em,{children:"identifier"}),", although, when deployed, they must be configured to respect the definition of identity and identity commitment established by the provider this pallet is linked to."]}),"\n",(0,n.jsx)(i.p,{children:"For instance, if the provider establishes that an identity commitment is a Merkle root of a set of public keys, an identity proof for the consumer will most likely be a Merkle proof revealing a subset of those keys.\nSimilarly, if the provider defines an identity commitment as some ZK-commitment, the respective identity proof on the consumer chain will be a ZK-proof verifying the validity of the commitment and therefore of the revealed information."}),"\n",(0,n.jsxs)(i.p,{children:["For identifiers, if the provider establishes that an identifier is a public key, the same definition must be used in the consumer pallet.\nOther definitions for an identifier, such as a simple integer or a ",(0,n.jsx)(i.a,{href:"https://www.w3.org/TR/did-core/",children:"Decentralized Identifier (DID)"}),", must also be configured in the same way."]}),"\n",(0,n.jsxs)(i.p,{children:["The pallet allows the consumer runtime to define some ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," associated with each identifier, which the pallet's proof verifier can access and optionally modify upon proof verification.\nAny changes made to the ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," will be persisted if the identity proof is verified correctly and the extrinsic executed successfully."]}),"\n",(0,n.jsxs)(i.p,{children:["If the consumer does not need to store anything in addition to the information an identity proof conveys, they can use an empty tuple ",(0,n.jsx)(i.code,{children:"()"})," for the local identity info.\nAnother example could be the use of signatures, which requires a nonce to avoid replay protections.\nIn this case, a numeric type such as a ",(0,n.jsx)(i.code,{children:"u64"})," or a ",(0,n.jsx)(i.code,{children:"u128"})," could be used, and increased by the proof verifier when validating each new cross-chain transaction proof."]}),"\n",(0,n.jsxs)(i.h2,{id:"the-config-trait",children:["The ",(0,n.jsx)(i.code,{children:"Config"})," trait"]}),"\n",(0,n.jsxs)(i.p,{children:["Being chain-agnostic, most of the runtime configurations must be passed to the pallet's ",(0,n.jsx)(i.code,{children:"Config"})," trait.\nNevertheless, most of the types provided must reflect the definition of identity and identity commitment that the identity provider chain has established.\nThe trait has the following components:"]}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type DipCallOriginFilter: Contains>"}),": A preliminary filter that checks whether a provided ",(0,n.jsx)(i.code,{children:"Call"})," accepts a DIP origin or not. If a call such as a system call does not accept a DIP origin, there is no need to verify the identity proof, hence the execution can bail out early. This does not guarantee that the dispatch call will succeed, but rather than it will mostly not fail with a ",(0,n.jsx)(i.code,{children:"BadOrigin"})," error."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type DispatchOriginCheck: EnsureOrigin<::RuntimeOrigin, Success = Self::AccountId>"}),": The origin check on the ",(0,n.jsx)(i.code,{children:"dispatch_as"})," extrinsic to verify that the caller is authorized to call the extrinsic. If successful, the check must return a ",(0,n.jsx)(i.code,{children:"AccountId"})," as defined by the consumer runtime."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type Identifier: Parameter + MaxEncodedLen"}),": The type of a subject identifier. This must match the definition of ",(0,n.jsx)(i.code,{children:"Identifier"})," the identity provider has defined in their deployment of the provider pallet."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type LocalIdentityInfo: FullCodec + TypeInfo + MaxEncodedLen"}),": Any additional information that must be available only to the provider runtime that is required to provide additional context when verifying a cross-chain identity proof."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type ProofVerifier: IdentityProofVerifier"}),": The core component of this pallet. It takes care of validating an identity proof and optionally update any ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"}),". It also defines, via its associated type, the structure of the identity proof that must be passed to the ",(0,n.jsx)(i.code,{children:"dispatch_as"})," extrinsic. Although not directly, the proof structure depends on the information that goes into the identity commitment on the provider chain, as that defines what information can be revealed as part of the commitment proof. Additional info to satisfy requirements according to the ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," (e.g., a signature) must also be provided in the proof."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type RuntimeCall: Parameter + Dispatchable::RuntimeOrigin>"}),": The aggregated ",(0,n.jsx)(i.code,{children:"Call"})," type."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type RuntimeOrigin: From> + From<::RuntimeOrigin>"}),": The aggregated ",(0,n.jsx)(i.code,{children:"Origin"})," type, which must include the origin exposed by this pallet."]}),"\n"]}),"\n",(0,n.jsx)(i.h2,{id:"storage",children:"Storage"}),"\n",(0,n.jsxs)(i.p,{children:["The pallet contains a single storage element, the ",(0,n.jsx)(i.code,{children:"IdentityEntries"})," map.\nIt maps from a subject ",(0,n.jsx)(i.code,{children:"Identifier"})," to an instance of ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"}),"."]}),"\n",(0,n.jsx)(i.p,{children:"This information is updated by the proof verifier whenever a new cross-chain transaction and its proof is submitted."}),"\n",(0,n.jsx)(i.h2,{id:"origin",children:"Origin"}),"\n",(0,n.jsxs)(i.p,{children:["Because the pallet allows other ",(0,n.jsx)(i.code,{children:"Call"}),"s to be dispatched after an identity proof has been verified, it also exposes a ",(0,n.jsx)(i.code,{children:"Origin"})," that can be used for those calls that require indeed a call to be DIP-authorized."]}),"\n",(0,n.jsx)(i.p,{children:"The origin is created after the identity proof has been successfully verified by the proof verifier, and it includes the identifier of the subject, the address of the tx submitter, and the result returned by the proof verifier upon successful verification."}),"\n",(0,n.jsx)(i.h2,{id:"calls-bullet-numbers-represent-each-calls-encoded-index",children:"Calls (bullet numbers represent each call's encoded index)"}),"\n",(0,n.jsxs)(i.ol,{start:"0",children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"pub fn dispatch_as(origin: OriginFor, identifier: T::Identifier, proof: IdentityProofOf, call: Box>) -> DispatchResult"}),": Try to dispatch a new local call only if it passes all the DIP requirements. Specifically, the call will be dispatched if it passes the preliminary ",(0,n.jsx)(i.code,{children:"DipCallOriginFilter"})," and if the proof verifier returns an ",(0,n.jsx)(i.code,{children:"Ok(verification_result)"})," value. The value is then added to the ",(0,n.jsx)(i.code,{children:"DipOrigin"})," and passed down as the origin for the specified ",(0,n.jsx)(i.code,{children:"Call"}),". If the whole execution terminates successfully, any changes applied to the ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," by the proof verifier are persisted to the pallet storage."]}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,o.M)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},4552:(e,i,t)=>{t.d(i,{I:()=>c,M:()=>s});var n=t(11504);const o={},r=n.createContext(o);function s(e){const i=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1780],{14308:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=t(17624),o=t(4552);const r={},s="Decentralized Identity Provider (DIP) provider consumer pallet",c={id:"concepts/dip/consumer",title:"Decentralized Identity Provider (DIP) provider consumer pallet",description:"This pallet is a core component of the Decentralized Identity Provider protocol.",source:"@site/docs/concepts/07_dip/03_consumer.md",sourceDirName:"concepts/07_dip",slug:"/concepts/dip/consumer",permalink:"/docs/concepts/dip/consumer",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/07_dip/03_consumer.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:3,frontMatter:{},sidebar:"concepts",previous:{title:"Provider pallet",permalink:"/docs/concepts/dip/provider"},next:{title:"Enabling DIP for user accounts on the KILT blockchain",permalink:"/docs/concepts/dip/dip-accounts-kilt"}},a={},d=[{value:"The Config trait",id:"the-config-trait",level:2},{value:"Storage",id:"storage",level:2},{value:"Origin",id:"origin",level:2},{value:"Calls (bullet numbers represent each call's encoded index)",id:"calls-bullet-numbers-represent-each-calls-encoded-index",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"decentralized-identity-provider-dip-provider-consumer-pallet",children:"Decentralized Identity Provider (DIP) provider consumer pallet"}),"\n",(0,n.jsxs)(i.p,{children:["This pallet is a core component of the Decentralized Identity Provider protocol.\nIt enables entities with an identity on a connected Substrate-based chain (provider) to use those identities on the chain this pallet is deployed (consumers) without requiring those entities to set up a new identity locally.\nA consumer chain is ",(0,n.jsx)(i.em,{children:"connected"})," to a provider if there is a way for the consumer chain to verify state proofs about parts of the state of the provider chain."]}),"\n",(0,n.jsxs)(i.p,{children:["A cross-chain transaction with DIP assumes the entity submitting the transaction has already generated a cross-chain identity commitment on the provider chain, by interacting with the DIP provider pallet on the provider chain.\nWith a generated identity commitment, a cross-chain transaction flow for a generic entity ",(0,n.jsx)(i.code,{children:"A"})," works as follows:"]}),"\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"A"})," generates a state proof proving the state of the identity commitment on the provider chain."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"A"})," generates any additional information required for an identity proof to be successfully verified by the consumer runtime."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"A"}),", using their account ",(0,n.jsx)(i.code,{children:"AccC"})," on the consumer chain, calls the ",(0,n.jsx)(i.code,{children:"dispatch_as"})," extrinsic by providing its identifier on the provider chain, the generated proof, and the ",(0,n.jsx)(i.code,{children:"Call"})," to be dispatched on the consumer chain.","\n",(0,n.jsxs)(i.ol,{children:["\n",(0,n.jsx)(i.li,{children:"This pallet verifies if the proof is correct, if not it returns an error."}),"\n",(0,n.jsxs)(i.li,{children:["This pallet dispatches the provided ",(0,n.jsx)(i.code,{children:"Call"})," with a new origin created by this pallet, returning any errors the dispatch action returns. The origin contains the information revealed in the proof, the identifier of the acting subject and the account ",(0,n.jsx)(i.code,{children:"AccC"})," dispatching the transaction."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(i.p,{children:["The pallet is agnostic over the chain-specific definition of ",(0,n.jsx)(i.em,{children:"identity proof verifier"})," and ",(0,n.jsx)(i.em,{children:"identifier"}),", although, when deployed, they must be configured to respect the definition of identity and identity commitment established by the provider this pallet is linked to."]}),"\n",(0,n.jsx)(i.p,{children:"For instance, if the provider establishes that an identity commitment is a Merkle root of a set of public keys, an identity proof for the consumer will most likely be a Merkle proof revealing a subset of those keys.\nSimilarly, if the provider defines an identity commitment as some ZK-commitment, the respective identity proof on the consumer chain will be a ZK-proof verifying the validity of the commitment and therefore of the revealed information."}),"\n",(0,n.jsxs)(i.p,{children:["For identifiers, if the provider establishes that an identifier is a public key, the same definition must be used in the consumer pallet.\nOther definitions for an identifier, such as a simple integer or a ",(0,n.jsx)(i.a,{href:"https://www.w3.org/TR/did-core/",children:"Decentralized Identifier (DID)"}),", must also be configured in the same way."]}),"\n",(0,n.jsxs)(i.p,{children:["The pallet allows the consumer runtime to define some ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," associated with each identifier, which the pallet's proof verifier can access and optionally modify upon proof verification.\nAny changes made to the ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," will be persisted if the identity proof is verified correctly and the extrinsic executed successfully."]}),"\n",(0,n.jsxs)(i.p,{children:["If the consumer does not need to store anything in addition to the information an identity proof conveys, they can use an empty tuple ",(0,n.jsx)(i.code,{children:"()"})," for the local identity info.\nAnother example could be the use of signatures, which requires a nonce to avoid replay protections.\nIn this case, a numeric type such as a ",(0,n.jsx)(i.code,{children:"u64"})," or a ",(0,n.jsx)(i.code,{children:"u128"})," could be used, and increased by the proof verifier when validating each new cross-chain transaction proof."]}),"\n",(0,n.jsxs)(i.h2,{id:"the-config-trait",children:["The ",(0,n.jsx)(i.code,{children:"Config"})," trait"]}),"\n",(0,n.jsxs)(i.p,{children:["Being chain-agnostic, most of the runtime configurations must be passed to the pallet's ",(0,n.jsx)(i.code,{children:"Config"})," trait.\nNevertheless, most of the types provided must reflect the definition of identity and identity commitment that the identity provider chain has established.\nThe trait has the following components:"]}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type DipCallOriginFilter: Contains>"}),": A preliminary filter that checks whether a provided ",(0,n.jsx)(i.code,{children:"Call"})," accepts a DIP origin or not. If a call such as a system call does not accept a DIP origin, there is no need to verify the identity proof, hence the execution can bail out early. This does not guarantee that the dispatch call will succeed, but rather than it will mostly not fail with a ",(0,n.jsx)(i.code,{children:"BadOrigin"})," error."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type DispatchOriginCheck: EnsureOrigin<::RuntimeOrigin, Success = Self::AccountId>"}),": The origin check on the ",(0,n.jsx)(i.code,{children:"dispatch_as"})," extrinsic to verify that the caller is authorized to call the extrinsic. If successful, the check must return a ",(0,n.jsx)(i.code,{children:"AccountId"})," as defined by the consumer runtime."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type Identifier: Parameter + MaxEncodedLen"}),": The type of a subject identifier. This must match the definition of ",(0,n.jsx)(i.code,{children:"Identifier"})," the identity provider has defined in their deployment of the provider pallet."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type LocalIdentityInfo: FullCodec + TypeInfo + MaxEncodedLen"}),": Any additional information that must be available only to the provider runtime that is required to provide additional context when verifying a cross-chain identity proof."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type ProofVerifier: IdentityProofVerifier"}),": The core component of this pallet. It takes care of validating an identity proof and optionally update any ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"}),". It also defines, via its associated type, the structure of the identity proof that must be passed to the ",(0,n.jsx)(i.code,{children:"dispatch_as"})," extrinsic. Although not directly, the proof structure depends on the information that goes into the identity commitment on the provider chain, as that defines what information can be revealed as part of the commitment proof. Additional info to satisfy requirements according to the ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," (e.g., a signature) must also be provided in the proof."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type RuntimeCall: Parameter + Dispatchable::RuntimeOrigin>"}),": The aggregated ",(0,n.jsx)(i.code,{children:"Call"})," type."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"type RuntimeOrigin: From> + From<::RuntimeOrigin>"}),": The aggregated ",(0,n.jsx)(i.code,{children:"Origin"})," type, which must include the origin exposed by this pallet."]}),"\n"]}),"\n",(0,n.jsx)(i.h2,{id:"storage",children:"Storage"}),"\n",(0,n.jsxs)(i.p,{children:["The pallet contains a single storage element, the ",(0,n.jsx)(i.code,{children:"IdentityEntries"})," map.\nIt maps from a subject ",(0,n.jsx)(i.code,{children:"Identifier"})," to an instance of ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"}),"."]}),"\n",(0,n.jsx)(i.p,{children:"This information is updated by the proof verifier whenever a new cross-chain transaction and its proof is submitted."}),"\n",(0,n.jsx)(i.h2,{id:"origin",children:"Origin"}),"\n",(0,n.jsxs)(i.p,{children:["Because the pallet allows other ",(0,n.jsx)(i.code,{children:"Call"}),"s to be dispatched after an identity proof has been verified, it also exposes a ",(0,n.jsx)(i.code,{children:"Origin"})," that can be used for those calls that require indeed a call to be DIP-authorized."]}),"\n",(0,n.jsx)(i.p,{children:"The origin is created after the identity proof has been successfully verified by the proof verifier, and it includes the identifier of the subject, the address of the tx submitter, and the result returned by the proof verifier upon successful verification."}),"\n",(0,n.jsx)(i.h2,{id:"calls-bullet-numbers-represent-each-calls-encoded-index",children:"Calls (bullet numbers represent each call's encoded index)"}),"\n",(0,n.jsxs)(i.ol,{start:"0",children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.code,{children:"pub fn dispatch_as(origin: OriginFor, identifier: T::Identifier, proof: IdentityProofOf, call: Box>) -> DispatchResult"}),": Try to dispatch a new local call only if it passes all the DIP requirements. Specifically, the call will be dispatched if it passes the preliminary ",(0,n.jsx)(i.code,{children:"DipCallOriginFilter"})," and if the proof verifier returns an ",(0,n.jsx)(i.code,{children:"Ok(verification_result)"})," value. The value is then added to the ",(0,n.jsx)(i.code,{children:"DipOrigin"})," and passed down as the origin for the specified ",(0,n.jsx)(i.code,{children:"Call"}),". If the whole execution terminates successfully, any changes applied to the ",(0,n.jsx)(i.code,{children:"LocalIdentityInfo"})," by the proof verifier are persisted to the pallet storage."]}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,o.M)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},4552:(e,i,t)=>{t.d(i,{I:()=>c,M:()=>s});var n=t(11504);const o={},r=n.createContext(o);function s(e){const i=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(r.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/107f4b3b.812c14d8.js b/assets/js/107f4b3b.8e19fd56.js similarity index 85% rename from assets/js/107f4b3b.812c14d8.js rename to assets/js/107f4b3b.8e19fd56.js index bc406e245..a611bee40 100644 --- a/assets/js/107f4b3b.812c14d8.js +++ b/assets/js/107f4b3b.8e19fd56.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5624],{41516:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var n=i(17624),s=i(4552),o=i(77440);const a={id:"exit",title:"Leave the Set of Delegators"},r=void 0,c={id:"participate/staking/delegate/exit",title:"Leave the Set of Delegators",description:"A Delegator can revoke their delegation by calling parachainStaking -> leaveDelegators.",source:"@site/docs/participate/01_staking/03_delegate/04_exit.md",sourceDirName:"participate/01_staking/03_delegate",slug:"/participate/staking/delegate/exit",permalink:"/docs/participate/staking/delegate/exit",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/03_delegate/04_exit.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:4,frontMatter:{id:"exit",title:"Leave the Set of Delegators"},sidebar:"staking",previous:{title:"Adjust Your Delegation Stake",permalink:"/docs/participate/staking/delegate/adjust-stake"},next:{title:"Lifecycle of a Delegator",permalink:"/docs/participate/staking/delegate/lifecycle"}},l={},d=[];function p(e){const t={a:"a",code:"code",em:"em",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["A Delegator can revoke their delegation by calling ",(0,n.jsx)(t.code,{children:"parachainStaking -> leaveDelegators"}),".\nAs a result, you won't receive any rewards immediately after the transaction is successfully executed."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Your previously delegated amount will be prepared for unstaking."}),"\n",(0,n.jsxs)(t.li,{children:["You need to wait 7 days (in block time) before you can unlock your unstaked tokens, see the section ",(0,n.jsx)(t.a,{href:"/docs/participate/staking/unlock-unstaked",children:"Unlock Unstaked"})," for more information."]}),"\n",(0,n.jsx)(t.li,{children:"Exiting does not count towards the limit of \u201c1 delegation per round\u201d."}),"\n"]}),"\n",(0,n.jsx)(o.cp,{}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(7688).c+"",width:"1998",height:"922"})}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Select the KILT address you delegated from as the extrinsic submitter (the ",(0,n.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,n.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,n.jsx)(t.code,{children:"parachainStaking -> leaveDelegators"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,n.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},77440:(e,t,i)=>{i.d(t,{cp:()=>a});var n=i(17624),s=i(4552);function o(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",strong:"strong",...(0,s.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{type:"info",children:(0,n.jsxs)(t.p,{children:["You can either execute this transaction in Polkadot JS Apps or the ",(0,n.jsx)(t.a,{href:"/docs/develop/builtonkilt#web-apps",children:(0,n.jsx)(t.strong,{children:"KILT Stakeboard"})}),", which serves as an in-house developed Frontend for all KILT staking activity.\nBelow, we outline the steps for Polkadot JS Apps.\nThe process for KILT Stakeboard is described in detail in the ",(0,n.jsx)(t.a,{href:"https://support.kilt.io/support/solutions/80000442174",children:(0,n.jsx)(t.strong,{children:"BOTLabs Trusted Entity support hub"})}),"."]})}),"\n",(0,n.jsxs)(t.p,{children:["In the Polkadot JS Apps (",(0,n.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer",children:"wss://spiritnet.kilt.io"}),", or ",(0,n.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer",children:"wss://peregrine.kilt.io"}),") go to ",(0,n.jsx)(t.code,{children:"Developer -> Extrinsics -> Submission"}),"."]})]})}function a(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(o,{...e})}):o(e)}},7688:(e,t,i)=>{i.d(t,{c:()=>n});const n=i.p+"assets/images/parachainStaking-leaveDelegators-19bb6f352d0c3d5bfc92923a741c9e4c.png"},4552:(e,t,i)=>{i.d(t,{I:()=>r,M:()=>a});var n=i(11504);const s={},o=n.createContext(s);function a(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5624],{41516:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var n=i(17624),s=i(4552),o=i(77440);const r={id:"exit",title:"Leave the Set of Delegators"},a=void 0,c={id:"participate/staking/delegate/exit",title:"Leave the Set of Delegators",description:"A Delegator can revoke their delegation by calling parachainStaking -> leaveDelegators.",source:"@site/docs/participate/01_staking/03_delegate/04_exit.md",sourceDirName:"participate/01_staking/03_delegate",slug:"/participate/staking/delegate/exit",permalink:"/docs/participate/staking/delegate/exit",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/03_delegate/04_exit.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:4,frontMatter:{id:"exit",title:"Leave the Set of Delegators"},sidebar:"staking",previous:{title:"Adjust Your Delegation Stake",permalink:"/docs/participate/staking/delegate/adjust-stake"},next:{title:"Lifecycle of a Delegator",permalink:"/docs/participate/staking/delegate/lifecycle"}},l={},d=[];function p(e){const t={a:"a",code:"code",em:"em",img:"img",li:"li",ol:"ol",p:"p",ul:"ul",...(0,s.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["A Delegator can revoke their delegation by calling ",(0,n.jsx)(t.code,{children:"parachainStaking -> leaveDelegators"}),".\nAs a result, you won't receive any rewards immediately after the transaction is successfully executed."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Your previously delegated amount will be prepared for unstaking."}),"\n",(0,n.jsxs)(t.li,{children:["You need to wait 7 days (in block time) before you can unlock your unstaked tokens, see the section ",(0,n.jsx)(t.a,{href:"/docs/participate/staking/unlock-unstaked",children:"Unlock Unstaked"})," for more information."]}),"\n",(0,n.jsx)(t.li,{children:"Exiting does not count towards the limit of \u201c1 delegation per round\u201d."}),"\n"]}),"\n",(0,n.jsx)(o.cp,{}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:i(7688).c+"",width:"1998",height:"922"})}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["Select the KILT address you delegated from as the extrinsic submitter (the ",(0,n.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,n.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,n.jsx)(t.code,{children:"parachainStaking -> leaveDelegators"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,n.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},77440:(e,t,i)=>{i.d(t,{cp:()=>r});var n=i(17624),s=i(4552);function o(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",strong:"strong",...(0,s.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{type:"info",children:(0,n.jsxs)(t.p,{children:["You can either execute this transaction in Polkadot JS Apps or the ",(0,n.jsx)(t.a,{href:"/docs/develop/builtonkilt#web-apps",children:(0,n.jsx)(t.strong,{children:"KILT Stakeboard"})}),", which serves as an in-house developed Frontend for all KILT staking activity.\nBelow, we outline the steps for Polkadot JS Apps.\nThe process for KILT Stakeboard is described in detail in the ",(0,n.jsx)(t.a,{href:"https://support.kilt.io/support/solutions/80000442174",children:(0,n.jsx)(t.strong,{children:"BOTLabs Trusted Entity support hub"})}),"."]})}),"\n",(0,n.jsxs)(t.p,{children:["In the Polkadot JS Apps (",(0,n.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer",children:"wss://spiritnet.kilt.io"}),", or ",(0,n.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer",children:"wss://peregrine.kilt.io"}),") go to ",(0,n.jsx)(t.code,{children:"Developer -> Extrinsics -> Submission"}),"."]})]})}function r(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(o,{...e})}):o(e)}},7688:(e,t,i)=>{i.d(t,{c:()=>n});const n=i.p+"assets/images/parachainStaking-leaveDelegators-19bb6f352d0c3d5bfc92923a741c9e4c.png"},4552:(e,t,i)=>{i.d(t,{I:()=>a,M:()=>r});var n=i(11504);const s={},o=n.createContext(s);function r(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1291f88a.3ef55582.js b/assets/js/1291f88a.64862138.js similarity index 99% rename from assets/js/1291f88a.3ef55582.js rename to assets/js/1291f88a.64862138.js index 1b5bef39c..344b46882 100644 --- a/assets/js/1291f88a.3ef55582.js +++ b/assets/js/1291f88a.64862138.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7112],{17584:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>l,toc:()=>h});var i=t(17624),o=t(4552),r=t(61268),a=t(87768);const s={id:"dapp-developer",title:"Dapp developer"},c=void 0,l={id:"concepts/dip/dapp-developer",title:"Dapp developer",description:"The Decentralized Identity Provider (DIP) SDK helps Dapp developers build DIP functionality into their apps.",source:"@site/docs/concepts/07_dip/05_dapp_developer.md",sourceDirName:"concepts/07_dip",slug:"/concepts/dip/dapp-developer",permalink:"/docs/concepts/dip/dapp-developer",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/07_dip/05_dapp_developer.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:5,frontMatter:{id:"dapp-developer",title:"Dapp developer"},sidebar:"concepts",previous:{title:"Enabling DIP for user accounts on the KILT blockchain",permalink:"/docs/concepts/dip/dip-accounts-kilt"},next:{title:"KILT Messaging",permalink:"/docs/concepts/messaging"}},d={},h=[{value:"Installation",id:"installation",level:2},{value:"Example application",id:"example-application",level:2},{value:"1. Generate a base proof",id:"1-generate-a-base-proof",level:3},{value:"2. Generate a submittable extrinsic",id:"2-generate-a-submittable-extrinsic",level:3},{value:"3. Linking accounts (optional)",id:"3-linking-accounts-optional",level:3},{value:"Creating extensions for specific proofs",id:"creating-extensions-for-specific-proofs",level:2}];function u(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.admonition,{title:"DIP",type:"version-label"}),"\n",(0,i.jsx)(n.p,{children:"The Decentralized Identity Provider (DIP) SDK helps Dapp developers build DIP functionality into their apps."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.p,{children:"Add the SDK as a dependency:"}),"\n",(0,i.jsxs)(r.c,{groupId:"npm2yarn",children:[(0,i.jsx)(a.c,{value:"npm",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"npm install @kiltprotocol/dip-sdk\n"})})}),(0,i.jsx)(a.c,{value:"yarn",label:"Yarn",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"yarn add @kiltprotocol/dip-sdk\n"})})}),(0,i.jsx)(a.c,{value:"pnpm",label:"pnpm",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pnpm add @kiltprotocol/dip-sdk\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"Import the SDK into your code:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"import { * } from '@kiltprotocol/dip-sdk'\n"})}),"\n",(0,i.jsx)(n.h2,{id:"example-application",children:"Example application"}),"\n",(0,i.jsx)(n.p,{children:"This example application walks through the code you can find in the tests for the DIP SDK."}),"\n",(0,i.jsx)(n.h3,{id:"1-generate-a-base-proof",children:"1. Generate a base proof"}),"\n",(0,i.jsxs)(n.p,{children:["Start by generating the base proof for the DIP using the ",(0,i.jsx)(n.code,{children:"[generateDipSiblingBaseProof](https://kiltprotocol.github.io/dip-sdk/functions/generateDipSiblingBaseProof.html)"})," method and passing the desired configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const baseDipProof = await DipSdk.generateDipSiblingBaseProof(config)\n"})}),"\n",(0,i.jsx)(n.admonition,{title:"What's a base proof?",type:"info",children:(0,i.jsx)(n.p,{children:"A base proof is a cross-chain state proof, revealing the parts of a DID Document stored on the KILT blockchain."})}),"\n",(0,i.jsx)(n.p,{children:"The configuration for the base proof takes the following parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"didUri"}),": (Required) The DID URI of the DIP subject performing the cross-chain operation.\nFor example, ",(0,i.jsx)(n.code,{children:"did:kilt:4q4QzFTs9hKh4QizLB3B7zuGYCG3QPamiBFEgwM6gTM7gK3g"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"keyIds"}),": (Required) An array of verification method IDs of the DID revealed in the cross-chain operation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"proofVersion"}),": (Required) The version of the DIP proof to generate.\nCurrently only supports version 1."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"blockNumber"}),": The block number of the relay chain to use for the generation of the DIP proof.\nIf not provided, uses the last finalized block."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"linkedAccounts"}),": An array of ",(0,i.jsx)(n.a,{href:"/docs/develop/sdk/cookbook/account_linking/account-link##linking-an-account-to-a-did",children:"account addresses linked to the DID"})," to reveal in the generated proof."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"web3Name"}),": Whether to reveal ",(0,i.jsx)(n.a,{href:"/docs/develop/sdk/cookbook/web3names/web3name-claim",children:"the web3name of the DID subject"})," in the generated proof."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In the example code, the configuration also has extra parameters for the time-bound DID signature extension ",(0,i.jsx)(n.a,{href:"#creating-extensions-for-specific-proofs",children:"mentioned below"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The configuration also has details of the provider, which in this case uses a value populated from an environment variable:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const providerAddress = `ws://127.0.0.1:${process.env['PROVIDER_ALICE_RPC']}`\n"})}),"\n",(0,i.jsx)(n.h3,{id:"2-generate-a-submittable-extrinsic",children:"2. Generate a submittable extrinsic"}),"\n",(0,i.jsxs)(n.p,{children:["The method returns the DID base proof.\nYou have to call a second method, the ",(0,i.jsx)(n.code,{children:"[generateDipSubmittableExtrinsic](https://kiltprotocol.github.io/dip-sdk/functions/generateDipSubmittableExtrinsic.html)"})," method to generate a submittable extrinsic that includes the generated proof."]}),"\n",(0,i.jsx)(n.p,{children:"You need to pass the following parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The API of the consumer chain."}),"\n",(0,i.jsx)(n.li,{children:"The base proof."}),"\n",(0,i.jsx)(n.li,{children:"The call to the consumer chain."}),"\n",(0,i.jsx)(n.li,{children:"The DID URI."}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"Submittable extrinsics",type:"info",children:(0,i.jsx)(n.p,{children:"A transaction that originates from an external account and affects the state of the blockchain.\nAn extrinisc executes actions on the network, such as transferring funds, making governance decisions, using functionality of the parachain, or interacting with smart contracts."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const dipSubmittable = DipSdk.generateDipSubmittableExtrinsic({\n api: consumerApi,\n baseDipProof,\n call,\n didUri: did.uri,\n})\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The method returns the different components of the proof, ",(0,i.jsx)(n.a,{href:"https://github.com/KILTprotocol/dip-sdk/blob/9ad141b3757e076744ab8b2d29bcf10bbeaddd9f/tests/dip-provider-template-dip-consumer-template/develop.test.ts#L219",children:"which you can see in the example code"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The provider head proof, which is proof of the provider parachain header on the relay chain."}),"\n",(0,i.jsx)(n.li,{children:"The commitment proof, which proves the DIP commitment for the subject of the action, which is the DID URI."}),"\n",(0,i.jsx)(n.li,{children:"The DID proof, which reveals parts of the DID document as specified by key IDs, proof version, and whether to include the web3name and any of its linked accounts."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Behind the scenes, the method uses the ",(0,i.jsx)(n.code,{children:"dispatchAs"})," method (",(0,i.jsx)(n.a,{href:"https://github.com/KILTprotocol/kilt-node/blob/4ddb8a0ef6258873458f19d3ee9dcb6d7c24e645/pallets/did/src/lib.rs#L1152",children:"and corresponding chain method"}),") to pass the extrinsic following the consumer's type registry.\nYou can now sign and submit to the consumer chain."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"await signAndSubmitTx(consumerApi, dipSubmittable, submitterKeypair)\n"})}),"\n",(0,i.jsx)(n.h3,{id:"3-linking-accounts-optional",children:"3. Linking accounts (optional)"}),"\n",(0,i.jsx)(n.p,{children:"Linked accounts let you specify which accounts you want to prove that you control when you make the cross-chain proof.\nAs part of the proof provided, you can also include other values, such as the web3name."}),"\n",(0,i.jsxs)(n.p,{children:["For all the accounts you want to link, use the ",(0,i.jsx)(n.code,{children:"associateAccountToChainArgs"})," method, ",(0,i.jsx)(n.a,{href:"/docs/develop/sdk/cookbook/account_linking/account-link##linking-an-account-to-a-did",children:"as detailed in this guide"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can then batch all the linked account transactions and authorize them using the ",(0,i.jsx)(n.code,{children:"authorizeTx"})," method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const signedLinkedAccounts = await Kilt.Did.authorizeTx(\n newFullDidUri,\n providerApi.tx.utility.batchAll(linkAccountTxs),\n signCallback,\n newSubmitterKeypair.address as KiltAddress,\n { txCounter: new BN(4) }\n)\n"})}),"\n",(0,i.jsx)(n.h2,{id:"creating-extensions-for-specific-proofs",children:"Creating extensions for specific proofs"}),"\n",(0,i.jsxs)(n.p,{children:["If you need a specific proof type for a consumer chain, then a chain developer needs to submit a PR to the SDK repository in the ",(0,i.jsx)(n.code,{children:"src > dipProof > extensions"})," folder.\nThe extension included with the SDK adds support for a time-bound DID signature, i.e., a signature which is valid only until a certain block number on the consumer chain."]}),"\n",(0,i.jsxs)(n.p,{children:["The extension can take any form, but must return ",(0,i.jsx)(n.a,{href:"https://docs.substrate.io/reference/scale-codec/",children:"a SCALE encoded"})," object.\nThere's an example of how the extension does this ",(0,i.jsx)(n.a,{href:"https://github.com/KILTprotocol/dip-sdk/blob/9ad141b3757e076744ab8b2d29bcf10bbeaddd9f/src/dipProof/extensions/timeBoundDidSignature.ts#L113",children:"on GitHub"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["To add the extension, use the ",(0,i.jsx)(n.code,{children:"generateDipSubmittableExtrinsic"})," method and pass the additional proof elements along with consumer chain specific components."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const dipSubmittable = DipSdk.generateDipSubmittableExtrinsic({\n additionalProofElements:\n DipSdk.dipProof.extensions.timeBoundDidSignature.toChain(\n crossChainDidSignature\n ),\n api: consumerApi,\n baseDipProof,\n call,\n didUri: did.uri,\n})\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Read the auto-generated ",(0,i.jsx)(n.a,{href:"https://kiltprotocol.github.io/dip-sdk",children:"API documentation"})," for more details on the methods the SDK provides."]})})]})}function p(e={}){const{wrapper:n}={...(0,o.M)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},87768:(e,n,t)=>{t.d(n,{c:()=>a});t(11504);var i=t(65456);const o={tabItem:"tabItem_Ymn6"};var r=t(17624);function a(e){let{children:n,hidden:t,className:a}=e;return(0,r.jsx)("div",{role:"tabpanel",className:(0,i.c)(o.tabItem,a),hidden:t,children:n})}},61268:(e,n,t)=>{t.d(n,{c:()=>D});var i=t(11504),o=t(65456),r=t(53943),a=t(55592),s=t(95288),c=t(10632),l=t(27128),d=t(21148);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:t}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:t,attributes:i,default:o}}=e;return{value:n,label:t,attributes:i,default:o}}))}(t);return function(e){const n=(0,l.w)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function p(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:t}=e;const o=(0,a.Uz)(),r=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,c._M)(r),(0,i.useCallback)((e=>{if(!r)return;const n=new URLSearchParams(o.location.search);n.set(r,e),o.replace({...o.location,search:n.toString()})}),[r,o])]}function m(e){const{defaultValue:n,queryString:t=!1,groupId:o}=e,r=u(e),[a,c]=(0,i.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const i=t.find((e=>e.default))??t[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:n,tabValues:r}))),[l,h]=f({queryString:t,groupId:o}),[m,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[o,r]=(0,d.IN)(t);return[o,(0,i.useCallback)((e=>{t&&r.set(e)}),[t,r])]}({groupId:o}),x=(()=>{const e=l??m;return p({value:e,tabValues:r})?e:null})();(0,s.c)((()=>{x&&c(x)}),[x]);return{selectedValue:a,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);c(e),h(e),b(e)}),[h,b,r]),tabValues:r}}var b=t(93664);const x={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var g=t(17624);function j(e){let{className:n,block:t,selectedValue:i,selectValue:a,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:l}=(0,r.MV)(),d=e=>{const n=e.currentTarget,t=c.indexOf(n),o=s[t].value;o!==i&&(l(n),a(o))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}n?.focus()};return(0,g.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.c)("tabs",{"tabs--block":t},n),children:s.map((e=>{let{value:n,label:t,attributes:r}=e;return(0,g.jsx)("li",{role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,ref:e=>c.push(e),onKeyDown:h,onClick:d,...r,className:(0,o.c)("tabs__item",x.tabItem,r?.className,{"tabs__item--active":i===n}),children:t??n},n)}))})}function v(e){let{lazy:n,children:t,selectedValue:o}=e;const r=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===o));return e?(0,i.cloneElement)(e,{className:"margin-top--md"}):null}return(0,g.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==o})))})}function k(e){const n=m(e);return(0,g.jsxs)("div",{className:(0,o.c)("tabs-container",x.tabList),children:[(0,g.jsx)(j,{...e,...n}),(0,g.jsx)(v,{...e,...n})]})}function D(e){const n=(0,b.c)();return(0,g.jsx)(k,{...e,children:h(e.children)},String(n))}},4552:(e,n,t)=>{t.d(n,{I:()=>s,M:()=>a});var i=t(11504);const o={},r=i.createContext(o);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[7112],{17584:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>l,toc:()=>h});var i=t(17624),o=t(4552),r=t(61268),a=t(87768);const s={id:"dapp-developer",title:"Dapp developer"},c=void 0,l={id:"concepts/dip/dapp-developer",title:"Dapp developer",description:"The Decentralized Identity Provider (DIP) SDK helps Dapp developers build DIP functionality into their apps.",source:"@site/docs/concepts/07_dip/05_dapp_developer.md",sourceDirName:"concepts/07_dip",slug:"/concepts/dip/dapp-developer",permalink:"/docs/concepts/dip/dapp-developer",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/07_dip/05_dapp_developer.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:5,frontMatter:{id:"dapp-developer",title:"Dapp developer"},sidebar:"concepts",previous:{title:"Enabling DIP for user accounts on the KILT blockchain",permalink:"/docs/concepts/dip/dip-accounts-kilt"},next:{title:"KILT Messaging",permalink:"/docs/concepts/messaging"}},d={},h=[{value:"Installation",id:"installation",level:2},{value:"Example application",id:"example-application",level:2},{value:"1. Generate a base proof",id:"1-generate-a-base-proof",level:3},{value:"2. Generate a submittable extrinsic",id:"2-generate-a-submittable-extrinsic",level:3},{value:"3. Linking accounts (optional)",id:"3-linking-accounts-optional",level:3},{value:"Creating extensions for specific proofs",id:"creating-extensions-for-specific-proofs",level:2}];function u(e){const n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.admonition,{title:"DIP",type:"version-label"}),"\n",(0,i.jsx)(n.p,{children:"The Decentralized Identity Provider (DIP) SDK helps Dapp developers build DIP functionality into their apps."}),"\n",(0,i.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,i.jsx)(n.p,{children:"Add the SDK as a dependency:"}),"\n",(0,i.jsxs)(r.c,{groupId:"npm2yarn",children:[(0,i.jsx)(a.c,{value:"npm",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"npm install @kiltprotocol/dip-sdk\n"})})}),(0,i.jsx)(a.c,{value:"yarn",label:"Yarn",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"yarn add @kiltprotocol/dip-sdk\n"})})}),(0,i.jsx)(a.c,{value:"pnpm",label:"pnpm",children:(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pnpm add @kiltprotocol/dip-sdk\n"})})})]}),"\n",(0,i.jsx)(n.p,{children:"Import the SDK into your code:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"import { * } from '@kiltprotocol/dip-sdk'\n"})}),"\n",(0,i.jsx)(n.h2,{id:"example-application",children:"Example application"}),"\n",(0,i.jsx)(n.p,{children:"This example application walks through the code you can find in the tests for the DIP SDK."}),"\n",(0,i.jsx)(n.h3,{id:"1-generate-a-base-proof",children:"1. Generate a base proof"}),"\n",(0,i.jsxs)(n.p,{children:["Start by generating the base proof for the DIP using the ",(0,i.jsx)(n.code,{children:"[generateDipSiblingBaseProof](https://kiltprotocol.github.io/dip-sdk/functions/generateDipSiblingBaseProof.html)"})," method and passing the desired configuration:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const baseDipProof = await DipSdk.generateDipSiblingBaseProof(config)\n"})}),"\n",(0,i.jsx)(n.admonition,{title:"What's a base proof?",type:"info",children:(0,i.jsx)(n.p,{children:"A base proof is a cross-chain state proof, revealing the parts of a DID Document stored on the KILT blockchain."})}),"\n",(0,i.jsx)(n.p,{children:"The configuration for the base proof takes the following parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"didUri"}),": (Required) The DID URI of the DIP subject performing the cross-chain operation.\nFor example, ",(0,i.jsx)(n.code,{children:"did:kilt:4q4QzFTs9hKh4QizLB3B7zuGYCG3QPamiBFEgwM6gTM7gK3g"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"keyIds"}),": (Required) An array of verification method IDs of the DID revealed in the cross-chain operation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"proofVersion"}),": (Required) The version of the DIP proof to generate.\nCurrently only supports version 1."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"blockNumber"}),": The block number of the relay chain to use for the generation of the DIP proof.\nIf not provided, uses the last finalized block."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"linkedAccounts"}),": An array of ",(0,i.jsx)(n.a,{href:"/docs/develop/sdk/cookbook/account_linking/account-link##linking-an-account-to-a-did",children:"account addresses linked to the DID"})," to reveal in the generated proof."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"web3Name"}),": Whether to reveal ",(0,i.jsx)(n.a,{href:"/docs/develop/sdk/cookbook/web3names/web3name-claim",children:"the web3name of the DID subject"})," in the generated proof."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In the example code, the configuration also has extra parameters for the time-bound DID signature extension ",(0,i.jsx)(n.a,{href:"#creating-extensions-for-specific-proofs",children:"mentioned below"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"The configuration also has details of the provider, which in this case uses a value populated from an environment variable:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const providerAddress = `ws://127.0.0.1:${process.env['PROVIDER_ALICE_RPC']}`\n"})}),"\n",(0,i.jsx)(n.h3,{id:"2-generate-a-submittable-extrinsic",children:"2. Generate a submittable extrinsic"}),"\n",(0,i.jsxs)(n.p,{children:["The method returns the DID base proof.\nYou have to call a second method, the ",(0,i.jsx)(n.code,{children:"[generateDipSubmittableExtrinsic](https://kiltprotocol.github.io/dip-sdk/functions/generateDipSubmittableExtrinsic.html)"})," method to generate a submittable extrinsic that includes the generated proof."]}),"\n",(0,i.jsx)(n.p,{children:"You need to pass the following parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The API of the consumer chain."}),"\n",(0,i.jsx)(n.li,{children:"The base proof."}),"\n",(0,i.jsx)(n.li,{children:"The call to the consumer chain."}),"\n",(0,i.jsx)(n.li,{children:"The DID URI."}),"\n"]}),"\n",(0,i.jsx)(n.admonition,{title:"Submittable extrinsics",type:"info",children:(0,i.jsx)(n.p,{children:"A transaction that originates from an external account and affects the state of the blockchain.\nAn extrinisc executes actions on the network, such as transferring funds, making governance decisions, using functionality of the parachain, or interacting with smart contracts."})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const dipSubmittable = DipSdk.generateDipSubmittableExtrinsic({\n api: consumerApi,\n baseDipProof,\n call,\n didUri: did.uri,\n})\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The method returns the different components of the proof, ",(0,i.jsx)(n.a,{href:"https://github.com/KILTprotocol/dip-sdk/blob/9ad141b3757e076744ab8b2d29bcf10bbeaddd9f/tests/dip-provider-template-dip-consumer-template/develop.test.ts#L219",children:"which you can see in the example code"}),":"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The provider head proof, which is proof of the provider parachain header on the relay chain."}),"\n",(0,i.jsx)(n.li,{children:"The commitment proof, which proves the DIP commitment for the subject of the action, which is the DID URI."}),"\n",(0,i.jsx)(n.li,{children:"The DID proof, which reveals parts of the DID document as specified by key IDs, proof version, and whether to include the web3name and any of its linked accounts."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Behind the scenes, the method uses the ",(0,i.jsx)(n.code,{children:"dispatchAs"})," method (",(0,i.jsx)(n.a,{href:"https://github.com/KILTprotocol/kilt-node/blob/4ddb8a0ef6258873458f19d3ee9dcb6d7c24e645/pallets/did/src/lib.rs#L1152",children:"and corresponding chain method"}),") to pass the extrinsic following the consumer's type registry.\nYou can now sign and submit to the consumer chain."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"await signAndSubmitTx(consumerApi, dipSubmittable, submitterKeypair)\n"})}),"\n",(0,i.jsx)(n.h3,{id:"3-linking-accounts-optional",children:"3. Linking accounts (optional)"}),"\n",(0,i.jsx)(n.p,{children:"Linked accounts let you specify which accounts you want to prove that you control when you make the cross-chain proof.\nAs part of the proof provided, you can also include other values, such as the web3name."}),"\n",(0,i.jsxs)(n.p,{children:["For all the accounts you want to link, use the ",(0,i.jsx)(n.code,{children:"associateAccountToChainArgs"})," method, ",(0,i.jsx)(n.a,{href:"/docs/develop/sdk/cookbook/account_linking/account-link##linking-an-account-to-a-did",children:"as detailed in this guide"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["You can then batch all the linked account transactions and authorize them using the ",(0,i.jsx)(n.code,{children:"authorizeTx"})," method."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const signedLinkedAccounts = await Kilt.Did.authorizeTx(\n newFullDidUri,\n providerApi.tx.utility.batchAll(linkAccountTxs),\n signCallback,\n newSubmitterKeypair.address as KiltAddress,\n { txCounter: new BN(4) }\n)\n"})}),"\n",(0,i.jsx)(n.h2,{id:"creating-extensions-for-specific-proofs",children:"Creating extensions for specific proofs"}),"\n",(0,i.jsxs)(n.p,{children:["If you need a specific proof type for a consumer chain, then a chain developer needs to submit a PR to the SDK repository in the ",(0,i.jsx)(n.code,{children:"src > dipProof > extensions"})," folder.\nThe extension included with the SDK adds support for a time-bound DID signature, i.e., a signature which is valid only until a certain block number on the consumer chain."]}),"\n",(0,i.jsxs)(n.p,{children:["The extension can take any form, but must return ",(0,i.jsx)(n.a,{href:"https://docs.substrate.io/reference/scale-codec/",children:"a SCALE encoded"})," object.\nThere's an example of how the extension does this ",(0,i.jsx)(n.a,{href:"https://github.com/KILTprotocol/dip-sdk/blob/9ad141b3757e076744ab8b2d29bcf10bbeaddd9f/src/dipProof/extensions/timeBoundDidSignature.ts#L113",children:"on GitHub"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["To add the extension, use the ",(0,i.jsx)(n.code,{children:"generateDipSubmittableExtrinsic"})," method and pass the additional proof elements along with consumer chain specific components."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-typescript",children:"const dipSubmittable = DipSdk.generateDipSubmittableExtrinsic({\n additionalProofElements:\n DipSdk.dipProof.extensions.timeBoundDidSignature.toChain(\n crossChainDidSignature\n ),\n api: consumerApi,\n baseDipProof,\n call,\n didUri: did.uri,\n})\n"})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Read the auto-generated ",(0,i.jsx)(n.a,{href:"https://kiltprotocol.github.io/dip-sdk",children:"API documentation"})," for more details on the methods the SDK provides."]})})]})}function p(e={}){const{wrapper:n}={...(0,o.M)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(u,{...e})}):u(e)}},87768:(e,n,t)=>{t.d(n,{c:()=>a});t(11504);var i=t(65456);const o={tabItem:"tabItem_Ymn6"};var r=t(17624);function a(e){let{children:n,hidden:t,className:a}=e;return(0,r.jsx)("div",{role:"tabpanel",className:(0,i.c)(o.tabItem,a),hidden:t,children:n})}},61268:(e,n,t)=>{t.d(n,{c:()=>D});var i=t(11504),o=t(65456),r=t(53943),a=t(55592),s=t(95288),c=t(10632),l=t(27128),d=t(21148);function h(e){return i.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function u(e){const{values:n,children:t}=e;return(0,i.useMemo)((()=>{const e=n??function(e){return h(e).map((e=>{let{props:{value:n,label:t,attributes:i,default:o}}=e;return{value:n,label:t,attributes:i,default:o}}))}(t);return function(e){const n=(0,l.w)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,t])}function p(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:t}=e;const o=(0,a.Uz)(),r=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,c._M)(r),(0,i.useCallback)((e=>{if(!r)return;const n=new URLSearchParams(o.location.search);n.set(r,e),o.replace({...o.location,search:n.toString()})}),[r,o])]}function m(e){const{defaultValue:n,queryString:t=!1,groupId:o}=e,r=u(e),[a,c]=(0,i.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:t}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const i=t.find((e=>e.default))??t[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:n,tabValues:r}))),[l,h]=f({queryString:t,groupId:o}),[m,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[o,r]=(0,d.IN)(t);return[o,(0,i.useCallback)((e=>{t&&r.set(e)}),[t,r])]}({groupId:o}),x=(()=>{const e=l??m;return p({value:e,tabValues:r})?e:null})();(0,s.c)((()=>{x&&c(x)}),[x]);return{selectedValue:a,selectValue:(0,i.useCallback)((e=>{if(!p({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);c(e),h(e),b(e)}),[h,b,r]),tabValues:r}}var b=t(93664);const x={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var g=t(17624);function j(e){let{className:n,block:t,selectedValue:i,selectValue:a,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:l}=(0,r.MV)(),d=e=>{const n=e.currentTarget,t=c.indexOf(n),o=s[t].value;o!==i&&(l(n),a(o))},h=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}n?.focus()};return(0,g.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.c)("tabs",{"tabs--block":t},n),children:s.map((e=>{let{value:n,label:t,attributes:r}=e;return(0,g.jsx)("li",{role:"tab",tabIndex:i===n?0:-1,"aria-selected":i===n,ref:e=>c.push(e),onKeyDown:h,onClick:d,...r,className:(0,o.c)("tabs__item",x.tabItem,r?.className,{"tabs__item--active":i===n}),children:t??n},n)}))})}function v(e){let{lazy:n,children:t,selectedValue:o}=e;const r=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=r.find((e=>e.props.value===o));return e?(0,i.cloneElement)(e,{className:"margin-top--md"}):null}return(0,g.jsx)("div",{className:"margin-top--md",children:r.map(((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==o})))})}function k(e){const n=m(e);return(0,g.jsxs)("div",{className:(0,o.c)("tabs-container",x.tabList),children:[(0,g.jsx)(j,{...e,...n}),(0,g.jsx)(v,{...e,...n})]})}function D(e){const n=(0,b.c)();return(0,g.jsx)(k,{...e,children:h(e.children)},String(n))}},4552:(e,n,t)=>{t.d(n,{I:()=>s,M:()=>a});var i=t(11504);const o={},r=i.createContext(o);function a(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/13646d7d.a362b8ee.js b/assets/js/13646d7d.8d300a47.js similarity index 99% rename from assets/js/13646d7d.a362b8ee.js rename to assets/js/13646d7d.8d300a47.js index 14865d034..c061981c8 100644 --- a/assets/js/13646d7d.a362b8ee.js +++ b/assets/js/13646d7d.8d300a47.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99],{24476:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>h,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var n=i(17624),r=i(4552);const a={id:"verification",title:"Verification"},s=void 0,o={id:"concepts/credentials/verification",title:"Verification",description:"KILT allows a Verifier to check if the information in a credential presented by a Claimer is correct and valid.",source:"@site/docs/concepts/05_credentials/05_verification.md",sourceDirName:"concepts/05_credentials",slug:"/concepts/credentials/verification",permalink:"/docs/concepts/credentials/verification",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/05_credentials/05_verification.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:5,frontMatter:{id:"verification",title:"Verification"},sidebar:"concepts",previous:{title:"Attestations",permalink:"/docs/concepts/credentials/attestation"},next:{title:"Public Credentials for Assets",permalink:"/docs/concepts/credentials/public-credentials"}},h={},c=[{value:"Requesting a Credential from a Claimer",id:"requesting-a-credential-from-a-claimer",level:2},{value:"Presenting a Credential with Selective Disclosure",id:"presenting-a-credential-with-selective-disclosure",level:2},{value:"Verifying a Presentation",id:"verifying-a-presentation",level:2},{value:"Verifying the Owner of the Presented Credential",id:"verifying-the-owner-of-the-presented-credential",level:3},{value:"Verifying the Content of the Presented Credential",id:"verifying-the-content-of-the-presented-credential",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"KILT allows a Verifier to check if the information in a credential presented by a Claimer is correct and valid.\nWith the presentation of the credential, the Claimer also presents evidence that a third party (i.e., an Attester) ensured the correctness of the Claimer\u2019s attributes."}),"\n",(0,n.jsx)(t.p,{children:"The Verifier trusts this third party either because they trust their reputation directly or they trust a delegation structure that this Attester is part of (e.g., a State department issuing driving licenses)."}),"\n",(0,n.jsx)(t.p,{children:"For the verification process:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The Claimer needs their credential and the private key associated with their identifier"}),"\n",(0,n.jsx)(t.li,{children:"The Verifier needs the identifier of the trusted Attester"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"During the verification process the Claimer wants to prove three things to the Verifier:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The credential is valid (i.e., not revoked by its Attester)"}),"\n",(0,n.jsx)(t.li,{children:"The attributes in the credential actually refer to the Claimer"}),"\n",(0,n.jsx)(t.li,{children:"The credential contains information that is relevant for the Verifier in this use case"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"requesting-a-credential-from-a-claimer",children:"Requesting a Credential from a Claimer"}),"\n",(0,n.jsx)(t.p,{children:"The Verifier may request a credential from a Claimer, providing the following data:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"CTypes"}),": which CTypes the Verifier can work with for the use case. They can provide multiple options, which have to be regarded as alternatives."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"TrustedAttesters"}),": which Attesters are considered trusted for each specified CType."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"RequiredProperties"}),': which properties for each specified CType must at least be revealed for the presentation to be considered sufficient. More on "selective disclosure" later.']}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Challenge"}),": a nonce, which the Verifier can make use of to ensure that the presentation generated by the Claimer is fresh and is not being replayed by some other older interactions. More on that later."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"presenting-a-credential-with-selective-disclosure",children:"Presenting a Credential with Selective Disclosure"}),"\n",(0,n.jsxs)(t.p,{children:["Given the ",(0,n.jsx)(t.code,{children:"RequiredProperties"})," specified by the Verifier, the Claimer can decide how much of the information they wish to reveal before they generate the presentation and send it to the Verifier.\nIf supported by the Verifier, they can choose to hide attributes and thus only disclose a subset of the original claim data."]}),"\n",(0,n.jsx)(t.p,{children:"For example, if verifying a driving license only requires the verification of the driver's name and picture, a Claimer can decide to hide additional information such as age and place of residence.\nThis increases the privacy of the Claimer since they only need to show attributes that are required in the specific context."}),"\n",(0,n.jsxs)(t.p,{children:["For a detailed developer-oriented guide to KILT presentation creation, see our ",(0,n.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/claiming/presentation-creation",children:"Presentation Cookbook section"}),"."]}),"\n",(0,n.jsx)(t.admonition,{type:"caution",children:(0,n.jsx)(t.p,{children:"The presentations can still be correlated, since the hash of the credential always stays the same, even when creating new presentations and selecting different attributes to show."})}),"\n",(0,n.jsx)(t.h2,{id:"verifying-a-presentation",children:"Verifying a Presentation"}),"\n",(0,n.jsx)(t.p,{children:"The Verifier receives the presentation from the Claimer, re-calculates the root hash of the credential from which the presentation was generated, and queries the KILT blockchain to obtain the associated attestation information, including the revocation status of the credential."}),"\n",(0,n.jsx)(t.p,{children:"If the Claimer tampered with the credential, the re-calculated root hash will not match any attestation on the chain.\nOn the other hand, if an attestation with the calculated hash can be found on the chain and has not been revoked, the credential is valid."}),"\n",(0,n.jsx)(t.p,{children:"However, this does not give the Verifier the guarantee that the Claimer is the rightful/legitimate owner of the credential presented.\nThat problem is addressed in the next section."}),"\n",(0,n.jsx)(t.h3,{id:"verifying-the-owner-of-the-presented-credential",children:"Verifying the Owner of the Presented Credential"}),"\n",(0,n.jsxs)(t.p,{children:["When issued, a credential is linked to the KILT decentralized identifier (DID) of the original Claimer.\nThe DID can be resolved to the public key of the Claimer according to the ",(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-kilt-did",children:"KILT DID specification"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"The Verifier assumes that the private key for the DID public key is only known to the owner of the credential, and is not shared across users.\nTherefore, when requesting the Claimer to generate a presentation, the Verifier challenges the Claimer to sign a nonce (a random number that is used once) that the Verifier sends together with their request."}),"\n",(0,n.jsx)(t.p,{children:"If the Claimer can sign both the nonce and the presentation with the private key that only the credential's owner should have knowledge of, the Verifier can be sure that the Claimer is indeed the legitimate owner of the credential."}),"\n",(0,n.jsx)(t.h3,{id:"verifying-the-content-of-the-presented-credential",children:"Verifying the Content of the Presented Credential"}),"\n",(0,n.jsxs)(t.p,{children:["After the Verifier has checked that the credential is valid and belongs to the presenting Claimer, they still need to verify that they have received all the required information as the presentation received could contain the right values, but not the right semantics.\nFor example, the ",(0,n.jsx)(t.em,{children:"age"})," property could have different meanings depending on whether it is defined for a passport CType or a Whisky Certificate CType.\nTherefore, the Verifier has to check if the CType matches one of the requested CTypes, and that the properties disclosed in the presentation include at least all of the properties requested for that CType presentation."]}),"\n",(0,n.jsxs)(t.p,{children:["For a detailed developer-oriented guide to KILT credential verification, see our ",(0,n.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/claiming/presentation-verification",children:"Verification Cookbook section"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},4552:(e,t,i)=>{i.d(t,{I:()=>o,M:()=>s});var n=i(11504);const r={},a=n.createContext(r);function s(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[99],{24476:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>h,contentTitle:()=>s,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var n=i(17624),r=i(4552);const a={id:"verification",title:"Verification"},s=void 0,o={id:"concepts/credentials/verification",title:"Verification",description:"KILT allows a Verifier to check if the information in a credential presented by a Claimer is correct and valid.",source:"@site/docs/concepts/05_credentials/05_verification.md",sourceDirName:"concepts/05_credentials",slug:"/concepts/credentials/verification",permalink:"/docs/concepts/credentials/verification",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/05_credentials/05_verification.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:5,frontMatter:{id:"verification",title:"Verification"},sidebar:"concepts",previous:{title:"Attestations",permalink:"/docs/concepts/credentials/attestation"},next:{title:"Public Credentials for Assets",permalink:"/docs/concepts/credentials/public-credentials"}},h={},c=[{value:"Requesting a Credential from a Claimer",id:"requesting-a-credential-from-a-claimer",level:2},{value:"Presenting a Credential with Selective Disclosure",id:"presenting-a-credential-with-selective-disclosure",level:2},{value:"Verifying a Presentation",id:"verifying-a-presentation",level:2},{value:"Verifying the Owner of the Presented Credential",id:"verifying-the-owner-of-the-presented-credential",level:3},{value:"Verifying the Content of the Presented Credential",id:"verifying-the-content-of-the-presented-credential",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"KILT allows a Verifier to check if the information in a credential presented by a Claimer is correct and valid.\nWith the presentation of the credential, the Claimer also presents evidence that a third party (i.e., an Attester) ensured the correctness of the Claimer\u2019s attributes."}),"\n",(0,n.jsx)(t.p,{children:"The Verifier trusts this third party either because they trust their reputation directly or they trust a delegation structure that this Attester is part of (e.g., a State department issuing driving licenses)."}),"\n",(0,n.jsx)(t.p,{children:"For the verification process:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The Claimer needs their credential and the private key associated with their identifier"}),"\n",(0,n.jsx)(t.li,{children:"The Verifier needs the identifier of the trusted Attester"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"During the verification process the Claimer wants to prove three things to the Verifier:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"The credential is valid (i.e., not revoked by its Attester)"}),"\n",(0,n.jsx)(t.li,{children:"The attributes in the credential actually refer to the Claimer"}),"\n",(0,n.jsx)(t.li,{children:"The credential contains information that is relevant for the Verifier in this use case"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"requesting-a-credential-from-a-claimer",children:"Requesting a Credential from a Claimer"}),"\n",(0,n.jsx)(t.p,{children:"The Verifier may request a credential from a Claimer, providing the following data:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"CTypes"}),": which CTypes the Verifier can work with for the use case. They can provide multiple options, which have to be regarded as alternatives."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"TrustedAttesters"}),": which Attesters are considered trusted for each specified CType."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"RequiredProperties"}),': which properties for each specified CType must at least be revealed for the presentation to be considered sufficient. More on "selective disclosure" later.']}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.strong,{children:"Challenge"}),": a nonce, which the Verifier can make use of to ensure that the presentation generated by the Claimer is fresh and is not being replayed by some other older interactions. More on that later."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"presenting-a-credential-with-selective-disclosure",children:"Presenting a Credential with Selective Disclosure"}),"\n",(0,n.jsxs)(t.p,{children:["Given the ",(0,n.jsx)(t.code,{children:"RequiredProperties"})," specified by the Verifier, the Claimer can decide how much of the information they wish to reveal before they generate the presentation and send it to the Verifier.\nIf supported by the Verifier, they can choose to hide attributes and thus only disclose a subset of the original claim data."]}),"\n",(0,n.jsx)(t.p,{children:"For example, if verifying a driving license only requires the verification of the driver's name and picture, a Claimer can decide to hide additional information such as age and place of residence.\nThis increases the privacy of the Claimer since they only need to show attributes that are required in the specific context."}),"\n",(0,n.jsxs)(t.p,{children:["For a detailed developer-oriented guide to KILT presentation creation, see our ",(0,n.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/claiming/presentation-creation",children:"Presentation Cookbook section"}),"."]}),"\n",(0,n.jsx)(t.admonition,{type:"caution",children:(0,n.jsx)(t.p,{children:"The presentations can still be correlated, since the hash of the credential always stays the same, even when creating new presentations and selecting different attributes to show."})}),"\n",(0,n.jsx)(t.h2,{id:"verifying-a-presentation",children:"Verifying a Presentation"}),"\n",(0,n.jsx)(t.p,{children:"The Verifier receives the presentation from the Claimer, re-calculates the root hash of the credential from which the presentation was generated, and queries the KILT blockchain to obtain the associated attestation information, including the revocation status of the credential."}),"\n",(0,n.jsx)(t.p,{children:"If the Claimer tampered with the credential, the re-calculated root hash will not match any attestation on the chain.\nOn the other hand, if an attestation with the calculated hash can be found on the chain and has not been revoked, the credential is valid."}),"\n",(0,n.jsx)(t.p,{children:"However, this does not give the Verifier the guarantee that the Claimer is the rightful/legitimate owner of the credential presented.\nThat problem is addressed in the next section."}),"\n",(0,n.jsx)(t.h3,{id:"verifying-the-owner-of-the-presented-credential",children:"Verifying the Owner of the Presented Credential"}),"\n",(0,n.jsxs)(t.p,{children:["When issued, a credential is linked to the KILT decentralized identifier (DID) of the original Claimer.\nThe DID can be resolved to the public key of the Claimer according to the ",(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-kilt-did",children:"KILT DID specification"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"The Verifier assumes that the private key for the DID public key is only known to the owner of the credential, and is not shared across users.\nTherefore, when requesting the Claimer to generate a presentation, the Verifier challenges the Claimer to sign a nonce (a random number that is used once) that the Verifier sends together with their request."}),"\n",(0,n.jsx)(t.p,{children:"If the Claimer can sign both the nonce and the presentation with the private key that only the credential's owner should have knowledge of, the Verifier can be sure that the Claimer is indeed the legitimate owner of the credential."}),"\n",(0,n.jsx)(t.h3,{id:"verifying-the-content-of-the-presented-credential",children:"Verifying the Content of the Presented Credential"}),"\n",(0,n.jsxs)(t.p,{children:["After the Verifier has checked that the credential is valid and belongs to the presenting Claimer, they still need to verify that they have received all the required information as the presentation received could contain the right values, but not the right semantics.\nFor example, the ",(0,n.jsx)(t.em,{children:"age"})," property could have different meanings depending on whether it is defined for a passport CType or a Whisky Certificate CType.\nTherefore, the Verifier has to check if the CType matches one of the requested CTypes, and that the properties disclosed in the presentation include at least all of the properties requested for that CType presentation."]}),"\n",(0,n.jsxs)(t.p,{children:["For a detailed developer-oriented guide to KILT credential verification, see our ",(0,n.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/claiming/presentation-verification",children:"Verification Cookbook section"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},4552:(e,t,i)=>{i.d(t,{I:()=>o,M:()=>s});var n=i(11504);const r={},a=n.createContext(r);function s(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/16a6a7ba.dc3849fd.js b/assets/js/16a6a7ba.107b3a6c.js similarity index 97% rename from assets/js/16a6a7ba.dc3849fd.js rename to assets/js/16a6a7ba.107b3a6c.js index 00bdb1b35..6a5706549 100644 --- a/assets/js/16a6a7ba.dc3849fd.js +++ b/assets/js/16a6a7ba.107b3a6c.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5980],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},56280:(e,t,i)=>{"use strict";i.r(t),i.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>c,toc:()=>p});var n=i(17624),o=i(4552),s=i(96020);const a="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport function createSimpleLightDid({\n authentication\n}: {\n authentication: Kilt.NewLightDidVerificationKey\n}): Kilt.DidDocument {\n // Create a light DID from the generated authentication key.\n const lightDID = Kilt.Did.createLightDidDocument({\n authentication: [authentication]\n })\n console.log(lightDID.uri)\n\n return lightDID\n}\n",r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport function createCompleteLightDid({\n authentication,\n keyAgreement\n}: {\n authentication: Kilt.NewLightDidVerificationKey\n keyAgreement: Kilt.NewDidEncryptionKey\n}): Kilt.DidDocument {\n // Example service for the DID.\n const service: Kilt.DidServiceEndpoint[] = [\n {\n id: '#my-service',\n type: ['KiltPublishedCredentialCollectionV1'],\n serviceEndpoint: ['http://example.domain.org']\n }\n ]\n\n // Create the KILT light DID with the information generated.\n const lightDID = Kilt.Did.createLightDidDocument({\n authentication: [authentication],\n keyAgreement: [keyAgreement],\n service\n })\n console.log(lightDID.uri)\n\n return lightDID\n}\n",d={id:"light-did-creation",title:"Create a Light DID"},l=void 0,c={id:"develop/sdk/cookbook/dids/light-did-creation",title:"Create a Light DID",description:"The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption.",source:"@site/docs/develop/01_sdk/02_cookbook/01_dids/01_light_did_creation.md",sourceDirName:"develop/01_sdk/02_cookbook/01_dids",slug:"/develop/sdk/cookbook/dids/light-did-creation",permalink:"/docs/develop/sdk/cookbook/dids/light-did-creation",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/01_dids/01_light_did_creation.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:1,frontMatter:{id:"light-did-creation",title:"Create a Light DID"},sidebar:"sdk",previous:{title:"Generate DID keys",permalink:"/docs/develop/sdk/cookbook/dids/key-generation"},next:{title:"Create a Full DID",permalink:"/docs/develop/sdk/cookbook/dids/full-did-creation"}},h={},p=[];function u(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",li:"li",ol:"ol",p:"p",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption.\nFor the sake of ease of use, the example snippets below show how to use keys generated with a ",(0,n.jsx)(t.code,{children:"Keyring"}),", provided also by the ",(0,n.jsx)(t.code,{children:"@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."]}),"\n",(0,n.jsx)(t.p,{children:"The following is an example of how to create a light DID after creating an authentication keypair."}),"\n",(0,n.jsx)(s.c,{children:a}),"\n",(0,n.jsx)(t.p,{children:"For cases in which an encryption key and some services also need to be added to a light DID:"}),"\n",(0,n.jsx)(s.c,{children:r}),"\n",(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsx)(t.p,{children:"In KILT, light DIDs are meant to be used in one of two cases:"}),(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["As ",(0,n.jsx)(t.em,{children:"ephemeral, one-time identifiers"})," when establishing new communication channels with untrusted parties."]}),"\n",(0,n.jsxs)(t.li,{children:["As an ",(0,n.jsx)(t.em,{children:"entrypoint into the KILT ecosystem"}),", i.e., to obtain one's first credentials and get acquainted with KILT."]}),"\n"]}),(0,n.jsxs)(t.p,{children:["As such, light DIDs do not support updates of any sort, but they retain the same identifier until they are upgraded to full DIDs.\nThey are not intended for use in complex and/or high-security use cases.\nIn those situations, a full DID should be used.\nVisit the ",(0,n.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/dids/full-did-creation",children:"next section"})," to see how to create and manage full DIDs."]})]})]})}function m(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},96020:(e,t,i)=>{"use strict";i.d(t,{c:()=>u});var n=i(11504),o=i(28264),s=i(46352),a=i(58440),r=i(14300),d=i(28168),l=i(61268),c=i(87768),h=i(1608),p=i(17624);const u=e=>{let{children:t,fileName:i,...u}=e;const m=t,[g,D]=(0,n.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:f}}}=(0,o.c)(),k=(0,n.useMemo)((()=>{const{code:e}=(0,s.transform)(m,{plugins:["transform-typescript"],retainLines:!0});return e}),[m]);(0,n.useEffect)((()=>{a.E9(k,{parser:"babel",plugins:[r.c,d.cp],...f}).then(D)}),[f,k]);const y=[{fileName:i?`${i}.ts`:void 0,fileContents:m,fileID:"ts",fileLabel:"Typescript"},{fileName:i?`${i}.js`:void 0,fileContents:g,fileID:"js",fileLabel:"Javascript"}];return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)(l.c,{groupId:"ts-js-choice",children:y.map((e=>(0,p.jsx)(c.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,p.jsx)(h.c,{...u,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5980],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},56280:(e,t,i)=>{"use strict";i.r(t),i.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>m,frontMatter:()=>d,metadata:()=>c,toc:()=>p});var n=i(17624),o=i(4552),s=i(96020);const a="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport function createSimpleLightDid({\n authentication\n}: {\n authentication: Kilt.NewLightDidVerificationKey\n}): Kilt.DidDocument {\n // Create a light DID from the generated authentication key.\n const lightDID = Kilt.Did.createLightDidDocument({\n authentication: [authentication]\n })\n console.log(lightDID.uri)\n\n return lightDID\n}\n",r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport function createCompleteLightDid({\n authentication,\n keyAgreement\n}: {\n authentication: Kilt.NewLightDidVerificationKey\n keyAgreement: Kilt.NewDidEncryptionKey\n}): Kilt.DidDocument {\n // Example service for the DID.\n const service: Kilt.DidServiceEndpoint[] = [\n {\n id: '#my-service',\n type: ['KiltPublishedCredentialCollectionV1'],\n serviceEndpoint: ['http://example.domain.org']\n }\n ]\n\n // Create the KILT light DID with the information generated.\n const lightDID = Kilt.Did.createLightDidDocument({\n authentication: [authentication],\n keyAgreement: [keyAgreement],\n service\n })\n console.log(lightDID.uri)\n\n return lightDID\n}\n",d={id:"light-did-creation",title:"Create a Light DID"},l=void 0,c={id:"develop/sdk/cookbook/dids/light-did-creation",title:"Create a Light DID",description:"The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption.",source:"@site/docs/develop/01_sdk/02_cookbook/01_dids/01_light_did_creation.md",sourceDirName:"develop/01_sdk/02_cookbook/01_dids",slug:"/develop/sdk/cookbook/dids/light-did-creation",permalink:"/docs/develop/sdk/cookbook/dids/light-did-creation",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/01_dids/01_light_did_creation.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:1,frontMatter:{id:"light-did-creation",title:"Create a Light DID"},sidebar:"sdk",previous:{title:"Generate DID keys",permalink:"/docs/develop/sdk/cookbook/dids/key-generation"},next:{title:"Create a Full DID",permalink:"/docs/develop/sdk/cookbook/dids/full-did-creation"}},h={},p=[];function u(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",li:"li",ol:"ol",p:"p",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption.\nFor the sake of ease of use, the example snippets below show how to use keys generated with a ",(0,n.jsx)(t.code,{children:"Keyring"}),", provided also by the ",(0,n.jsx)(t.code,{children:"@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."]}),"\n",(0,n.jsx)(t.p,{children:"The following is an example of how to create a light DID after creating an authentication keypair."}),"\n",(0,n.jsx)(s.c,{children:a}),"\n",(0,n.jsx)(t.p,{children:"For cases in which an encryption key and some services also need to be added to a light DID:"}),"\n",(0,n.jsx)(s.c,{children:r}),"\n",(0,n.jsxs)(t.admonition,{type:"info",children:[(0,n.jsx)(t.p,{children:"In KILT, light DIDs are meant to be used in one of two cases:"}),(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["As ",(0,n.jsx)(t.em,{children:"ephemeral, one-time identifiers"})," when establishing new communication channels with untrusted parties."]}),"\n",(0,n.jsxs)(t.li,{children:["As an ",(0,n.jsx)(t.em,{children:"entrypoint into the KILT ecosystem"}),", i.e., to obtain one's first credentials and get acquainted with KILT."]}),"\n"]}),(0,n.jsxs)(t.p,{children:["As such, light DIDs do not support updates of any sort, but they retain the same identifier until they are upgraded to full DIDs.\nThey are not intended for use in complex and/or high-security use cases.\nIn those situations, a full DID should be used.\nVisit the ",(0,n.jsx)(t.a,{href:"/docs/develop/sdk/cookbook/dids/full-did-creation",children:"next section"})," to see how to create and manage full DIDs."]})]})]})}function m(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},96020:(e,t,i)=>{"use strict";i.d(t,{c:()=>u});var n=i(11504),o=i(28264),s=i(46352),a=i(58440),r=i(14300),d=i(28168),l=i(61268),c=i(87768),h=i(1608),p=i(17624);const u=e=>{let{children:t,fileName:i,...u}=e;const m=t,[g,D]=(0,n.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:f}}}=(0,o.c)(),k=(0,n.useMemo)((()=>{const{code:e}=(0,s.transform)(m,{plugins:["transform-typescript"],retainLines:!0});return e}),[m]);(0,n.useEffect)((()=>{a.E9(k,{parser:"babel",plugins:[r.c,d.cp],...f}).then(D)}),[f,k]);const y=[{fileName:i?`${i}.ts`:void 0,fileContents:m,fileID:"ts",fileLabel:"Typescript"},{fileName:i?`${i}.js`:void 0,fileContents:g,fileID:"js",fileLabel:"Javascript"}];return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)(l.c,{groupId:"ts-js-choice",children:y.map((e=>(0,p.jsx)(c.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,p.jsx)(h.c,{...u,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/1c5fc417.a8664556.js b/assets/js/1c5fc417.cf9f5c3b.js similarity index 98% rename from assets/js/1c5fc417.a8664556.js rename to assets/js/1c5fc417.cf9f5c3b.js index ac11cce84..274359d6c 100644 --- a/assets/js/1c5fc417.a8664556.js +++ b/assets/js/1c5fc417.cf9f5c3b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4560],{43788:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=n(17624),a=n(4552);const s={id:"v29-backward-compatibility",title:"Backward Compatibility with Pre-0.29.x Versions"},o=void 0,r={id:"develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility",title:"Backward Compatibility with Pre-0.29.x Versions",description:"Depending on how exactly your application interacts with other applications, changes to some data formats and interfaces might mean that conversions are required for them to remain compatible.",source:"@site/docs/develop/01_sdk/02_cookbook/08_upgrading_to_v0_29/01_backward_compatibility.md",sourceDirName:"develop/01_sdk/02_cookbook/08_upgrading_to_v0_29",slug:"/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility",permalink:"/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/08_upgrading_to_v0_29/01_backward_compatibility.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:1,frontMatter:{id:"v29-backward-compatibility",title:"Backward Compatibility with Pre-0.29.x Versions"},sidebar:"sdk",previous:{title:"Upgrading to v0.29",permalink:"/docs/develop/sdk/cookbook/upgrading_to_v0_29/"},next:{title:"Chain Setup for Development",permalink:"/docs/develop/sdk/chain_setup/"}},c={},d=[{value:"General Strategy",id:"general-strategy",level:2},{value:"Message Conversion",id:"message-conversion",level:2},{value:"submit-terms",id:"submit-terms",level:3},{value:"request-attestation",id:"request-attestation",level:3},{value:"submit-credential",id:"submit-credential",level:3}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,a.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"Depending on how exactly your application interacts with other applications, changes to some data formats and interfaces might mean that conversions are required for them to remain compatible."}),"\n",(0,i.jsxs)(t.p,{children:["To align with breaking changes to data structures in messaging, credentials, and CTypes, we published version 3.0 of the ",(0,i.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-credential-api",children:"Credentials API specification"})," that specifies how browser extensions like the ",(0,i.jsx)(t.a,{href:"https://github.com/BTE-Trusted-Entity/sporran-extension",children:"Sporran credential wallet"})," interact with web applications that produce or consume credentials."]}),"\n",(0,i.jsx)(t.p,{children:"When upgrading to a 0.29.x version of the SDK and to the Credentials API version 3.0, we recommend backward support of Credentials API version 2.0, as supporting only the latest version may result in poor user experience. In what follows, we outline an upgrade strategy for implementers of the Credentials API specification."}),"\n",(0,i.jsx)(t.p,{children:"These instructions will also help with translating from and to data types of pre-0.29 SDK versions in other scenarios, such as when sending messages between clients, or when importing older data (e.g. credentials)."}),"\n",(0,i.jsx)(t.h2,{id:"general-strategy",children:"General Strategy"}),"\n",(0,i.jsxs)(t.p,{children:["Since version 3.0, the specification requires conformant web apps as well as extensions to announce the versions of the API they use, allowing for version negotiation.\nBecause extensions inject themselves into web pages that signal support for kilt features via the ",(0,i.jsx)(t.code,{children:"window.kilt"})," property, the recommended strategy is to handle backward compatibility on the extension side.\nThis way, extensions can be upgraded ahead of time, and implement a fallback to a version 2.0 compatible interface if a web application does not signal version 3.0 support.\nFollowing this strategy, backward compatibility on the application side is not strictly necessary.\nWe recommend notifying users of web apps that have upgraded to version 3.0 if they try to connect with an older extension, pointing them to the need to upgrade their extension to use this app."]}),"\n",(0,i.jsx)(t.h2,{id:"message-conversion",children:"Message Conversion"}),"\n",(0,i.jsxs)(t.p,{children:["Breaking changes introduced with version 3.0 of the Credential Api exclusively affect selected data types of messages passed between the application backend and extension.\nIn the attester (credential issuance) flow the message types ",(0,i.jsx)(t.code,{children:"submit-terms"})," and ",(0,i.jsx)(t.code,{children:"request-attestation"})," have changed.\nIn the verifier (presentation exchange) flow the message type ",(0,i.jsx)(t.code,{children:"submit-credential"})," message is affected."]}),"\n",(0,i.jsx)(t.p,{children:"Version 3.0 extensions can achieve backward compatibility by translating messages received from and sent to the application which implements an earlier version of the specification.\nBelow you can find brief descriptions of how these conversions can be implemented."}),"\n",(0,i.jsx)(t.h3,{id:"submit-terms",children:(0,i.jsx)(t.code,{children:"submit-terms"})}),"\n",(0,i.jsxs)(t.p,{children:["When receiving a ",(0,i.jsx)(t.code,{children:"submit-terms"})," message from the old web app, replace the items of the ",(0,i.jsx)(t.code,{children:"cTypes"})," content property with the values of their ",(0,i.jsx)(t.code,{children:"schema"})," properties:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ts",children:"interface Old {\n cTypes: Array<{\n schema: ICTypeSchema\n hash: HexString // duplicates `schema.$id`\n owner: DidUri | null // apparently unused\n }>\n ...\n}\n\ninterface New {\n cTypes: Array // Note that 0.29 renames ICTypeSchema to ICType\n ...\n}\n"})}),"\n",(0,i.jsx)(t.h3,{id:"request-attestation",children:(0,i.jsx)(t.code,{children:"request-attestation"})}),"\n",(0,i.jsxs)(t.p,{children:["Before encrypting a ",(0,i.jsx)(t.code,{children:"request-attestation"})," type message destined for an older web app, rename ",(0,i.jsx)(t.code,{children:"credential"})," to ",(0,i.jsx)(t.code,{children:"requestForAttestation"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ts",children:"interface New {\n credential: { claim, ... }\n quote?: IQuoteAgreement\n}\n\ninterface Old {\n requestForAttestation: { claim, ... }\n quote?: IQuoteAgreement\n}\n"})}),"\n",(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["The old ",(0,i.jsx)(t.code,{children:"IRequestForAttestation"})," interface optionally allowed claimers to attach a signature for authentication.\nThere is no property intended for this purpose on the new interface, as the message encryption scheme already takes care of authentication.\nWhat has changed is that this form of authentication is ",(0,i.jsx)(t.strong,{children:"not publicly verifiable"}),".\nAttesters can instead require claimers to sign a quote agreement for the purpose of bookkeeping, which contains the credential hash and thus represents a commitment to any claims made."]})}),"\n",(0,i.jsx)(t.h3,{id:"submit-credential",children:(0,i.jsx)(t.code,{children:"submit-credential"})}),"\n",(0,i.jsxs)(t.p,{children:["Before encrypting a ",(0,i.jsx)(t.code,{children:"submit-credential"})," message for the older application, replace every item with an object having the property ",(0,i.jsx)(t.code,{children:"request"})," with the value of item itself, and the property ",(0,i.jsx)(t.code,{children:"attestation"})," with the attestation for this credential."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ts",children:"interface New extends Array<{ claim, ..., claimerSignature }> {}\n\ninterface Old extends Array<{\n attestation: { claimHash, owner, ... }\n request: { claim, ..., claimerSignature }\n}> {}\n"})})]})}function h(e={}){const{wrapper:t}={...(0,a.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>r,M:()=>o});var i=n(11504);const a={},s=i.createContext(a);function o(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[4560],{43788:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var i=n(17624),a=n(4552);const s={id:"v29-backward-compatibility",title:"Backward Compatibility with Pre-0.29.x Versions"},o=void 0,r={id:"develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility",title:"Backward Compatibility with Pre-0.29.x Versions",description:"Depending on how exactly your application interacts with other applications, changes to some data formats and interfaces might mean that conversions are required for them to remain compatible.",source:"@site/docs/develop/01_sdk/02_cookbook/08_upgrading_to_v0_29/01_backward_compatibility.md",sourceDirName:"develop/01_sdk/02_cookbook/08_upgrading_to_v0_29",slug:"/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility",permalink:"/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/08_upgrading_to_v0_29/01_backward_compatibility.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:1,frontMatter:{id:"v29-backward-compatibility",title:"Backward Compatibility with Pre-0.29.x Versions"},sidebar:"sdk",previous:{title:"Upgrading to v0.29",permalink:"/docs/develop/sdk/cookbook/upgrading_to_v0_29/"},next:{title:"Chain Setup for Development",permalink:"/docs/develop/sdk/chain_setup/"}},c={},d=[{value:"General Strategy",id:"general-strategy",level:2},{value:"Message Conversion",id:"message-conversion",level:2},{value:"submit-terms",id:"submit-terms",level:3},{value:"request-attestation",id:"request-attestation",level:3},{value:"submit-credential",id:"submit-credential",level:3}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,a.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"Depending on how exactly your application interacts with other applications, changes to some data formats and interfaces might mean that conversions are required for them to remain compatible."}),"\n",(0,i.jsxs)(t.p,{children:["To align with breaking changes to data structures in messaging, credentials, and CTypes, we published version 3.0 of the ",(0,i.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-credential-api",children:"Credentials API specification"})," that specifies how browser extensions like the ",(0,i.jsx)(t.a,{href:"https://github.com/BTE-Trusted-Entity/sporran-extension",children:"Sporran credential wallet"})," interact with web applications that produce or consume credentials."]}),"\n",(0,i.jsx)(t.p,{children:"When upgrading to a 0.29.x version of the SDK and to the Credentials API version 3.0, we recommend backward support of Credentials API version 2.0, as supporting only the latest version may result in poor user experience. In what follows, we outline an upgrade strategy for implementers of the Credentials API specification."}),"\n",(0,i.jsx)(t.p,{children:"These instructions will also help with translating from and to data types of pre-0.29 SDK versions in other scenarios, such as when sending messages between clients, or when importing older data (e.g. credentials)."}),"\n",(0,i.jsx)(t.h2,{id:"general-strategy",children:"General Strategy"}),"\n",(0,i.jsxs)(t.p,{children:["Since version 3.0, the specification requires conformant web apps as well as extensions to announce the versions of the API they use, allowing for version negotiation.\nBecause extensions inject themselves into web pages that signal support for kilt features via the ",(0,i.jsx)(t.code,{children:"window.kilt"})," property, the recommended strategy is to handle backward compatibility on the extension side.\nThis way, extensions can be upgraded ahead of time, and implement a fallback to a version 2.0 compatible interface if a web application does not signal version 3.0 support.\nFollowing this strategy, backward compatibility on the application side is not strictly necessary.\nWe recommend notifying users of web apps that have upgraded to version 3.0 if they try to connect with an older extension, pointing them to the need to upgrade their extension to use this app."]}),"\n",(0,i.jsx)(t.h2,{id:"message-conversion",children:"Message Conversion"}),"\n",(0,i.jsxs)(t.p,{children:["Breaking changes introduced with version 3.0 of the Credential Api exclusively affect selected data types of messages passed between the application backend and extension.\nIn the attester (credential issuance) flow the message types ",(0,i.jsx)(t.code,{children:"submit-terms"})," and ",(0,i.jsx)(t.code,{children:"request-attestation"})," have changed.\nIn the verifier (presentation exchange) flow the message type ",(0,i.jsx)(t.code,{children:"submit-credential"})," message is affected."]}),"\n",(0,i.jsx)(t.p,{children:"Version 3.0 extensions can achieve backward compatibility by translating messages received from and sent to the application which implements an earlier version of the specification.\nBelow you can find brief descriptions of how these conversions can be implemented."}),"\n",(0,i.jsx)(t.h3,{id:"submit-terms",children:(0,i.jsx)(t.code,{children:"submit-terms"})}),"\n",(0,i.jsxs)(t.p,{children:["When receiving a ",(0,i.jsx)(t.code,{children:"submit-terms"})," message from the old web app, replace the items of the ",(0,i.jsx)(t.code,{children:"cTypes"})," content property with the values of their ",(0,i.jsx)(t.code,{children:"schema"})," properties:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ts",children:"interface Old {\n cTypes: Array<{\n schema: ICTypeSchema\n hash: HexString // duplicates `schema.$id`\n owner: DidUri | null // apparently unused\n }>\n ...\n}\n\ninterface New {\n cTypes: Array // Note that 0.29 renames ICTypeSchema to ICType\n ...\n}\n"})}),"\n",(0,i.jsx)(t.h3,{id:"request-attestation",children:(0,i.jsx)(t.code,{children:"request-attestation"})}),"\n",(0,i.jsxs)(t.p,{children:["Before encrypting a ",(0,i.jsx)(t.code,{children:"request-attestation"})," type message destined for an older web app, rename ",(0,i.jsx)(t.code,{children:"credential"})," to ",(0,i.jsx)(t.code,{children:"requestForAttestation"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ts",children:"interface New {\n credential: { claim, ... }\n quote?: IQuoteAgreement\n}\n\ninterface Old {\n requestForAttestation: { claim, ... }\n quote?: IQuoteAgreement\n}\n"})}),"\n",(0,i.jsx)(t.admonition,{type:"info",children:(0,i.jsxs)(t.p,{children:["The old ",(0,i.jsx)(t.code,{children:"IRequestForAttestation"})," interface optionally allowed claimers to attach a signature for authentication.\nThere is no property intended for this purpose on the new interface, as the message encryption scheme already takes care of authentication.\nWhat has changed is that this form of authentication is ",(0,i.jsx)(t.strong,{children:"not publicly verifiable"}),".\nAttesters can instead require claimers to sign a quote agreement for the purpose of bookkeeping, which contains the credential hash and thus represents a commitment to any claims made."]})}),"\n",(0,i.jsx)(t.h3,{id:"submit-credential",children:(0,i.jsx)(t.code,{children:"submit-credential"})}),"\n",(0,i.jsxs)(t.p,{children:["Before encrypting a ",(0,i.jsx)(t.code,{children:"submit-credential"})," message for the older application, replace every item with an object having the property ",(0,i.jsx)(t.code,{children:"request"})," with the value of item itself, and the property ",(0,i.jsx)(t.code,{children:"attestation"})," with the attestation for this credential."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-ts",children:"interface New extends Array<{ claim, ..., claimerSignature }> {}\n\ninterface Old extends Array<{\n attestation: { claimHash, owner, ... }\n request: { claim, ..., claimerSignature }\n}> {}\n"})})]})}function h(e={}){const{wrapper:t}={...(0,a.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>r,M:()=>o});var i=n(11504);const a={},s=i.createContext(a);function o(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e03658d.27016eb6.js b/assets/js/1e03658d.3e627196.js similarity index 96% rename from assets/js/1e03658d.27016eb6.js rename to assets/js/1e03658d.3e627196.js index a47b4fba3..d1f1895db 100644 --- a/assets/js/1e03658d.27016eb6.js +++ b/assets/js/1e03658d.3e627196.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5220],{98932:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var a=n(17624),r=n(4552);const i={id:"benchmarking",title:"Benchmark Your Collator"},o=void 0,c={id:"participate/staking/advanced_collator_section/benchmarking",title:"Benchmark Your Collator",description:"To enable benchmarking, the collator must enable the benchmarking feature from a new build of the kilt-parachain.",source:"@site/docs/participate/01_staking/02_advanced_collator_section/06_benchmarking.md",sourceDirName:"participate/01_staking/02_advanced_collator_section",slug:"/participate/staking/advanced_collator_section/benchmarking",permalink:"/docs/participate/staking/advanced_collator_section/benchmarking",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/02_advanced_collator_section/06_benchmarking.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:6,frontMatter:{id:"benchmarking",title:"Benchmark Your Collator"},sidebar:"staking",previous:{title:"Bootnodes",permalink:"/docs/participate/staking/advanced_collator_section/bootnodes"},next:{title:"Overview",permalink:"/docs/participate/staking/delegate/overview"}},s={},l=[];function h(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",pre:"pre",...(0,r.M)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t.p,{children:["To enable benchmarking, the collator must enable the benchmarking feature from a new build of the ",(0,a.jsx)(t.code,{children:"kilt-parachain"}),"."]}),"\n",(0,a.jsx)(t.admonition,{title:"Don't use this binary for running the Collator!",type:"caution",children:(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash=",children:"cargo build --release -p kilt-parachain --features=runtime-benchmarks\n"})})}),"\n",(0,a.jsx)(t.p,{children:"The benchmarks can be run to compare the server's hardware capabilities against the referenced hardware.\nAt the moment, we have benchmarked the Spiritnet and Peregrine runtimes on an AMD Ryzen 7 1700X with 64GB RAM and an NVMe SSD.\nAfter executing the benchmarks on a server compare the weights to the official KILT weights.\nYour weight results should at least be similar to the official ones and the lower yours are, the better."}),"\n",(0,a.jsxs)(t.p,{children:["The commands executed to benchmark the KILT runtimes can be found in the official benchmark files for both ",(0,a.jsx)(t.a,{href:"https://github.com/KILTprotocol/kilt-node/tree/master/runtimes/spiritnet/src/weights",children:"Spiritnet"})," and ",(0,a.jsx)(t.a,{href:"https://github.com/KILTprotocol/kilt-node/tree/master/runtimes/peregrine/src/weights",children:"Peregrine"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["Below is an example of benchmarking for the the ",(0,a.jsx)(t.code,{children:"balances"})," pallet."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash=",children:"./target/release/kilt-parachain \\\n benchmark \\\n --chain=spiritnet-dev \\\n --execution=wasm \\\n --wasm-execution=Compiled \\\n --heap-pages=4096 \\\n --extrinsic=* \\\n --pallet=pallet-balances \\\n --steps=50 \\\n --repeat=20 \\\n --output \\\n ./runtimes/spiritnet/src/weights/pallet_balances.rs \\\n --template \\\n ./.maintain/weight-template.hbs\n"})})]})}function d(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>c,M:()=>o});var a=n(11504);const r={},i=a.createContext(r);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5220],{98932:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var a=n(17624),r=n(4552);const i={id:"benchmarking",title:"Benchmark Your Collator"},o=void 0,c={id:"participate/staking/advanced_collator_section/benchmarking",title:"Benchmark Your Collator",description:"To enable benchmarking, the collator must enable the benchmarking feature from a new build of the kilt-parachain.",source:"@site/docs/participate/01_staking/02_advanced_collator_section/06_benchmarking.md",sourceDirName:"participate/01_staking/02_advanced_collator_section",slug:"/participate/staking/advanced_collator_section/benchmarking",permalink:"/docs/participate/staking/advanced_collator_section/benchmarking",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/02_advanced_collator_section/06_benchmarking.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:6,frontMatter:{id:"benchmarking",title:"Benchmark Your Collator"},sidebar:"staking",previous:{title:"Bootnodes",permalink:"/docs/participate/staking/advanced_collator_section/bootnodes"},next:{title:"Overview",permalink:"/docs/participate/staking/delegate/overview"}},s={},l=[];function h(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",pre:"pre",...(0,r.M)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t.p,{children:["To enable benchmarking, the collator must enable the benchmarking feature from a new build of the ",(0,a.jsx)(t.code,{children:"kilt-parachain"}),"."]}),"\n",(0,a.jsx)(t.admonition,{title:"Don't use this binary for running the Collator!",type:"caution",children:(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash=",children:"cargo build --release -p kilt-parachain --features=runtime-benchmarks\n"})})}),"\n",(0,a.jsx)(t.p,{children:"The benchmarks can be run to compare the server's hardware capabilities against the referenced hardware.\nAt the moment, we have benchmarked the Spiritnet and Peregrine runtimes on an AMD Ryzen 7 1700X with 64GB RAM and an NVMe SSD.\nAfter executing the benchmarks on a server compare the weights to the official KILT weights.\nYour weight results should at least be similar to the official ones and the lower yours are, the better."}),"\n",(0,a.jsxs)(t.p,{children:["The commands executed to benchmark the KILT runtimes can be found in the official benchmark files for both ",(0,a.jsx)(t.a,{href:"https://github.com/KILTprotocol/kilt-node/tree/master/runtimes/spiritnet/src/weights",children:"Spiritnet"})," and ",(0,a.jsx)(t.a,{href:"https://github.com/KILTprotocol/kilt-node/tree/master/runtimes/peregrine/src/weights",children:"Peregrine"}),"."]}),"\n",(0,a.jsxs)(t.p,{children:["Below is an example of benchmarking for the the ",(0,a.jsx)(t.code,{children:"balances"})," pallet."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash=",children:"./target/release/kilt-parachain \\\n benchmark \\\n --chain=spiritnet-dev \\\n --execution=wasm \\\n --wasm-execution=Compiled \\\n --heap-pages=4096 \\\n --extrinsic=* \\\n --pallet=pallet-balances \\\n --steps=50 \\\n --repeat=20 \\\n --output \\\n ./runtimes/spiritnet/src/weights/pallet_balances.rs \\\n --template \\\n ./.maintain/weight-template.hbs\n"})})]})}function d(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>c,M:()=>o});var a=n(11504);const r={},i=a.createContext(r);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e1cf5e0.5779a0c8.js b/assets/js/1e1cf5e0.ea8cc707.js similarity index 99% rename from assets/js/1e1cf5e0.5779a0c8.js rename to assets/js/1e1cf5e0.ea8cc707.js index befaa65a4..d22ea5b46 100644 --- a/assets/js/1e1cf5e0.5779a0c8.js +++ b/assets/js/1e1cf5e0.ea8cc707.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3568],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},19164:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>h,default:()=>j,frontMatter:()=>d,metadata:()=>m,toc:()=>u});var i=n(17624),a=n(4552),r=n(96020),s=n(61268),l=n(87768);const c="import * as Kilt from '@kiltprotocol/sdk-js'\n\n// Create a Claim object from light DID, CType and given content.\nexport function createClaim(\n lightDid: Kilt.DidUri,\n ctype: Kilt.ICType,\n content: Kilt.IClaim['contents']\n): Kilt.IClaim {\n const claim = Kilt.Claim.fromCTypeAndClaimContents(ctype, content, lightDid)\n\n return claim\n}\n",o="import { config as envConfig } from 'dotenv'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\nimport { createClaim } from './createClaim'\nimport { generateLightDid } from './generateLightDid'\nimport { getCtypeSchema } from '../attester/ctypeSchema'\n\nexport function generateCredential(\n claimerDid: Kilt.DidUri,\n claimAttributes: Kilt.IClaim['contents']\n): Kilt.ICredential {\n // Create claim.\n const ctype = getCtypeSchema()\n const claim = createClaim(claimerDid, ctype, claimAttributes)\n\n // Create credential and request attestation.\n console.log('Claimer -> create request')\n return Kilt.Credential.fromClaim(claim)\n}\n\n// Don't execute if this is imported by another file.\nif (require.main === module) {\n ;(async () => {\n envConfig()\n\n try {\n await Kilt.init()\n\n const claimerDidMnemonic = process.env.CLAIMER_DID_MNEMONIC as string\n const claimerDid = generateLightDid(claimerDidMnemonic)\n\n const request = generateCredential(claimerDid.uri, {\n age: 28,\n name: 'Max Mustermann'\n })\n console.log(\n '\u26a0\ufe0f save this to ./claimer/_credential.json for testing \u26a0\ufe0f\\n\\n'\n )\n console.log(JSON.stringify(request, null, 2))\n } catch (e) {\n console.log('Error while building credential')\n throw e\n }\n })()\n}\n",d={id:"request",title:"Request an Attestation"},h=void 0,m={id:"develop/workshop/claimer/request",title:"Request an Attestation",description:"This section covers creating a Claim and a Credential.",source:"@site/docs/develop/03_workshop/05_claimer/02_request.md",sourceDirName:"develop/03_workshop/05_claimer",slug:"/develop/workshop/claimer/request",permalink:"/docs/develop/workshop/claimer/request",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/03_workshop/05_claimer/02_request.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:2,frontMatter:{id:"request",title:"Request an Attestation"},sidebar:"workshop",previous:{title:"DID",permalink:"/docs/develop/workshop/claimer/did"},next:{title:"\ud83e\uddfe Attestation",permalink:"/docs/develop/workshop/attestation"}},p={},u=[{value:"Create Credential",id:"create-credential",level:2},{value:"Receive attestation for claim",id:"receive-attestation-for-claim",level:2},{value:"Run",id:"run",level:2}];function f(e){const t={a:"a",code:"code",em:"em",h2:"h2",p:"p",pre:"pre",...(0,a.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["This section covers creating a ",(0,i.jsx)(t.code,{children:"Claim"})," and a ",(0,i.jsx)(t.code,{children:"Credential"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["KILT is a premissionless system.\nAnyone or anything can claim something and attest to it.\nBut an attested credential only has value if the ",(0,i.jsx)("span",{className:"label-role verifier",children:"Verifier"})," of the credential ",(0,i.jsx)(t.em,{children:"trusts"})," the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," of the credential."]}),"\n",(0,i.jsx)(t.h2,{id:"create-credential",children:"Create Credential"}),"\n",(0,i.jsxs)(t.p,{children:["Use the previously created ",(0,i.jsx)(t.code,{children:"light DID"}),", ",(0,i.jsx)(t.code,{children:"ctype"}),", and ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"})," provided ",(0,i.jsx)(t.code,{children:"content"})," to generate the ",(0,i.jsx)(t.code,{children:"Claim"})," object."]}),"\n",(0,i.jsx)(t.p,{children:"A claim consists of attributes that we claim to be true about us."}),"\n",(0,i.jsx)(r.c,{fileName:"claimer/createClaim",children:c}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"fromCTypeAndClaimContents"})," function takes the ",(0,i.jsx)(t.code,{children:"lightDid"}),", ",(0,i.jsx)(t.code,{children:"ctype"}),", and ",(0,i.jsx)(t.code,{children:"content"})," values and generates a ",(0,i.jsx)(t.code,{children:"Claim"})," object."]}),"\n",(0,i.jsx)(t.h2,{id:"receive-attestation-for-claim",children:"Receive attestation for claim"}),"\n",(0,i.jsxs)(t.p,{children:["Since you want to receive an attestation for those claims, build a ",(0,i.jsx)(t.code,{children:"Credential"})," in the ",(0,i.jsx)(t.code,{children:"generateCredential"})," function below."]}),"\n",(0,i.jsxs)(t.p,{children:["The credential contains all necessary information so the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," can attest it."]}),"\n",(0,i.jsx)(r.c,{fileName:"claimer/generateCredential",children:o}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"main"})," function takes the Claimer mnemonic and generates the light DID following the steps outlined in the ",(0,i.jsx)(t.a,{href:"/docs/develop/workshop/claimer/did",children:"DID section"}),".\nIt then calls the ",(0,i.jsx)(t.code,{children:"generateCredential"})," function using the supplied claim attributes.\nIt then uses the ",(0,i.jsx)(t.code,{children:"createClaim"})," method from the previous step to create the ",(0,i.jsx)(t.code,{children:"Claim"})," object and the ",(0,i.jsx)(t.code,{children:"Kilt.Credential.fromClaim"})," method takes the claim and returns the ",(0,i.jsx)(t.code,{children:"Credential"})," object."]}),"\n",(0,i.jsxs)(t.p,{children:["When ",(0,i.jsx)("span",{className:"label-role attester",children:"Attesters"})," issue ",(0,i.jsx)(t.code,{children:"Attestations"}),", they are written to the chain, which requires a deposit.\nEach new ",(0,i.jsx)(t.code,{children:"Credential"})," is unique.\nDuring testing, you can store and reuse credentials into ",(0,i.jsx)(t.code,{children:"./claimer/_credential.json"})," to avoid multiple attestations."]}),"\n",(0,i.jsx)(t.p,{children:"You can share this credential with others following the workshop to see how they get denied from fraudulent senders."}),"\n",(0,i.jsx)(t.h2,{id:"run",children:"Run"}),"\n",(0,i.jsxs)(s.c,{groupId:"ts-js-choice",children:[(0,i.jsx)(l.c,{value:"ts",label:"Typescript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"yarn ts-node claimer/generateCredential.ts\n"})})}),(0,i.jsx)(l.c,{value:"js",label:"Javascript",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"node claimer/generateCredential.js\n"})})})]}),"\n",(0,i.jsxs)(t.p,{children:["OK, you've made a claim as a ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"})," and created a credential from it.\nThe next step is to finish the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," and get the credential attested!"]})]})}function j(e={}){const{wrapper:t}={...(0,a.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(f,{...e})}):f(e)}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>p});var i=n(11504),a=n(28264),r=n(46352),s=n(58440),l=n(14300),c=n(28168),o=n(61268),d=n(87768),h=n(1608),m=n(17624);const p=e=>{let{children:t,fileName:n,...p}=e;const u=t,[f,j]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:x}}}=(0,a.c)(),g=(0,i.useMemo)((()=>{const{code:e}=(0,r.transform)(u,{plugins:["transform-typescript"],retainLines:!0});return e}),[u]);(0,i.useEffect)((()=>{s.E9(g,{parser:"babel",plugins:[l.c,c.cp],...x}).then(j)}),[x,g]);const C=[{fileName:n?`${n}.ts`:void 0,fileContents:u,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:f,fileID:"js",fileLabel:"Javascript"}];return(0,m.jsx)(m.Fragment,{children:(0,m.jsx)(o.c,{groupId:"ts-js-choice",children:C.map((e=>(0,m.jsx)(d.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,m.jsx)(h.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3568],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},19164:(e,t,n)=>{"use strict";n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>h,default:()=>j,frontMatter:()=>d,metadata:()=>m,toc:()=>u});var i=n(17624),a=n(4552),r=n(96020),s=n(61268),l=n(87768);const c="import * as Kilt from '@kiltprotocol/sdk-js'\n\n// Create a Claim object from light DID, CType and given content.\nexport function createClaim(\n lightDid: Kilt.DidUri,\n ctype: Kilt.ICType,\n content: Kilt.IClaim['contents']\n): Kilt.IClaim {\n const claim = Kilt.Claim.fromCTypeAndClaimContents(ctype, content, lightDid)\n\n return claim\n}\n",o="import { config as envConfig } from 'dotenv'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\nimport { createClaim } from './createClaim'\nimport { generateLightDid } from './generateLightDid'\nimport { getCtypeSchema } from '../attester/ctypeSchema'\n\nexport function generateCredential(\n claimerDid: Kilt.DidUri,\n claimAttributes: Kilt.IClaim['contents']\n): Kilt.ICredential {\n // Create claim.\n const ctype = getCtypeSchema()\n const claim = createClaim(claimerDid, ctype, claimAttributes)\n\n // Create credential and request attestation.\n console.log('Claimer -> create request')\n return Kilt.Credential.fromClaim(claim)\n}\n\n// Don't execute if this is imported by another file.\nif (require.main === module) {\n ;(async () => {\n envConfig()\n\n try {\n await Kilt.init()\n\n const claimerDidMnemonic = process.env.CLAIMER_DID_MNEMONIC as string\n const claimerDid = generateLightDid(claimerDidMnemonic)\n\n const request = generateCredential(claimerDid.uri, {\n age: 28,\n name: 'Max Mustermann'\n })\n console.log(\n '\u26a0\ufe0f save this to ./claimer/_credential.json for testing \u26a0\ufe0f\\n\\n'\n )\n console.log(JSON.stringify(request, null, 2))\n } catch (e) {\n console.log('Error while building credential')\n throw e\n }\n })()\n}\n",d={id:"request",title:"Request an Attestation"},h=void 0,m={id:"develop/workshop/claimer/request",title:"Request an Attestation",description:"This section covers creating a Claim and a Credential.",source:"@site/docs/develop/03_workshop/05_claimer/02_request.md",sourceDirName:"develop/03_workshop/05_claimer",slug:"/develop/workshop/claimer/request",permalink:"/docs/develop/workshop/claimer/request",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/03_workshop/05_claimer/02_request.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:2,frontMatter:{id:"request",title:"Request an Attestation"},sidebar:"workshop",previous:{title:"DID",permalink:"/docs/develop/workshop/claimer/did"},next:{title:"\ud83e\uddfe Attestation",permalink:"/docs/develop/workshop/attestation"}},p={},u=[{value:"Create Credential",id:"create-credential",level:2},{value:"Receive attestation for claim",id:"receive-attestation-for-claim",level:2},{value:"Run",id:"run",level:2}];function f(e){const t={a:"a",code:"code",em:"em",h2:"h2",p:"p",pre:"pre",...(0,a.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(t.p,{children:["This section covers creating a ",(0,i.jsx)(t.code,{children:"Claim"})," and a ",(0,i.jsx)(t.code,{children:"Credential"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["KILT is a premissionless system.\nAnyone or anything can claim something and attest to it.\nBut an attested credential only has value if the ",(0,i.jsx)("span",{className:"label-role verifier",children:"Verifier"})," of the credential ",(0,i.jsx)(t.em,{children:"trusts"})," the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," of the credential."]}),"\n",(0,i.jsx)(t.h2,{id:"create-credential",children:"Create Credential"}),"\n",(0,i.jsxs)(t.p,{children:["Use the previously created ",(0,i.jsx)(t.code,{children:"light DID"}),", ",(0,i.jsx)(t.code,{children:"ctype"}),", and ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"})," provided ",(0,i.jsx)(t.code,{children:"content"})," to generate the ",(0,i.jsx)(t.code,{children:"Claim"})," object."]}),"\n",(0,i.jsx)(t.p,{children:"A claim consists of attributes that we claim to be true about us."}),"\n",(0,i.jsx)(r.c,{fileName:"claimer/createClaim",children:c}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"fromCTypeAndClaimContents"})," function takes the ",(0,i.jsx)(t.code,{children:"lightDid"}),", ",(0,i.jsx)(t.code,{children:"ctype"}),", and ",(0,i.jsx)(t.code,{children:"content"})," values and generates a ",(0,i.jsx)(t.code,{children:"Claim"})," object."]}),"\n",(0,i.jsx)(t.h2,{id:"receive-attestation-for-claim",children:"Receive attestation for claim"}),"\n",(0,i.jsxs)(t.p,{children:["Since you want to receive an attestation for those claims, build a ",(0,i.jsx)(t.code,{children:"Credential"})," in the ",(0,i.jsx)(t.code,{children:"generateCredential"})," function below."]}),"\n",(0,i.jsxs)(t.p,{children:["The credential contains all necessary information so the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," can attest it."]}),"\n",(0,i.jsx)(r.c,{fileName:"claimer/generateCredential",children:o}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"main"})," function takes the Claimer mnemonic and generates the light DID following the steps outlined in the ",(0,i.jsx)(t.a,{href:"/docs/develop/workshop/claimer/did",children:"DID section"}),".\nIt then calls the ",(0,i.jsx)(t.code,{children:"generateCredential"})," function using the supplied claim attributes.\nIt then uses the ",(0,i.jsx)(t.code,{children:"createClaim"})," method from the previous step to create the ",(0,i.jsx)(t.code,{children:"Claim"})," object and the ",(0,i.jsx)(t.code,{children:"Kilt.Credential.fromClaim"})," method takes the claim and returns the ",(0,i.jsx)(t.code,{children:"Credential"})," object."]}),"\n",(0,i.jsxs)(t.p,{children:["When ",(0,i.jsx)("span",{className:"label-role attester",children:"Attesters"})," issue ",(0,i.jsx)(t.code,{children:"Attestations"}),", they are written to the chain, which requires a deposit.\nEach new ",(0,i.jsx)(t.code,{children:"Credential"})," is unique.\nDuring testing, you can store and reuse credentials into ",(0,i.jsx)(t.code,{children:"./claimer/_credential.json"})," to avoid multiple attestations."]}),"\n",(0,i.jsx)(t.p,{children:"You can share this credential with others following the workshop to see how they get denied from fraudulent senders."}),"\n",(0,i.jsx)(t.h2,{id:"run",children:"Run"}),"\n",(0,i.jsxs)(s.c,{groupId:"ts-js-choice",children:[(0,i.jsx)(l.c,{value:"ts",label:"Typescript",default:!0,children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"yarn ts-node claimer/generateCredential.ts\n"})})}),(0,i.jsx)(l.c,{value:"js",label:"Javascript",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"node claimer/generateCredential.js\n"})})})]}),"\n",(0,i.jsxs)(t.p,{children:["OK, you've made a claim as a ",(0,i.jsx)("span",{className:"label-role claimer",children:"Claimer"})," and created a credential from it.\nThe next step is to finish the ",(0,i.jsx)("span",{className:"label-role attester",children:"Attester"})," and get the credential attested!"]})]})}function j(e={}){const{wrapper:t}={...(0,a.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(f,{...e})}):f(e)}},96020:(e,t,n)=>{"use strict";n.d(t,{c:()=>p});var i=n(11504),a=n(28264),r=n(46352),s=n(58440),l=n(14300),c=n(28168),o=n(61268),d=n(87768),h=n(1608),m=n(17624);const p=e=>{let{children:t,fileName:n,...p}=e;const u=t,[f,j]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:x}}}=(0,a.c)(),g=(0,i.useMemo)((()=>{const{code:e}=(0,r.transform)(u,{plugins:["transform-typescript"],retainLines:!0});return e}),[u]);(0,i.useEffect)((()=>{s.E9(g,{parser:"babel",plugins:[l.c,c.cp],...x}).then(j)}),[x,g]);const C=[{fileName:n?`${n}.ts`:void 0,fileContents:u,fileID:"ts",fileLabel:"Typescript"},{fileName:n?`${n}.js`:void 0,fileContents:f,fileID:"js",fileLabel:"Javascript"}];return(0,m.jsx)(m.Fragment,{children:(0,m.jsx)(o.c,{groupId:"ts-js-choice",children:C.map((e=>(0,m.jsx)(d.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,m.jsx)(h.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/1f78a1b9.b4b7eec5.js b/assets/js/1f78a1b9.fd6d5dad.js similarity index 97% rename from assets/js/1f78a1b9.b4b7eec5.js rename to assets/js/1f78a1b9.fd6d5dad.js index 7f96e9bbb..5d0293c90 100644 --- a/assets/js/1f78a1b9.b4b7eec5.js +++ b/assets/js/1f78a1b9.fd6d5dad.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1644],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},27036:(e,t,i)=>{"use strict";i.r(t),i.d(t,{assets:()=>m,contentTitle:()=>c,default:()=>u,frontMatter:()=>l,metadata:()=>d,toc:()=>h});var n=i(17624),o=i(4552),a=i(96020);const s="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function revokeCredential(\n attester: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n signCallback: Kilt.SignExtrinsicCallback,\n credential: Kilt.ICredential,\n shouldRemove = false\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n const tx = shouldRemove\n ? // If the attestation is to be removed, create a `remove` tx,\n // which revokes and removes the attestation in one go.\n api.tx.attestation.remove(credential.rootHash, null)\n : // Otherwise, simply revoke the attestation but leave it on chain.\n // Hence, the storage is not cleared and the deposit not returned.\n api.tx.attestation.revoke(credential.rootHash, null)\n\n const authorizedTx = await Kilt.Did.authorizeTx(\n attester,\n tx,\n signCallback,\n submitterAccount.address\n )\n\n // Submit the right tx to the KILT blockchain.\n await Kilt.Blockchain.signAndSubmitTx(authorizedTx, submitterAccount)\n}\n",r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function reclaimAttestationDeposit(\n submitterAddress: Kilt.KiltKeyringPair,\n credential: Kilt.ICredential\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Generate the tx to claim the deposit back.\n const depositReclaimTx = api.tx.attestation.reclaimDeposit(\n credential.rootHash\n )\n\n // Submit the revocation tx to the KILT blockchain.\n await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress)\n}\n",l={id:"attestation-removal",title:"Revoke a Credential"},c=void 0,d={id:"develop/sdk/cookbook/claiming/attestation-removal",title:"Revoke a Credential",description:"If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain.",source:"@site/docs/develop/01_sdk/02_cookbook/04_claiming/06_credential_revocation.md",sourceDirName:"develop/01_sdk/02_cookbook/04_claiming",slug:"/develop/sdk/cookbook/claiming/attestation-removal",permalink:"/docs/develop/sdk/cookbook/claiming/attestation-removal",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/04_claiming/06_credential_revocation.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:6,frontMatter:{id:"attestation-removal",title:"Revoke a Credential"},sidebar:"sdk",previous:{title:"Verify a Credential or a Presentation",permalink:"/docs/develop/sdk/cookbook/claiming/presentation-verification"},next:{title:"Credential Issuance",permalink:"/docs/develop/sdk/cookbook/public_credentials/public-credential-issuance"}},m={},h=[{value:"Claim Back an Attestation Deposit",id:"claim-back-an-attestation-deposit",level:2}];function p(e){const t={h2:"h2",p:"p",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain.\nThis 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."}),"\n",(0,n.jsx)(t.p,{children:"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."}),"\n",(0,n.jsx)(a.c,{children:s}),"\n",(0,n.jsx)(t.h2,{id:"claim-back-an-attestation-deposit",children:"Claim Back an Attestation Deposit"}),"\n",(0,n.jsx)(t.p,{children:"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:"}),"\n",(0,n.jsx)(a.c,{children:r})]})}function u(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},96020:(e,t,i)=>{"use strict";i.d(t,{c:()=>p});var n=i(11504),o=i(28264),a=i(46352),s=i(58440),r=i(14300),l=i(28168),c=i(61268),d=i(87768),m=i(1608),h=i(17624);const p=e=>{let{children:t,fileName:i,...p}=e;const u=t,[k,v]=(0,n.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:f}}}=(0,o.c)(),b=(0,n.useMemo)((()=>{const{code:e}=(0,a.transform)(u,{plugins:["transform-typescript"],retainLines:!0});return e}),[u]);(0,n.useEffect)((()=>{s.E9(b,{parser:"babel",plugins:[r.c,l.cp],...f}).then(v)}),[f,b]);const g=[{fileName:i?`${i}.ts`:void 0,fileContents:u,fileID:"ts",fileLabel:"Typescript"},{fileName:i?`${i}.js`:void 0,fileContents:k,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(c.c,{groupId:"ts-js-choice",children:g.map((e=>(0,h.jsx)(d.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,h.jsx)(m.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[1644],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},27036:(e,t,i)=>{"use strict";i.r(t),i.d(t,{assets:()=>m,contentTitle:()=>c,default:()=>u,frontMatter:()=>l,metadata:()=>d,toc:()=>h});var n=i(17624),o=i(4552),a=i(96020);const s="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function revokeCredential(\n attester: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n signCallback: Kilt.SignExtrinsicCallback,\n credential: Kilt.ICredential,\n shouldRemove = false\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n const tx = shouldRemove\n ? // If the attestation is to be removed, create a `remove` tx,\n // which revokes and removes the attestation in one go.\n api.tx.attestation.remove(credential.rootHash, null)\n : // Otherwise, simply revoke the attestation but leave it on chain.\n // Hence, the storage is not cleared and the deposit not returned.\n api.tx.attestation.revoke(credential.rootHash, null)\n\n const authorizedTx = await Kilt.Did.authorizeTx(\n attester,\n tx,\n signCallback,\n submitterAccount.address\n )\n\n // Submit the right tx to the KILT blockchain.\n await Kilt.Blockchain.signAndSubmitTx(authorizedTx, submitterAccount)\n}\n",r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function reclaimAttestationDeposit(\n submitterAddress: Kilt.KiltKeyringPair,\n credential: Kilt.ICredential\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Generate the tx to claim the deposit back.\n const depositReclaimTx = api.tx.attestation.reclaimDeposit(\n credential.rootHash\n )\n\n // Submit the revocation tx to the KILT blockchain.\n await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress)\n}\n",l={id:"attestation-removal",title:"Revoke a Credential"},c=void 0,d={id:"develop/sdk/cookbook/claiming/attestation-removal",title:"Revoke a Credential",description:"If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain.",source:"@site/docs/develop/01_sdk/02_cookbook/04_claiming/06_credential_revocation.md",sourceDirName:"develop/01_sdk/02_cookbook/04_claiming",slug:"/develop/sdk/cookbook/claiming/attestation-removal",permalink:"/docs/develop/sdk/cookbook/claiming/attestation-removal",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/04_claiming/06_credential_revocation.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:6,frontMatter:{id:"attestation-removal",title:"Revoke a Credential"},sidebar:"sdk",previous:{title:"Verify a Credential or a Presentation",permalink:"/docs/develop/sdk/cookbook/claiming/presentation-verification"},next:{title:"Credential Issuance",permalink:"/docs/develop/sdk/cookbook/public_credentials/public-credential-issuance"}},m={},h=[{value:"Claim Back an Attestation Deposit",id:"claim-back-an-attestation-deposit",level:2}];function p(e){const t={h2:"h2",p:"p",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain.\nThis 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."}),"\n",(0,n.jsx)(t.p,{children:"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."}),"\n",(0,n.jsx)(a.c,{children:s}),"\n",(0,n.jsx)(t.h2,{id:"claim-back-an-attestation-deposit",children:"Claim Back an Attestation Deposit"}),"\n",(0,n.jsx)(t.p,{children:"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:"}),"\n",(0,n.jsx)(a.c,{children:r})]})}function u(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},96020:(e,t,i)=>{"use strict";i.d(t,{c:()=>p});var n=i(11504),o=i(28264),a=i(46352),s=i(58440),r=i(14300),l=i(28168),c=i(61268),d=i(87768),m=i(1608),h=i(17624);const p=e=>{let{children:t,fileName:i,...p}=e;const u=t,[k,v]=(0,n.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:f}}}=(0,o.c)(),b=(0,n.useMemo)((()=>{const{code:e}=(0,a.transform)(u,{plugins:["transform-typescript"],retainLines:!0});return e}),[u]);(0,n.useEffect)((()=>{s.E9(b,{parser:"babel",plugins:[r.c,l.cp],...f}).then(v)}),[f,b]);const g=[{fileName:i?`${i}.ts`:void 0,fileContents:u,fileID:"ts",fileLabel:"Typescript"},{fileName:i?`${i}.js`:void 0,fileContents:k,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(c.c,{groupId:"ts-js-choice",children:g.map((e=>(0,h.jsx)(d.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,h.jsx)(m.c,{...p,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/23178811.69dbf8ae.js b/assets/js/23178811.cff3f5ff.js similarity index 99% rename from assets/js/23178811.69dbf8ae.js rename to assets/js/23178811.cff3f5ff.js index b756cadf0..7a43b3523 100644 --- a/assets/js/23178811.69dbf8ae.js +++ b/assets/js/23178811.cff3f5ff.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[616],{84568:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>r,default:()=>l,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var n=s(17624),i=s(4552);s(61964);const a={id:"asset-dids",title:"AssetDIDs"},r=void 0,c={id:"concepts/asset-dids",title:"AssetDIDs",description:'KILT DIDs are suitable for use cases that involve "active" participants.',source:"@site/docs/concepts/04_asset_dids.md",sourceDirName:"concepts",slug:"/concepts/asset-dids",permalink:"/docs/concepts/asset-dids",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/04_asset_dids.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:4,frontMatter:{id:"asset-dids",title:"AssetDIDs"},sidebar:"concepts",previous:{title:"web3names",permalink:"/docs/concepts/web3names"},next:{title:"Overview",permalink:"/docs/concepts/credentials/overview"}},o={},d=[{value:"AssetDID structure",id:"assetdid-structure",level:2},{value:"Chain namespace and reference",id:"chain-namespace-and-reference",level:3},{value:"Asset namespace, reference and identifier",id:"asset-namespace-reference-and-identifier",level:3}];function h(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",p:"p",strong:"strong",...(0,i.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:'KILT DIDs are suitable for use cases that involve "active" participants.\nFor example, entities that can act of their will (a person, an organization, a DAO).'}),"\n",(0,n.jsxs)(t.p,{children:['There are classes of entities that represent "passive" participants.\nThat is, they can be "used" by active participants within a given use case.\nKILT defines these class of participants as ',(0,n.jsx)(t.strong,{children:"assets"}),".\nAs with traditional KILT users, assets also need to be uniquely identified, with an ",(0,n.jsx)(t.em,{children:"AssetDID"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["An example of a valid AssetDID is the following: ",(0,n.jsx)(t.code,{children:"did:asset:eip155:1.erc721:0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb"}),".\nThis AssetDID refers to the ",(0,n.jsx)(t.a,{href:"https://opensea.io/collection/cryptopunks",children:"CryptoPunks NFT collection"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"assetdid-structure",children:"AssetDID structure"}),"\n",(0,n.jsxs)(t.p,{children:["An AssetDID is a ",(0,n.jsx)(t.em,{children:"generative"})," identifier, meaning that it doesn't depend nor rely on any information stored anywhere.\nRather, given the asset to identify, it's ",(0,n.jsx)(t.strong,{children:"always"})," possible to generate its AssetDID.\nThe reverse is also true. Given an AssetDID, it's always possible to dereference it into its components, which, together, uniquely identify a given asset."]}),"\n",(0,n.jsxs)(t.p,{children:["AssetDIDs always start with the ",(0,n.jsx)(t.code,{children:"did:asset"})," prefix, and then contain a ",(0,n.jsx)(t.em,{children:"chain"})," component (namespace + reference) and an ",(0,n.jsx)(t.em,{children:"asset"})," component (namespace + reference + identifier)."]}),"\n",(0,n.jsx)(t.h3,{id:"chain-namespace-and-reference",children:"Chain namespace and reference"}),"\n",(0,n.jsx)(t.p,{children:"Together, the namespace and reference identify the (blockchain) network on which the asset lives."}),"\n",(0,n.jsxs)(t.p,{children:["In the case of NFTs, this represents the blockchain on which the smart contract is deployed.\nDifferent deployments of the same network have the same chain namespace but a different reference.\nFor instance, both the Ethereum mainnet and the Goerli testnet have a chain namespace of ",(0,n.jsx)(t.code,{children:"eip155"}),", but the former is identified by the reference ",(0,n.jsx)(t.code,{children:"1"})," (as the mainnet), while the Goerli testnet is identified by the reference ",(0,n.jsx)(t.code,{children:"5"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"asset-namespace-reference-and-identifier",children:"Asset namespace, reference and identifier"}),"\n",(0,n.jsxs)(t.p,{children:["Similar to their chain counterparts, you use asset ",(0,n.jsx)(t.em,{children:"namespaces"})," to distinguish among different asset classes within the same environment.\nIn the case of NFTs, a smart contract could support both ERC20 (fungible) and ERC721 (non-fungible) tokens, hence the namespace distinguishes between the two token types."]}),"\n",(0,n.jsxs)(t.p,{children:["Each asset namespace defines the semantics and the meaning of asset references and asset identifiers within that namespace.\nIn the example of Ethereum-based NFTs, the asset ",(0,n.jsx)(t.em,{children:"reference"})," identifies the smart contract address that stores the NFT."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"The combination of asset namespace + asset reference is sufficient to identify an NFT collection on a given network."})}),"\n",(0,n.jsxs)(t.p,{children:["For some assets, for instance NFTs, it's possible to specify an asset ",(0,n.jsx)(t.em,{children:"identifier"}),", used to refer to a single item within the collection.\nIn the example of the CryptoPunks collection, the AssetDID could be extended with an additional ",(0,n.jsx)(t.code,{children:":1005"})," to now refer to the ",(0,n.jsx)(t.a,{href:"https://opensea.io/assets/ethereum/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/1005",children:"CryptoPunk piece #1005"})," rather than to the CryptoPunks collection as a whole."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:"https://i.seadn.io/gae/qoR1cWuIZzjlrNVcSMAzhrwDvXNtMxaYuDbNqkc_J5WGGqMSrF0wzO7K2MnSCEBLG8G8pZyJPqV7eTGt4wGwret85sbXJBYoAkypdQ?auto=format&w=3840",alt:""})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.em,{children:"Credits to OpenSea for the NFT image above."})}),"\n",(0,n.jsxs)(t.p,{children:["For a more technical explanation of AssetDIDs, please visit our ",(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-asset-did",children:"official specification"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,i.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},4552:(e,t,s)=>{s.d(t,{I:()=>c,M:()=>r});var n=s(11504);const i={},a=n.createContext(i);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[616],{84568:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>o,contentTitle:()=>r,default:()=>l,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var n=s(17624),i=s(4552);s(61964);const a={id:"asset-dids",title:"AssetDIDs"},r=void 0,c={id:"concepts/asset-dids",title:"AssetDIDs",description:'KILT DIDs are suitable for use cases that involve "active" participants.',source:"@site/docs/concepts/04_asset_dids.md",sourceDirName:"concepts",slug:"/concepts/asset-dids",permalink:"/docs/concepts/asset-dids",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/04_asset_dids.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:4,frontMatter:{id:"asset-dids",title:"AssetDIDs"},sidebar:"concepts",previous:{title:"web3names",permalink:"/docs/concepts/web3names"},next:{title:"Overview",permalink:"/docs/concepts/credentials/overview"}},o={},d=[{value:"AssetDID structure",id:"assetdid-structure",level:2},{value:"Chain namespace and reference",id:"chain-namespace-and-reference",level:3},{value:"Asset namespace, reference and identifier",id:"asset-namespace-reference-and-identifier",level:3}];function h(e){const t={a:"a",code:"code",em:"em",h2:"h2",h3:"h3",img:"img",p:"p",strong:"strong",...(0,i.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:'KILT DIDs are suitable for use cases that involve "active" participants.\nFor example, entities that can act of their will (a person, an organization, a DAO).'}),"\n",(0,n.jsxs)(t.p,{children:['There are classes of entities that represent "passive" participants.\nThat is, they can be "used" by active participants within a given use case.\nKILT defines these class of participants as ',(0,n.jsx)(t.strong,{children:"assets"}),".\nAs with traditional KILT users, assets also need to be uniquely identified, with an ",(0,n.jsx)(t.em,{children:"AssetDID"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["An example of a valid AssetDID is the following: ",(0,n.jsx)(t.code,{children:"did:asset:eip155:1.erc721:0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb"}),".\nThis AssetDID refers to the ",(0,n.jsx)(t.a,{href:"https://opensea.io/collection/cryptopunks",children:"CryptoPunks NFT collection"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"assetdid-structure",children:"AssetDID structure"}),"\n",(0,n.jsxs)(t.p,{children:["An AssetDID is a ",(0,n.jsx)(t.em,{children:"generative"})," identifier, meaning that it doesn't depend nor rely on any information stored anywhere.\nRather, given the asset to identify, it's ",(0,n.jsx)(t.strong,{children:"always"})," possible to generate its AssetDID.\nThe reverse is also true. Given an AssetDID, it's always possible to dereference it into its components, which, together, uniquely identify a given asset."]}),"\n",(0,n.jsxs)(t.p,{children:["AssetDIDs always start with the ",(0,n.jsx)(t.code,{children:"did:asset"})," prefix, and then contain a ",(0,n.jsx)(t.em,{children:"chain"})," component (namespace + reference) and an ",(0,n.jsx)(t.em,{children:"asset"})," component (namespace + reference + identifier)."]}),"\n",(0,n.jsx)(t.h3,{id:"chain-namespace-and-reference",children:"Chain namespace and reference"}),"\n",(0,n.jsx)(t.p,{children:"Together, the namespace and reference identify the (blockchain) network on which the asset lives."}),"\n",(0,n.jsxs)(t.p,{children:["In the case of NFTs, this represents the blockchain on which the smart contract is deployed.\nDifferent deployments of the same network have the same chain namespace but a different reference.\nFor instance, both the Ethereum mainnet and the Goerli testnet have a chain namespace of ",(0,n.jsx)(t.code,{children:"eip155"}),", but the former is identified by the reference ",(0,n.jsx)(t.code,{children:"1"})," (as the mainnet), while the Goerli testnet is identified by the reference ",(0,n.jsx)(t.code,{children:"5"}),"."]}),"\n",(0,n.jsx)(t.h3,{id:"asset-namespace-reference-and-identifier",children:"Asset namespace, reference and identifier"}),"\n",(0,n.jsxs)(t.p,{children:["Similar to their chain counterparts, you use asset ",(0,n.jsx)(t.em,{children:"namespaces"})," to distinguish among different asset classes within the same environment.\nIn the case of NFTs, a smart contract could support both ERC20 (fungible) and ERC721 (non-fungible) tokens, hence the namespace distinguishes between the two token types."]}),"\n",(0,n.jsxs)(t.p,{children:["Each asset namespace defines the semantics and the meaning of asset references and asset identifiers within that namespace.\nIn the example of Ethereum-based NFTs, the asset ",(0,n.jsx)(t.em,{children:"reference"})," identifies the smart contract address that stores the NFT."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"The combination of asset namespace + asset reference is sufficient to identify an NFT collection on a given network."})}),"\n",(0,n.jsxs)(t.p,{children:["For some assets, for instance NFTs, it's possible to specify an asset ",(0,n.jsx)(t.em,{children:"identifier"}),", used to refer to a single item within the collection.\nIn the example of the CryptoPunks collection, the AssetDID could be extended with an additional ",(0,n.jsx)(t.code,{children:":1005"})," to now refer to the ",(0,n.jsx)(t.a,{href:"https://opensea.io/assets/ethereum/0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb/1005",children:"CryptoPunk piece #1005"})," rather than to the CryptoPunks collection as a whole."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:"https://i.seadn.io/gae/qoR1cWuIZzjlrNVcSMAzhrwDvXNtMxaYuDbNqkc_J5WGGqMSrF0wzO7K2MnSCEBLG8G8pZyJPqV7eTGt4wGwret85sbXJBYoAkypdQ?auto=format&w=3840",alt:""})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.em,{children:"Credits to OpenSea for the NFT image above."})}),"\n",(0,n.jsxs)(t.p,{children:["For a more technical explanation of AssetDIDs, please visit our ",(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-asset-did",children:"official specification"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,i.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},4552:(e,t,s)=>{s.d(t,{I:()=>c,M:()=>r});var n=s(11504);const i={},a=n.createContext(i);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23f8d77a.a51d9997.js b/assets/js/23f8d77a.59c1ca7b.js similarity index 86% rename from assets/js/23f8d77a.a51d9997.js rename to assets/js/23f8d77a.59c1ca7b.js index 4c07c6374..4f4f6c5d8 100644 --- a/assets/js/23f8d77a.a51d9997.js +++ b/assets/js/23f8d77a.59c1ca7b.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3324],{48952:e=>{function o(e){var o=new Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}o.keys=()=>[],o.resolve=o,o.id=48952,e.exports=o},43792:(e,o,t)=>{"use strict";t.r(o),t.d(o,{assets:()=>a,contentTitle:()=>c,default:()=>D,frontMatter:()=>d,metadata:()=>l,toc:()=>p});var n=t(17624),i=t(4552),s=t(96020);const r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function exportDid(\n did: Kilt.DidDocument,\n exportType: 'application/json' | 'application/ld+json'\n) {\n const conformingDidDocument = Kilt.Did.exportToDidDocument(did, exportType)\n\n // Will print the DID URI.\n console.log(conformingDidDocument.id)\n\n // Will print all the public keys associated with the DID.\n console.log(conformingDidDocument.verificationMethod)\n\n // Will print all the assertion keys IDs.\n console.log(conformingDidDocument.assertionMethod)\n\n // Will print all the encryption keys IDs.\n console.log(conformingDidDocument.keyAgreement)\n\n // Will print all the delegation keys IDs.\n console.log(conformingDidDocument.capabilityDelegation)\n\n // Will print all the external services referenced inside the `DidDocument` instance.\n console.log(conformingDidDocument.service)\n\n return conformingDidDocument\n}\n",d={id:"did-export",title:"Exporting a KILT DID"},c=void 0,l={id:"develop/sdk/cookbook/dids/did-export",title:"Exporting a KILT DID",description:"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.",source:"@site/docs/develop/01_sdk/02_cookbook/01_dids/08_did_export.md",sourceDirName:"develop/01_sdk/02_cookbook/01_dids",slug:"/develop/sdk/cookbook/dids/did-export",permalink:"/docs/develop/sdk/cookbook/dids/did-export",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/01_dids/08_did_export.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:8,frontMatter:{id:"did-export",title:"Exporting a KILT DID"},sidebar:"sdk",previous:{title:"Generate and Verify a DID Signature",permalink:"/docs/develop/sdk/cookbook/dids/did-signature"},next:{title:"Claim a web3name",permalink:"/docs/develop/sdk/cookbook/web3names/web3name-claim"}},a={},p=[{value:"How to use the exporter",id:"how-to-use-the-exporter",level:2}];function h(e){const o={a:"a",code:"code",h2:"h2",p:"p",...(0,i.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(o.p,{children:["The DID Document exporter provides the functionality needed to convert an instance of an SDK ",(0,n.jsx)(o.code,{children:"DidDocument"})," object into a document that is compliant with the ",(0,n.jsx)(o.a,{href:"https://www.w3.org/TR/did-core/",children:"W3C specification"}),".\nThis component is required for the KILT plugin for the ",(0,n.jsx)(o.a,{href:"https://dev.uniresolver.io/",children:"DIF Universal Resolver"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"how-to-use-the-exporter",children:"How to use the exporter"}),"\n",(0,n.jsxs)(o.p,{children:["The exporter interface and used types are part of the ",(0,n.jsx)(o.code,{children:"@kiltprotocol/types"})," package, while the actual ",(0,n.jsx)(o.code,{children:"DidDocumentExporter"})," is part of the ",(0,n.jsx)(o.code,{children:"@kiltprotocol/did"})," package.\nBoth types and DID packages are accessible via the top-level ",(0,n.jsx)(o.code,{children:"@kiltprotocol/sdk-js"})," import.\nThe following shows how to use the exporter to generate a W3C-compliant DID Document from a given ",(0,n.jsx)(o.code,{children:"DidDocument"}),", which can represent either a light or a full DID."]}),"\n",(0,n.jsx)(s.c,{children:r})]})}function D(e={}){const{wrapper:o}={...(0,i.M)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},96020:(e,o,t)=>{"use strict";t.d(o,{c:()=>D});var n=t(11504),i=t(28264),s=t(46352),r=t(58440),d=t(14300),c=t(28168),l=t(61268),a=t(87768),p=t(1608),h=t(17624);const D=e=>{let{children:o,fileName:t,...D}=e;const u=o,[m,f]=(0,n.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:k}}}=(0,i.c)(),x=(0,n.useMemo)((()=>{const{code:e}=(0,s.transform)(u,{plugins:["transform-typescript"],retainLines:!0});return e}),[u]);(0,n.useEffect)((()=>{r.E9(x,{parser:"babel",plugins:[d.c,c.cp],...k}).then(f)}),[k,x]);const g=[{fileName:t?`${t}.ts`:void 0,fileContents:u,fileID:"ts",fileLabel:"Typescript"},{fileName:t?`${t}.js`:void 0,fileContents:m,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(l.c,{groupId:"ts-js-choice",children:g.map((e=>(0,h.jsx)(a.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,h.jsx)(p.c,{...D,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3324],{48952:e=>{function o(e){var o=new Error("Cannot find module '"+e+"'");throw o.code="MODULE_NOT_FOUND",o}o.keys=()=>[],o.resolve=o,o.id=48952,e.exports=o},43792:(e,o,t)=>{"use strict";t.r(o),t.d(o,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>d,metadata:()=>l,toc:()=>p});var n=t(17624),i=t(4552),s=t(96020);const r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function exportDid(\n did: Kilt.DidDocument,\n exportType: 'application/json' | 'application/ld+json'\n) {\n const conformingDidDocument = Kilt.Did.exportToDidDocument(did, exportType)\n\n // Will print the DID URI.\n console.log(conformingDidDocument.id)\n\n // Will print all the public keys associated with the DID.\n console.log(conformingDidDocument.verificationMethod)\n\n // Will print all the assertion keys IDs.\n console.log(conformingDidDocument.assertionMethod)\n\n // Will print all the encryption keys IDs.\n console.log(conformingDidDocument.keyAgreement)\n\n // Will print all the delegation keys IDs.\n console.log(conformingDidDocument.capabilityDelegation)\n\n // Will print all the external services referenced inside the `DidDocument` instance.\n console.log(conformingDidDocument.service)\n\n return conformingDidDocument\n}\n",d={id:"did-export",title:"Exporting a KILT DID"},c=void 0,l={id:"develop/sdk/cookbook/dids/did-export",title:"Exporting a KILT DID",description:"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.",source:"@site/docs/develop/01_sdk/02_cookbook/01_dids/08_did_export.md",sourceDirName:"develop/01_sdk/02_cookbook/01_dids",slug:"/develop/sdk/cookbook/dids/did-export",permalink:"/docs/develop/sdk/cookbook/dids/did-export",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/01_dids/08_did_export.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:8,frontMatter:{id:"did-export",title:"Exporting a KILT DID"},sidebar:"sdk",previous:{title:"Generate and Verify a DID Signature",permalink:"/docs/develop/sdk/cookbook/dids/did-signature"},next:{title:"Claim a web3name",permalink:"/docs/develop/sdk/cookbook/web3names/web3name-claim"}},a={},p=[{value:"How to use the exporter",id:"how-to-use-the-exporter",level:2}];function h(e){const o={a:"a",code:"code",h2:"h2",p:"p",...(0,i.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(o.p,{children:["The DID Document exporter provides the functionality needed to convert an instance of an SDK ",(0,n.jsx)(o.code,{children:"DidDocument"})," object into a document that is compliant with the ",(0,n.jsx)(o.a,{href:"https://www.w3.org/TR/did-core/",children:"W3C specification"}),".\nThis component is required for the KILT plugin for the ",(0,n.jsx)(o.a,{href:"https://dev.uniresolver.io/",children:"DIF Universal Resolver"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"how-to-use-the-exporter",children:"How to use the exporter"}),"\n",(0,n.jsxs)(o.p,{children:["The exporter interface and used types are part of the ",(0,n.jsx)(o.code,{children:"@kiltprotocol/types"})," package, while the actual ",(0,n.jsx)(o.code,{children:"DidDocumentExporter"})," is part of the ",(0,n.jsx)(o.code,{children:"@kiltprotocol/did"})," package.\nBoth types and DID packages are accessible via the top-level ",(0,n.jsx)(o.code,{children:"@kiltprotocol/sdk-js"})," import.\nThe following shows how to use the exporter to generate a W3C-compliant DID Document from a given ",(0,n.jsx)(o.code,{children:"DidDocument"}),", which can represent either a light or a full DID."]}),"\n",(0,n.jsx)(s.c,{children:r})]})}function u(e={}){const{wrapper:o}={...(0,i.M)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},96020:(e,o,t)=>{"use strict";t.d(o,{c:()=>u});var n=t(11504),i=t(28264),s=t(46352),r=t(58440),d=t(14300),c=t(28168),l=t(61268),a=t(87768),p=t(1608),h=t(17624);const u=e=>{let{children:o,fileName:t,...u}=e;const D=o,[m,f]=(0,n.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:k}}}=(0,i.c)(),x=(0,n.useMemo)((()=>{const{code:e}=(0,s.transform)(D,{plugins:["transform-typescript"],retainLines:!0});return e}),[D]);(0,n.useEffect)((()=>{r.E9(x,{parser:"babel",plugins:[d.c,c.cp],...k}).then(f)}),[k,x]);const g=[{fileName:t?`${t}.ts`:void 0,fileContents:D,fileID:"ts",fileLabel:"Typescript"},{fileName:t?`${t}.js`:void 0,fileContents:m,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(l.c,{groupId:"ts-js-choice",children:g.map((e=>(0,h.jsx)(a.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,h.jsx)(p.c,{...u,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/2500a579.ac37e3b0.js b/assets/js/2500a579.e45c4c2f.js similarity index 99% rename from assets/js/2500a579.ac37e3b0.js rename to assets/js/2500a579.e45c4c2f.js index 0fe32eab8..07fc54b26 100644 --- a/assets/js/2500a579.ac37e3b0.js +++ b/assets/js/2500a579.e45c4c2f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3684],{42948:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>d});var a=n(17624),r=n(4552),o=(n(61268),n(87768),n(77440));const l={id:"join",title:"Become a Delegator"},i=void 0,s={id:"participate/staking/delegate/join",title:"Become a Delegator",description:"In contrast to the rather difficult path to become a collator candidate, joining the delegator pool is rather simple.",source:"@site/docs/participate/01_staking/03_delegate/02_become.md",sourceDirName:"participate/01_staking/03_delegate",slug:"/participate/staking/delegate/join",permalink:"/docs/participate/staking/delegate/join",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/03_delegate/02_become.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:2,frontMatter:{id:"join",title:"Become a Delegator"},sidebar:"staking",previous:{title:"Overview",permalink:"/docs/participate/staking/delegate/overview"},next:{title:"Adjust Your Delegation Stake",permalink:"/docs/participate/staking/delegate/adjust-stake"}},c={},d=[{value:"Happy Path",id:"happy-path",level:2},{value:"Unhappy Path",id:"unhappy-path",level:2}];function u(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",ul:"ul",...(0,r.M)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t.p,{children:["In contrast to the rather difficult ",(0,a.jsx)(t.a,{href:"/docs/participate/staking/become_a_collator/overview",children:"path to become a collator candidate"}),", joining the delegator pool is rather simple.\nAnyone can delegate to a collator candidate by staking a minimum of 20 KILT and calling ",(0,a.jsx)(t.code,{children:"parachainStaking -> joinDelegators"}),"."]}),"\n",(0,a.jsx)(o.cp,{}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{src:n(25236).c+"",width:"2004",height:"1334"})}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["Select the KILT address you want to delegate from as the extrinsic submitter (the ",(0,a.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,a.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,a.jsx)(t.code,{children:"parachainStaking -> joinDelegators"})]}),"\n",(0,a.jsxs)(t.li,{children:["Select the ",(0,a.jsx)(t.code,{children:"Id"})," option (the ",(0,a.jsx)(t.em,{children:"MultiAddress (LookupSource) field"}),")"]}),"\n",(0,a.jsxs)(t.li,{children:["Select the collator account (the ",(0,a.jsx)(t.em,{children:"Id: AccountId"})," field)"]}),"\n",(0,a.jsx)(t.li,{children:"Choose the desired stake amount."}),"\n",(0,a.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,a.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsxs)(t.p,{children:["A recent change in the blockchain metadata resulted in a change in the UI regarding how balances are shown.\nIn the current version of PolkadotJS Apps, specifying 1 KILT requires adding 15 trailing ",(0,a.jsx)(t.code,{children:"0"}),"s.\nSo, for instance, 1 KILT needs to be written as ",(0,a.jsx)(t.code,{children:"1,000,000,000,000,000"}),", while 10,000 KILT would be written as ",(0,a.jsx)(t.code,{children:"10,000,000,000,000,000,000"}),"."]})}),"\n",(0,a.jsx)(t.h2,{id:"happy-path",children:"Happy Path"}),"\n",(0,a.jsx)(t.p,{children:"If your chosen collator candidate has at least one empty slot in their delegation pool (out of 35 maximum slots at the time of writing), your delegation will be successful and you immediately start receiving rewards each time the collator you delegated produces a block."}),"\n",(0,a.jsx)("div",{className:"kilt-mermaid",children:(0,a.jsx)(t.mermaid,{value:'flowchart TD\n A["Hold at least 20 KILT"] --\x3e |"decide on candidate"| B("Collator Candidate chosen");\n B --\x3e |"call extrinsic joinDelegators"| C{"Can delegate to target? \\n Either \\n 1. There are empty \\n delegations or \\n 2. You delegate more \\n than another Delegator"};\n C --\x3e |yes| D("Delegating to a Collator Candidate")\n D --\x3e |"Collator produces block"| E("Account rewards")\n E --\x3e |"claim"| F("Have rewards in wallet")\n %% Styles\n A:::unstakedFreeKilt\n B:::preDelegationCheck\n C:::preDelegationCheck\n D:::activelyDelegating\n E:::activelyDelegating\n F:::activelyDelegating\n\n %% StyleDef\n classDef preDelegationCheck fill:#FFF4BD, stroke:none, color:black;\n classDef notDelegating fill:#F1C0B9, stroke:black, color:black, stroke-width:1px;;\n classDef unstakedFreeKilt fill:#85D2D0, stroke:black, color:black, stroke-width:1px;\n classDef activelyDelegating fill:#94C973, stroke:#333, color:black, stroke-width:2px;\n classDef preUnlockStaked fill:#F37970, stroke:black, color:black;'})}),"\n",(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsx)(t.p,{children:"If your chosen collator fails to produce blocks, neither the collator itself nor their delegators receive rewards.\nThis can happen if the collator has connectivity issues or are not building blocks fast enough."})}),"\n",(0,a.jsx)(t.h2,{id:"unhappy-path",children:"Unhappy Path"}),"\n",(0,a.jsx)(t.p,{children:"If the delegation pool of your chosen collator candidate is full, you may still delegate to them if you stake more than the current lowest delegator stake of that pool.\nWhen that happens,"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The kicked delegator will be replaced by the delegator with a higher delegation (you) immediately"}),"\n",(0,a.jsxs)(t.li,{children:["The kicked delegator's stake is prepared for unstaking as if they revoked the delegation (",(0,a.jsxs)(t.em,{children:["see ",(0,a.jsx)(t.a,{href:"#Revoking",children:"revoking"})]}),")"]}),"\n",(0,a.jsx)(t.li,{children:"A delegator needs to wait 7 days (in block time) to be able to unlock the stake.\nPlease note that it can take longer in real time as the block times assumes a constant block time of 12s, which is not guaranteed."}),"\n"]}),"\n",(0,a.jsx)("div",{className:"kilt-mermaid",children:(0,a.jsx)(t.mermaid,{value:'flowchart TD\n A["Hold at least 20 KILT"] --\x3e |"Decide on candidate"| B("Collator candidate chosen");\n B --\x3e |"Call extrinsic joinDelegators"| C{"Can delegate to target? \\n Either \\n 1. There are empty \\n delegations or \\n 2. You delegate more \\n than another delegator"};\n C --\x3e |no| C2{"Balance locked?\\n e.g., previously delegated \\n without unlocking?"}\n C2 --\x3e |no| A\n\n %% Styles\n A:::unstakedFreeKilt\n B:::preDelegationCheck\n C:::preDelegationCheck\n C2:::notDelegating\n\n %% StyleDef\n classDef preDelegationCheck fill:#FFF4BD, stroke:none, color:black;\n classDef notDelegating fill:#F1C0B9, stroke:black, color:black, stroke-width:1px;\n classDef unstakedFreeKilt fill:#85D2D0, stroke:black, color:black, stroke-width:1px;'})}),"\n",(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsxs)(t.p,{children:["For now, an account can only delegate to one collator at any time!\nMoreover, you can only (re-) delegate, e.g., call ",(0,a.jsx)(t.code,{children:"parachainStaking -> {joinDelegators, delegateAnotherCandidate}"}),", once per staking round."]})})]})}function h(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},77440:(e,t,n)=>{n.d(t,{cp:()=>l});var a=n(17624),r=n(4552);function o(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",strong:"strong",...(0,r.M)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsxs)(t.p,{children:["You can either execute this transaction in Polkadot JS Apps or the ",(0,a.jsx)(t.a,{href:"/docs/develop/builtonkilt#web-apps",children:(0,a.jsx)(t.strong,{children:"KILT Stakeboard"})}),", which serves as an in-house developed Frontend for all KILT staking activity.\nBelow, we outline the steps for Polkadot JS Apps.\nThe process for KILT Stakeboard is described in detail in the ",(0,a.jsx)(t.a,{href:"https://support.kilt.io/support/solutions/80000442174",children:(0,a.jsx)(t.strong,{children:"BOTLabs Trusted Entity support hub"})}),"."]})}),"\n",(0,a.jsxs)(t.p,{children:["In the Polkadot JS Apps (",(0,a.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer",children:"wss://spiritnet.kilt.io"}),", or ",(0,a.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer",children:"wss://peregrine.kilt.io"}),") go to ",(0,a.jsx)(t.code,{children:"Developer -> Extrinsics -> Submission"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(o,{...e})}):o(e)}},87768:(e,t,n)=>{n.d(t,{c:()=>l});n(11504);var a=n(65456);const r={tabItem:"tabItem_Ymn6"};var o=n(17624);function l(e){let{children:t,hidden:n,className:l}=e;return(0,o.jsx)("div",{role:"tabpanel",className:(0,a.c)(r.tabItem,l),hidden:n,children:t})}},61268:(e,t,n)=>{n.d(t,{c:()=>y});var a=n(11504),r=n(65456),o=n(53943),l=n(55592),i=n(95288),s=n(10632),c=n(27128),d=n(21148);function u(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??function(e){return u(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}(n);return function(e){const t=(0,c.w)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function p(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.Uz)(),o=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,s._M)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(r.location.search);t.set(o,e),r.replace({...r.location,search:t.toString()})}),[o,r])]}function m(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=h(e),[l,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!p({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:o}))),[c,u]=g({queryString:n,groupId:r}),[m,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,d.IN)(n);return[r,(0,a.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),k=(()=>{const e=c??m;return p({value:e,tabValues:o})?e:null})();(0,i.c)((()=>{k&&s(k)}),[k]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!p({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,o]),tabValues:o}}var f=n(93664);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=n(17624);function x(e){let{className:t,block:n,selectedValue:a,selectValue:l,tabValues:i}=e;const s=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.MV)(),d=e=>{const t=e.currentTarget,n=s.indexOf(t),r=i[n].value;r!==a&&(c(t),l(r))},u=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=s.indexOf(e.currentTarget)+1;t=s[n]??s[0];break}case"ArrowLeft":{const n=s.indexOf(e.currentTarget)-1;t=s[n]??s[s.length-1];break}}t?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.c)("tabs",{"tabs--block":n},t),children:i.map((e=>{let{value:t,label:n,attributes:o}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:a===t?0:-1,"aria-selected":a===t,ref:e=>s.push(e),onKeyDown:u,onClick:d,...o,className:(0,r.c)("tabs__item",k.tabItem,o?.className,{"tabs__item--active":a===t}),children:n??t},t)}))})}function j(e){let{lazy:t,children:n,selectedValue:r}=e;const o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:o.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r})))})}function v(e){const t=m(e);return(0,b.jsxs)("div",{className:(0,r.c)("tabs-container",k.tabList),children:[(0,b.jsx)(x,{...e,...t}),(0,b.jsx)(j,{...e,...t})]})}function y(e){const t=(0,f.c)();return(0,b.jsx)(v,{...e,children:u(e.children)},String(t))}},25236:(e,t,n)=>{n.d(t,{c:()=>a});const a=n.p+"assets/images/parachainStaking-joinDelegators-673f3b3d0c410b6f43d425caa29f2e27.png"},4552:(e,t,n)=>{n.d(t,{I:()=>i,M:()=>l});var a=n(11504);const r={},o=a.createContext(r);function l(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[3684],{42948:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>d});var a=n(17624),r=n(4552),o=(n(61268),n(87768),n(77440));const l={id:"join",title:"Become a Delegator"},i=void 0,s={id:"participate/staking/delegate/join",title:"Become a Delegator",description:"In contrast to the rather difficult path to become a collator candidate, joining the delegator pool is rather simple.",source:"@site/docs/participate/01_staking/03_delegate/02_become.md",sourceDirName:"participate/01_staking/03_delegate",slug:"/participate/staking/delegate/join",permalink:"/docs/participate/staking/delegate/join",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/participate/01_staking/03_delegate/02_become.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:2,frontMatter:{id:"join",title:"Become a Delegator"},sidebar:"staking",previous:{title:"Overview",permalink:"/docs/participate/staking/delegate/overview"},next:{title:"Adjust Your Delegation Stake",permalink:"/docs/participate/staking/delegate/adjust-stake"}},c={},d=[{value:"Happy Path",id:"happy-path",level:2},{value:"Unhappy Path",id:"unhappy-path",level:2}];function u(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",ul:"ul",...(0,r.M)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t.p,{children:["In contrast to the rather difficult ",(0,a.jsx)(t.a,{href:"/docs/participate/staking/become_a_collator/overview",children:"path to become a collator candidate"}),", joining the delegator pool is rather simple.\nAnyone can delegate to a collator candidate by staking a minimum of 20 KILT and calling ",(0,a.jsx)(t.code,{children:"parachainStaking -> joinDelegators"}),"."]}),"\n",(0,a.jsx)(o.cp,{}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{src:n(25236).c+"",width:"2004",height:"1334"})}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["Select the KILT address you want to delegate from as the extrinsic submitter (the ",(0,a.jsx)(t.em,{children:"using the selected account"})," field)"]}),"\n",(0,a.jsxs)(t.li,{children:["Select the appropriate extrinsic: ",(0,a.jsx)(t.code,{children:"parachainStaking -> joinDelegators"})]}),"\n",(0,a.jsxs)(t.li,{children:["Select the ",(0,a.jsx)(t.code,{children:"Id"})," option (the ",(0,a.jsx)(t.em,{children:"MultiAddress (LookupSource) field"}),")"]}),"\n",(0,a.jsxs)(t.li,{children:["Select the collator account (the ",(0,a.jsx)(t.em,{children:"Id: AccountId"})," field)"]}),"\n",(0,a.jsx)(t.li,{children:"Choose the desired stake amount."}),"\n",(0,a.jsxs)(t.li,{children:["Sign and submit the extrinsic (the ",(0,a.jsx)(t.em,{children:"Submit Transaction"})," button)"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsxs)(t.p,{children:["A recent change in the blockchain metadata resulted in a change in the UI regarding how balances are shown.\nIn the current version of PolkadotJS Apps, specifying 1 KILT requires adding 15 trailing ",(0,a.jsx)(t.code,{children:"0"}),"s.\nSo, for instance, 1 KILT needs to be written as ",(0,a.jsx)(t.code,{children:"1,000,000,000,000,000"}),", while 10,000 KILT would be written as ",(0,a.jsx)(t.code,{children:"10,000,000,000,000,000,000"}),"."]})}),"\n",(0,a.jsx)(t.h2,{id:"happy-path",children:"Happy Path"}),"\n",(0,a.jsx)(t.p,{children:"If your chosen collator candidate has at least one empty slot in their delegation pool (out of 35 maximum slots at the time of writing), your delegation will be successful and you immediately start receiving rewards each time the collator you delegated produces a block."}),"\n",(0,a.jsx)("div",{className:"kilt-mermaid",children:(0,a.jsx)(t.mermaid,{value:'flowchart TD\n A["Hold at least 20 KILT"] --\x3e |"decide on candidate"| B("Collator Candidate chosen");\n B --\x3e |"call extrinsic joinDelegators"| C{"Can delegate to target? \\n Either \\n 1. There are empty \\n delegations or \\n 2. You delegate more \\n than another Delegator"};\n C --\x3e |yes| D("Delegating to a Collator Candidate")\n D --\x3e |"Collator produces block"| E("Account rewards")\n E --\x3e |"claim"| F("Have rewards in wallet")\n %% Styles\n A:::unstakedFreeKilt\n B:::preDelegationCheck\n C:::preDelegationCheck\n D:::activelyDelegating\n E:::activelyDelegating\n F:::activelyDelegating\n\n %% StyleDef\n classDef preDelegationCheck fill:#FFF4BD, stroke:none, color:black;\n classDef notDelegating fill:#F1C0B9, stroke:black, color:black, stroke-width:1px;;\n classDef unstakedFreeKilt fill:#85D2D0, stroke:black, color:black, stroke-width:1px;\n classDef activelyDelegating fill:#94C973, stroke:#333, color:black, stroke-width:2px;\n classDef preUnlockStaked fill:#F37970, stroke:black, color:black;'})}),"\n",(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsx)(t.p,{children:"If your chosen collator fails to produce blocks, neither the collator itself nor their delegators receive rewards.\nThis can happen if the collator has connectivity issues or are not building blocks fast enough."})}),"\n",(0,a.jsx)(t.h2,{id:"unhappy-path",children:"Unhappy Path"}),"\n",(0,a.jsx)(t.p,{children:"If the delegation pool of your chosen collator candidate is full, you may still delegate to them if you stake more than the current lowest delegator stake of that pool.\nWhen that happens,"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"The kicked delegator will be replaced by the delegator with a higher delegation (you) immediately"}),"\n",(0,a.jsxs)(t.li,{children:["The kicked delegator's stake is prepared for unstaking as if they revoked the delegation (",(0,a.jsxs)(t.em,{children:["see ",(0,a.jsx)(t.a,{href:"#Revoking",children:"revoking"})]}),")"]}),"\n",(0,a.jsx)(t.li,{children:"A delegator needs to wait 7 days (in block time) to be able to unlock the stake.\nPlease note that it can take longer in real time as the block times assumes a constant block time of 12s, which is not guaranteed."}),"\n"]}),"\n",(0,a.jsx)("div",{className:"kilt-mermaid",children:(0,a.jsx)(t.mermaid,{value:'flowchart TD\n A["Hold at least 20 KILT"] --\x3e |"Decide on candidate"| B("Collator candidate chosen");\n B --\x3e |"Call extrinsic joinDelegators"| C{"Can delegate to target? \\n Either \\n 1. There are empty \\n delegations or \\n 2. You delegate more \\n than another delegator"};\n C --\x3e |no| C2{"Balance locked?\\n e.g., previously delegated \\n without unlocking?"}\n C2 --\x3e |no| A\n\n %% Styles\n A:::unstakedFreeKilt\n B:::preDelegationCheck\n C:::preDelegationCheck\n C2:::notDelegating\n\n %% StyleDef\n classDef preDelegationCheck fill:#FFF4BD, stroke:none, color:black;\n classDef notDelegating fill:#F1C0B9, stroke:black, color:black, stroke-width:1px;\n classDef unstakedFreeKilt fill:#85D2D0, stroke:black, color:black, stroke-width:1px;'})}),"\n",(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsxs)(t.p,{children:["For now, an account can only delegate to one collator at any time!\nMoreover, you can only (re-) delegate, e.g., call ",(0,a.jsx)(t.code,{children:"parachainStaking -> {joinDelegators, delegateAnotherCandidate}"}),", once per staking round."]})})]})}function h(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},77440:(e,t,n)=>{n.d(t,{cp:()=>l});var a=n(17624),r=n(4552);function o(e){const t={a:"a",admonition:"admonition",code:"code",p:"p",strong:"strong",...(0,r.M)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.admonition,{type:"info",children:(0,a.jsxs)(t.p,{children:["You can either execute this transaction in Polkadot JS Apps or the ",(0,a.jsx)(t.a,{href:"/docs/develop/builtonkilt#web-apps",children:(0,a.jsx)(t.strong,{children:"KILT Stakeboard"})}),", which serves as an in-house developed Frontend for all KILT staking activity.\nBelow, we outline the steps for Polkadot JS Apps.\nThe process for KILT Stakeboard is described in detail in the ",(0,a.jsx)(t.a,{href:"https://support.kilt.io/support/solutions/80000442174",children:(0,a.jsx)(t.strong,{children:"BOTLabs Trusted Entity support hub"})}),"."]})}),"\n",(0,a.jsxs)(t.p,{children:["In the Polkadot JS Apps (",(0,a.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkilt-rpc.dwellir.com#/explorer",children:"wss://spiritnet.kilt.io"}),", or ",(0,a.jsx)(t.a,{href:"https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fperegrine-stg.kilt.io#/explorer",children:"wss://peregrine.kilt.io"}),") go to ",(0,a.jsx)(t.code,{children:"Developer -> Extrinsics -> Submission"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,r.M)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(o,{...e})}):o(e)}},87768:(e,t,n)=>{n.d(t,{c:()=>l});n(11504);var a=n(65456);const r={tabItem:"tabItem_Ymn6"};var o=n(17624);function l(e){let{children:t,hidden:n,className:l}=e;return(0,o.jsx)("div",{role:"tabpanel",className:(0,a.c)(r.tabItem,l),hidden:n,children:t})}},61268:(e,t,n)=>{n.d(t,{c:()=>y});var a=n(11504),r=n(65456),o=n(53943),l=n(55592),i=n(95288),s=n(10632),c=n(27128),d=n(21148);function u(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??function(e){return u(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}(n);return function(e){const t=(0,c.w)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function p(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.Uz)(),o=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,s._M)(o),(0,a.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(r.location.search);t.set(o,e),r.replace({...r.location,search:t.toString()})}),[o,r])]}function m(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,o=h(e),[l,s]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!p({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:o}))),[c,u]=g({queryString:n,groupId:r}),[m,f]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,o]=(0,d.IN)(n);return[r,(0,a.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:r}),k=(()=>{const e=c??m;return p({value:e,tabValues:o})?e:null})();(0,i.c)((()=>{k&&s(k)}),[k]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!p({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);s(e),u(e),f(e)}),[u,f,o]),tabValues:o}}var f=n(93664);const k={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var b=n(17624);function x(e){let{className:t,block:n,selectedValue:a,selectValue:l,tabValues:i}=e;const s=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.MV)(),d=e=>{const t=e.currentTarget,n=s.indexOf(t),r=i[n].value;r!==a&&(c(t),l(r))},u=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=s.indexOf(e.currentTarget)+1;t=s[n]??s[0];break}case"ArrowLeft":{const n=s.indexOf(e.currentTarget)-1;t=s[n]??s[s.length-1];break}}t?.focus()};return(0,b.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.c)("tabs",{"tabs--block":n},t),children:i.map((e=>{let{value:t,label:n,attributes:o}=e;return(0,b.jsx)("li",{role:"tab",tabIndex:a===t?0:-1,"aria-selected":a===t,ref:e=>s.push(e),onKeyDown:u,onClick:d,...o,className:(0,r.c)("tabs__item",k.tabItem,o?.className,{"tabs__item--active":a===t}),children:n??t},t)}))})}function j(e){let{lazy:t,children:n,selectedValue:r}=e;const o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return(0,b.jsx)("div",{className:"margin-top--md",children:o.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r})))})}function v(e){const t=m(e);return(0,b.jsxs)("div",{className:(0,r.c)("tabs-container",k.tabList),children:[(0,b.jsx)(x,{...e,...t}),(0,b.jsx)(j,{...e,...t})]})}function y(e){const t=(0,f.c)();return(0,b.jsx)(v,{...e,children:u(e.children)},String(t))}},25236:(e,t,n)=>{n.d(t,{c:()=>a});const a=n.p+"assets/images/parachainStaking-joinDelegators-673f3b3d0c410b6f43d425caa29f2e27.png"},4552:(e,t,n)=>{n.d(t,{I:()=>i,M:()=>l});var a=n(11504);const r={},o=a.createContext(r);function l(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2936e90b.b536d636.js b/assets/js/2936e90b.47cc57ab.js similarity index 99% rename from assets/js/2936e90b.b536d636.js rename to assets/js/2936e90b.47cc57ab.js index bced90922..69046786c 100644 --- a/assets/js/2936e90b.b536d636.js +++ b/assets/js/2936e90b.47cc57ab.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9584],{48952:n=>{function t(n){var t=new Error("Cannot find module '"+n+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,n.exports=t},23444:(n,t,e)=>{"use strict";e.r(t),e.d(t,{assets:()=>m,contentTitle:()=>g,default:()=>x,frontMatter:()=>k,metadata:()=>p,toc:()=>b});var i=e(17624),a=e(4552),o=e(96020),c=e(61268),s=e(87768);const l="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccount: Kilt.KeyringPair & { type: 'ed25519' | 'sr25519' | 'ecdsa' },\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Generate the parameters for the extrinsic that links account and DID.\n // This will contain the signature of the account that will be linked to the DID\n // and therefore signals the agreement of the account to be linked.\n const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(\n linkedAccount.address,\n did,\n async (payload) => linkedAccount.sign(payload)\n )\n\n // Afterwards we build the extrinsic using the parameters from above.\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n\n // Next the DID signs the extrinsic.\n // This signals the agreement of the DID owner to be linked to the account.\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // finally we need to submit everything to the blockchain, so that the link gets\n // registered.\n // This account will provide the required deposit and pay the fees.\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccount: Kilt.KeyringPair & { type: 'ethereum' },\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Generate the parameters for the extrinsic that links account and DID.\n // This will contain the signature of the account that will be linked to the DID\n // and therefore signals the agreement of the account to be linked.\n const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(\n linkedAccount.address,\n did,\n async (payload) => linkedAccount.sign(payload)\n )\n\n // Afterwards we build the extrinsic using the parameters from above.\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n\n // Next the DID signs the extrinsic.\n // This signals the agreement of the DID owner to be linked to the account.\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // finally we need to submit everything to the blockchain, so that the link gets\n // registered.\n // This account will provide the required deposit and pay the fees.\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",d="import { hexToU8a, u8aToString } from '@polkadot/util'\nimport Web3 from 'web3'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccountPrivateKey: string,\n linkedAccountAddress: string,\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n const web3 = new Web3()\n\n const blockNo = await api.query.system.number()\n // the challenge will be valid for 300 blocks (~1h)\n const validTill = blockNo.addn(300)\n\n // We build the challenge that needs to be signed by the ethereum account\n const challenge = u8aToString(\n await Kilt.Did.getLinkingChallenge(did, validTill)\n )\n\n // sign the challenge\n const signResult = await web3.eth.accounts.sign(\n challenge,\n linkedAccountPrivateKey\n )\n\n // build the arguments for the extrinsic that links ethereum account and DID\n const accountLinkingParameters = await Kilt.Did.getLinkingArguments(\n linkedAccountAddress,\n validTill,\n hexToU8a(signResult.signature),\n 'ethereum'\n )\n\n // Build the actual extrinsic\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // sign and submit the extrinsic to the blockchain\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",u="import { hexToU8a, u8aToString } from '@polkadot/util'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\ntype MetamaskApi = {\n request: (_: {\n method: string\n params: [string, string, string]\n }) => Promise\n}\n\ndeclare global {\n interface Window {\n ethereum: MetamaskApi\n }\n}\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccountAddress: string,\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n const blockNo = await api.query.system.number()\n // the challenge will be valid for 300 blocks (~1h)\n const validTill = blockNo.addn(300)\n\n // We build the challenge that needs to be signed by the ethereum account\n const challenge = u8aToString(\n await Kilt.Did.getLinkingChallenge(did, validTill)\n )\n\n // sign the challenge\n const signature = await window.ethereum.request({\n method: 'personal_sign',\n params: [challenge, linkedAccountAddress, '']\n })\n\n // build the arguments for the extrinsic that links ethereum account and DID\n const accountLinkingParameters = await Kilt.Did.getLinkingArguments(\n linkedAccountAddress,\n validTill,\n hexToU8a(signature),\n 'ethereum'\n )\n\n // Build the actual extrinsic\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // sign and submit the extrinsic to the blockchain\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",h="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkDidToAccount(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Authorizing the tx with the full DID and submitting it with the provided account\n // results in the submitter's account being linked to the DID authorizing the operation.\n const accountLinkingTx = api.tx.didLookup.associateSender()\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",k={id:"account-link",title:"Link an Account to a KILT DID"},g=void 0,p={id:"develop/sdk/cookbook/account_linking/account-link",title:"Link an Account to a KILT DID",description:"Sometimes there is the need to link a DID to an account publicly.",source:"@site/docs/develop/01_sdk/02_cookbook/03_account_linking/01_link.md",sourceDirName:"develop/01_sdk/02_cookbook/03_account_linking",slug:"/develop/sdk/cookbook/account_linking/account-link",permalink:"/docs/develop/sdk/cookbook/account_linking/account-link",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/03_account_linking/01_link.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:1,frontMatter:{id:"account-link",title:"Link an Account to a KILT DID"},sidebar:"sdk",previous:{title:"Resolve a web3name",permalink:"/docs/develop/sdk/cookbook/web3names/web3name-query"},next:{title:"Query the web3name of an Account",permalink:"/docs/develop/sdk/cookbook/account_linking/account-name"}},m={},b=[{value:"Linking the sender to a DID",id:"linking-the-sender-to-a-did",level:2},{value:"Linking an account to a DID",id:"linking-an-account-to-a-did",level:2}];function f(n){const t={a:"a",admonition:"admonition",h2:"h2",p:"p",...(0,a.M)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"Sometimes there is the need to link a DID to an account publicly.\nThe link makes it possible to lookup a DID for an account.\nThe other directions is also possible.\nWith a DID you can lookup a list of linked account."}),"\n",(0,i.jsx)(t.p,{children:"Linking accounts can be useful when your account should have an identity.\nE.g. as a collator, you might want to provide some public information so that delegator can better decide who earned their stake."}),"\n",(0,i.jsx)(t.p,{children:"An account can be linked to a DID in one of two ways.\nEither the account that sends the transaction links itself to the DID, or the sender is unrelated to the DID and a third account is linked.\nIn the latter case, a challenge needs to be signed using the third account, to prove ownership."}),"\n",(0,i.jsx)(t.p,{children:"The second option is useful in cases where the account that should be linked doesn't own KILT tokens and the transaction is paid for by a third party.\nThis option also allows to link account schemes that are not native to the Spiritnet Blockchain.\nRight now the only other address scheme supported are ethereum accounts."}),"\n",(0,i.jsxs)(t.admonition,{title:"Don't use linked accounts for asset transfers",type:"warning",children:[(0,i.jsx)(t.p,{children:"Don't use these linked accounts for asset transfers.\nSince these accounts are not limited to KILT accounts, but can be used on any chain, the recipient might not be able to access the transferred asset on other chains.\nWhen a link to an account on a different Polkadot chain is created, this account might only be usable on this specific chain."}),(0,i.jsxs)(t.p,{children:["If you want transfer assets to a DID have a look at ",(0,i.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-KiltTransferAssetRecipientV1",children:"the asset transfer service"}),"."]})]}),"\n",(0,i.jsx)(t.h2,{id:"linking-the-sender-to-a-did",children:"Linking the sender to a DID"}),"\n",(0,i.jsx)(t.p,{children:"Link the sender of the transaction to the DID.\nThe sender will provide the deposit and pay the fees.\nThey will also be linked to the DID."}),"\n",(0,i.jsx)(o.c,{children:h}),"\n",(0,i.jsx)(t.h2,{id:"linking-an-account-to-a-did",children:"Linking an account to a DID"}),"\n",(0,i.jsx)(t.p,{children:"Link another account to the DID.\nThe sender will provide the deposit and pay the fees, but will not be linked to the DID in any way.\nThe account that should be linked must sign a challenge to prove that the account agrees to be linked."}),"\n",(0,i.jsx)(t.p,{children:"The proof contains the DID that the account will be linked to and an expiration date (in terms of blocks), to prevent replay attacks.\nThe proof will only be valid up until the blocknumber is reached."}),"\n",(0,i.jsx)(t.p,{children:"With this option you can link addresses that are supported by the Spiritnet blockchain (Sr25519, Ed25519, Ecdsa), but also ethereum addresses."}),"\n",(0,i.jsxs)(c.c,{defaultValue:"substrate-link",children:[(0,i.jsx)(s.c,{value:"substrate-link",label:"Substrate",children:(0,i.jsx)(o.c,{children:l})}),(0,i.jsx)(s.c,{value:"eth-link",label:"Ethereum (polkadot-js)",children:(0,i.jsx)(o.c,{children:r})}),(0,i.jsx)(s.c,{value:"eth-link-web3js",label:"Ethereum (web3.js)",children:(0,i.jsx)(o.c,{children:d})}),(0,i.jsxs)(s.c,{value:"eth-link-metamask",label:"Ethereum (MetaMask)",children:[(0,i.jsxs)(t.p,{children:["Refer to the ",(0,i.jsx)("a",{href:"https://docs.metamask.io/guide/signing-data.html#personal-sign",children:"Metamask documentation"})," for further information."]}),(0,i.jsx)(o.c,{children:u})]})]})]})}function x(n={}){const{wrapper:t}={...(0,a.M)(),...n.components};return t?(0,i.jsx)(t,{...n,children:(0,i.jsx)(f,{...n})}):f(n)}},96020:(n,t,e)=>{"use strict";e.d(t,{c:()=>k});var i=e(11504),a=e(28264),o=e(46352),c=e(58440),s=e(14300),l=e(28168),r=e(61268),d=e(87768),u=e(1608),h=e(17624);const k=n=>{let{children:t,fileName:e,...k}=n;const g=t,[p,m]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:b}}}=(0,a.c)(),f=(0,i.useMemo)((()=>{const{code:n}=(0,o.transform)(g,{plugins:["transform-typescript"],retainLines:!0});return n}),[g]);(0,i.useEffect)((()=>{c.E9(f,{parser:"babel",plugins:[s.c,l.cp],...b}).then(m)}),[b,f]);const x=[{fileName:e?`${e}.ts`:void 0,fileContents:g,fileID:"ts",fileLabel:"Typescript"},{fileName:e?`${e}.js`:void 0,fileContents:p,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(r.c,{groupId:"ts-js-choice",children:x.map((n=>(0,h.jsx)(d.c,{value:n.fileID,label:n.fileLabel,default:!0,children:(0,h.jsx)(u.c,{...k,className:"language-"+n.fileID,title:n.fileName,children:n.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9584],{48952:n=>{function t(n){var t=new Error("Cannot find module '"+n+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,n.exports=t},23444:(n,t,e)=>{"use strict";e.r(t),e.d(t,{assets:()=>m,contentTitle:()=>g,default:()=>x,frontMatter:()=>k,metadata:()=>p,toc:()=>b});var i=e(17624),a=e(4552),o=e(96020),c=e(61268),s=e(87768);const l="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccount: Kilt.KeyringPair & { type: 'ed25519' | 'sr25519' | 'ecdsa' },\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Generate the parameters for the extrinsic that links account and DID.\n // This will contain the signature of the account that will be linked to the DID\n // and therefore signals the agreement of the account to be linked.\n const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(\n linkedAccount.address,\n did,\n async (payload) => linkedAccount.sign(payload)\n )\n\n // Afterwards we build the extrinsic using the parameters from above.\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n\n // Next the DID signs the extrinsic.\n // This signals the agreement of the DID owner to be linked to the account.\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // finally we need to submit everything to the blockchain, so that the link gets\n // registered.\n // This account will provide the required deposit and pay the fees.\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",r="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccount: Kilt.KeyringPair & { type: 'ethereum' },\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Generate the parameters for the extrinsic that links account and DID.\n // This will contain the signature of the account that will be linked to the DID\n // and therefore signals the agreement of the account to be linked.\n const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(\n linkedAccount.address,\n did,\n async (payload) => linkedAccount.sign(payload)\n )\n\n // Afterwards we build the extrinsic using the parameters from above.\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n\n // Next the DID signs the extrinsic.\n // This signals the agreement of the DID owner to be linked to the account.\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // finally we need to submit everything to the blockchain, so that the link gets\n // registered.\n // This account will provide the required deposit and pay the fees.\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",d="import { hexToU8a, u8aToString } from '@polkadot/util'\nimport Web3 from 'web3'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccountPrivateKey: string,\n linkedAccountAddress: string,\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n const web3 = new Web3()\n\n const blockNo = await api.query.system.number()\n // the challenge will be valid for 300 blocks (~1h)\n const validTill = blockNo.addn(300)\n\n // We build the challenge that needs to be signed by the ethereum account\n const challenge = u8aToString(\n await Kilt.Did.getLinkingChallenge(did, validTill)\n )\n\n // sign the challenge\n const signResult = await web3.eth.accounts.sign(\n challenge,\n linkedAccountPrivateKey\n )\n\n // build the arguments for the extrinsic that links ethereum account and DID\n const accountLinkingParameters = await Kilt.Did.getLinkingArguments(\n linkedAccountAddress,\n validTill,\n hexToU8a(signResult.signature),\n 'ethereum'\n )\n\n // Build the actual extrinsic\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // sign and submit the extrinsic to the blockchain\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",u="import { hexToU8a, u8aToString } from '@polkadot/util'\n\nimport * as Kilt from '@kiltprotocol/sdk-js'\n\ntype MetamaskApi = {\n request: (_: {\n method: string\n params: [string, string, string]\n }) => Promise\n}\n\ndeclare global {\n interface Window {\n ethereum: MetamaskApi\n }\n}\n\nexport async function linkAccountToDid(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n linkedAccountAddress: string,\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n const blockNo = await api.query.system.number()\n // the challenge will be valid for 300 blocks (~1h)\n const validTill = blockNo.addn(300)\n\n // We build the challenge that needs to be signed by the ethereum account\n const challenge = u8aToString(\n await Kilt.Did.getLinkingChallenge(did, validTill)\n )\n\n // sign the challenge\n const signature = await window.ethereum.request({\n method: 'personal_sign',\n params: [challenge, linkedAccountAddress, '']\n })\n\n // build the arguments for the extrinsic that links ethereum account and DID\n const accountLinkingParameters = await Kilt.Did.getLinkingArguments(\n linkedAccountAddress,\n validTill,\n hexToU8a(signature),\n 'ethereum'\n )\n\n // Build the actual extrinsic\n const accountLinkingTx = await api.tx.didLookup.associateAccount(\n ...accountLinkingParameters\n )\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n // sign and submit the extrinsic to the blockchain\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",h="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function linkDidToAccount(\n did: Kilt.DidUri,\n submitterAccount: Kilt.KiltKeyringPair,\n signCallback: Kilt.SignExtrinsicCallback\n): Promise {\n const api = Kilt.ConfigService.get('api')\n\n // Authorizing the tx with the full DID and submitting it with the provided account\n // results in the submitter's account being linked to the DID authorizing the operation.\n const accountLinkingTx = api.tx.didLookup.associateSender()\n const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(\n did,\n accountLinkingTx,\n signCallback,\n submitterAccount.address\n )\n\n await Kilt.Blockchain.signAndSubmitTx(\n authorizedAccountLinkingTx,\n submitterAccount\n )\n}\n",k={id:"account-link",title:"Link an Account to a KILT DID"},g=void 0,p={id:"develop/sdk/cookbook/account_linking/account-link",title:"Link an Account to a KILT DID",description:"Sometimes there is the need to link a DID to an account publicly.",source:"@site/docs/develop/01_sdk/02_cookbook/03_account_linking/01_link.md",sourceDirName:"develop/01_sdk/02_cookbook/03_account_linking",slug:"/develop/sdk/cookbook/account_linking/account-link",permalink:"/docs/develop/sdk/cookbook/account_linking/account-link",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/03_account_linking/01_link.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:1,frontMatter:{id:"account-link",title:"Link an Account to a KILT DID"},sidebar:"sdk",previous:{title:"Resolve a web3name",permalink:"/docs/develop/sdk/cookbook/web3names/web3name-query"},next:{title:"Query the web3name of an Account",permalink:"/docs/develop/sdk/cookbook/account_linking/account-name"}},m={},b=[{value:"Linking the sender to a DID",id:"linking-the-sender-to-a-did",level:2},{value:"Linking an account to a DID",id:"linking-an-account-to-a-did",level:2}];function f(n){const t={a:"a",admonition:"admonition",h2:"h2",p:"p",...(0,a.M)(),...n.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"Sometimes there is the need to link a DID to an account publicly.\nThe link makes it possible to lookup a DID for an account.\nThe other directions is also possible.\nWith a DID you can lookup a list of linked account."}),"\n",(0,i.jsx)(t.p,{children:"Linking accounts can be useful when your account should have an identity.\nE.g. as a collator, you might want to provide some public information so that delegator can better decide who earned their stake."}),"\n",(0,i.jsx)(t.p,{children:"An account can be linked to a DID in one of two ways.\nEither the account that sends the transaction links itself to the DID, or the sender is unrelated to the DID and a third account is linked.\nIn the latter case, a challenge needs to be signed using the third account, to prove ownership."}),"\n",(0,i.jsx)(t.p,{children:"The second option is useful in cases where the account that should be linked doesn't own KILT tokens and the transaction is paid for by a third party.\nThis option also allows to link account schemes that are not native to the Spiritnet Blockchain.\nRight now the only other address scheme supported are ethereum accounts."}),"\n",(0,i.jsxs)(t.admonition,{title:"Don't use linked accounts for asset transfers",type:"warning",children:[(0,i.jsx)(t.p,{children:"Don't use these linked accounts for asset transfers.\nSince these accounts are not limited to KILT accounts, but can be used on any chain, the recipient might not be able to access the transferred asset on other chains.\nWhen a link to an account on a different Polkadot chain is created, this account might only be usable on this specific chain."}),(0,i.jsxs)(t.p,{children:["If you want transfer assets to a DID have a look at ",(0,i.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-KiltTransferAssetRecipientV1",children:"the asset transfer service"}),"."]})]}),"\n",(0,i.jsx)(t.h2,{id:"linking-the-sender-to-a-did",children:"Linking the sender to a DID"}),"\n",(0,i.jsx)(t.p,{children:"Link the sender of the transaction to the DID.\nThe sender will provide the deposit and pay the fees.\nThey will also be linked to the DID."}),"\n",(0,i.jsx)(o.c,{children:h}),"\n",(0,i.jsx)(t.h2,{id:"linking-an-account-to-a-did",children:"Linking an account to a DID"}),"\n",(0,i.jsx)(t.p,{children:"Link another account to the DID.\nThe sender will provide the deposit and pay the fees, but will not be linked to the DID in any way.\nThe account that should be linked must sign a challenge to prove that the account agrees to be linked."}),"\n",(0,i.jsx)(t.p,{children:"The proof contains the DID that the account will be linked to and an expiration date (in terms of blocks), to prevent replay attacks.\nThe proof will only be valid up until the blocknumber is reached."}),"\n",(0,i.jsx)(t.p,{children:"With this option you can link addresses that are supported by the Spiritnet blockchain (Sr25519, Ed25519, Ecdsa), but also ethereum addresses."}),"\n",(0,i.jsxs)(c.c,{defaultValue:"substrate-link",children:[(0,i.jsx)(s.c,{value:"substrate-link",label:"Substrate",children:(0,i.jsx)(o.c,{children:l})}),(0,i.jsx)(s.c,{value:"eth-link",label:"Ethereum (polkadot-js)",children:(0,i.jsx)(o.c,{children:r})}),(0,i.jsx)(s.c,{value:"eth-link-web3js",label:"Ethereum (web3.js)",children:(0,i.jsx)(o.c,{children:d})}),(0,i.jsxs)(s.c,{value:"eth-link-metamask",label:"Ethereum (MetaMask)",children:[(0,i.jsxs)(t.p,{children:["Refer to the ",(0,i.jsx)("a",{href:"https://docs.metamask.io/guide/signing-data.html#personal-sign",children:"Metamask documentation"})," for further information."]}),(0,i.jsx)(o.c,{children:u})]})]})]})}function x(n={}){const{wrapper:t}={...(0,a.M)(),...n.components};return t?(0,i.jsx)(t,{...n,children:(0,i.jsx)(f,{...n})}):f(n)}},96020:(n,t,e)=>{"use strict";e.d(t,{c:()=>k});var i=e(11504),a=e(28264),o=e(46352),c=e(58440),s=e(14300),l=e(28168),r=e(61268),d=e(87768),u=e(1608),h=e(17624);const k=n=>{let{children:t,fileName:e,...k}=n;const g=t,[p,m]=(0,i.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:b}}}=(0,a.c)(),f=(0,i.useMemo)((()=>{const{code:n}=(0,o.transform)(g,{plugins:["transform-typescript"],retainLines:!0});return n}),[g]);(0,i.useEffect)((()=>{c.E9(f,{parser:"babel",plugins:[s.c,l.cp],...b}).then(m)}),[b,f]);const x=[{fileName:e?`${e}.ts`:void 0,fileContents:g,fileID:"ts",fileLabel:"Typescript"},{fileName:e?`${e}.js`:void 0,fileContents:p,fileID:"js",fileLabel:"Javascript"}];return(0,h.jsx)(h.Fragment,{children:(0,h.jsx)(r.c,{groupId:"ts-js-choice",children:x.map((n=>(0,h.jsx)(d.c,{value:n.fileID,label:n.fileLabel,default:!0,children:(0,h.jsx)(u.c,{...k,className:"language-"+n.fileID,title:n.fileName,children:n.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/29f1f863.ea795549.js b/assets/js/29f1f863.cceab445.js similarity index 96% rename from assets/js/29f1f863.ea795549.js rename to assets/js/29f1f863.cceab445.js index 69f40dc4f..85a9169ba 100644 --- a/assets/js/29f1f863.ea795549.js +++ b/assets/js/29f1f863.cceab445.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9508],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},66120:(e,t,o)=>{"use strict";o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>f,frontMatter:()=>l,metadata:()=>a,toc:()=>u});var s=o(17624),i=o(4552),d=o(96020);const n="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function queryFullDid(\n didUri: Kilt.DidUri\n): Promise {\n const { metadata, document } = await Kilt.Did.resolve(didUri)\n if (metadata.deactivated) {\n console.log(`DID ${didUri} has been deleted.`)\n return null\n } else if (document === undefined) {\n console.log(`DID ${didUri} does not exist.`)\n return null\n } else {\n return document\n }\n}\n",l={id:"did-query",title:"Resolve a DID"},r=void 0,a={id:"develop/sdk/cookbook/dids/did-query",title:"Resolve a DID",description:"Querying the state of a DID is called resolution.",source:"@site/docs/develop/01_sdk/02_cookbook/01_dids/04_did_query.md",sourceDirName:"develop/01_sdk/02_cookbook/01_dids",slug:"/develop/sdk/cookbook/dids/did-query",permalink:"/docs/develop/sdk/cookbook/dids/did-query",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/01_dids/04_did_query.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:4,frontMatter:{id:"did-query",title:"Resolve a DID"},sidebar:"sdk",previous:{title:"Update a Full DID keys and service endpoints",permalink:"/docs/develop/sdk/cookbook/dids/full-did-update"},next:{title:"Delete a Full DID",permalink:"/docs/develop/sdk/cookbook/dids/full-did-delete"}},c={},u=[];function p(e){const t={a:"a",admonition:"admonition",p:"p",strong:"strong",...(0,i.M)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["Querying the state of a DID is called ",(0,s.jsx)(t.strong,{children:"resolution"}),".\nThe entity that queries the DID Document for a given DID, i.e., resolves it, is called a ",(0,s.jsx)(t.strong,{children:"resolver"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The KILT SDK provides such a resolver to use with KILT DIDs, as the snippet below shows:"}),"\n",(0,s.jsx)(d.c,{children:n}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["The DID resolver can resolve both light and full DIDs.\nFor a more in-depth explanation about the KILT DID method and resolution, refer to our ",(0,s.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-kilt-did",children:"specification"}),"."]})})]})}function f(e={}){const{wrapper:t}={...(0,i.M)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},96020:(e,t,o)=>{"use strict";o.d(t,{c:()=>f});var s=o(11504),i=o(28264),d=o(46352),n=o(58440),l=o(14300),r=o(28168),a=o(61268),c=o(87768),u=o(1608),p=o(17624);const f=e=>{let{children:t,fileName:o,...f}=e;const D=t,[h,m]=(0,s.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:k}}}=(0,i.c)(),v=(0,s.useMemo)((()=>{const{code:e}=(0,d.transform)(D,{plugins:["transform-typescript"],retainLines:!0});return e}),[D]);(0,s.useEffect)((()=>{n.E9(v,{parser:"babel",plugins:[l.c,r.cp],...k}).then(m)}),[k,v]);const I=[{fileName:o?`${o}.ts`:void 0,fileContents:D,fileID:"ts",fileLabel:"Typescript"},{fileName:o?`${o}.js`:void 0,fileContents:h,fileID:"js",fileLabel:"Javascript"}];return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)(a.c,{groupId:"ts-js-choice",children:I.map((e=>(0,p.jsx)(c.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,p.jsx)(u.c,{...f,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file +(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9508],{48952:e=>{function t(e){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}t.keys=()=>[],t.resolve=t,t.id=48952,e.exports=t},66120:(e,t,o)=>{"use strict";o.r(t),o.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>f,frontMatter:()=>l,metadata:()=>a,toc:()=>u});var s=o(17624),i=o(4552),d=o(96020);const n="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function queryFullDid(\n didUri: Kilt.DidUri\n): Promise {\n const { metadata, document } = await Kilt.Did.resolve(didUri)\n if (metadata.deactivated) {\n console.log(`DID ${didUri} has been deleted.`)\n return null\n } else if (document === undefined) {\n console.log(`DID ${didUri} does not exist.`)\n return null\n } else {\n return document\n }\n}\n",l={id:"did-query",title:"Resolve a DID"},r=void 0,a={id:"develop/sdk/cookbook/dids/did-query",title:"Resolve a DID",description:"Querying the state of a DID is called resolution.",source:"@site/docs/develop/01_sdk/02_cookbook/01_dids/04_did_query.md",sourceDirName:"develop/01_sdk/02_cookbook/01_dids",slug:"/develop/sdk/cookbook/dids/did-query",permalink:"/docs/develop/sdk/cookbook/dids/did-query",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/01_sdk/02_cookbook/01_dids/04_did_query.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:4,frontMatter:{id:"did-query",title:"Resolve a DID"},sidebar:"sdk",previous:{title:"Update a Full DID keys and service endpoints",permalink:"/docs/develop/sdk/cookbook/dids/full-did-update"},next:{title:"Delete a Full DID",permalink:"/docs/develop/sdk/cookbook/dids/full-did-delete"}},c={},u=[];function p(e){const t={a:"a",admonition:"admonition",p:"p",strong:"strong",...(0,i.M)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["Querying the state of a DID is called ",(0,s.jsx)(t.strong,{children:"resolution"}),".\nThe entity that queries the DID Document for a given DID, i.e., resolves it, is called a ",(0,s.jsx)(t.strong,{children:"resolver"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The KILT SDK provides such a resolver to use with KILT DIDs, as the snippet below shows:"}),"\n",(0,s.jsx)(d.c,{children:n}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["The DID resolver can resolve both light and full DIDs.\nFor a more in-depth explanation about the KILT DID method and resolution, refer to our ",(0,s.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-kilt-did",children:"specification"}),"."]})})]})}function f(e={}){const{wrapper:t}={...(0,i.M)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},96020:(e,t,o)=>{"use strict";o.d(t,{c:()=>f});var s=o(11504),i=o(28264),d=o(46352),n=o(58440),l=o(14300),r=o(28168),a=o(61268),c=o(87768),u=o(1608),p=o(17624);const f=e=>{let{children:t,fileName:o,...f}=e;const D=t,[h,m]=(0,s.useState)("# loading code..."),{siteConfig:{customFields:{prettierConfig:k}}}=(0,i.c)(),v=(0,s.useMemo)((()=>{const{code:e}=(0,d.transform)(D,{plugins:["transform-typescript"],retainLines:!0});return e}),[D]);(0,s.useEffect)((()=>{n.E9(v,{parser:"babel",plugins:[l.c,r.cp],...k}).then(m)}),[k,v]);const I=[{fileName:o?`${o}.ts`:void 0,fileContents:D,fileID:"ts",fileLabel:"Typescript"},{fileName:o?`${o}.js`:void 0,fileContents:h,fileID:"js",fileLabel:"Javascript"}];return(0,p.jsx)(p.Fragment,{children:(0,p.jsx)(a.c,{groupId:"ts-js-choice",children:I.map((e=>(0,p.jsx)(c.c,{value:e.fileID,label:e.fileLabel,default:!0,children:(0,p.jsx)(u.c,{...f,className:"language-"+e.fileID,title:e.fileName,children:e.fileContents})})))})})}}}]); \ No newline at end of file diff --git a/assets/js/2d03795b.3d98a6c6.js b/assets/js/2d03795b.ac9be6b5.js similarity index 98% rename from assets/js/2d03795b.3d98a6c6.js rename to assets/js/2d03795b.ac9be6b5.js index 1e5113f32..912ed574c 100644 --- a/assets/js/2d03795b.3d98a6c6.js +++ b/assets/js/2d03795b.ac9be6b5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[888],{1664:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var i=n(17624),s=n(4552);const o={id:"what-is-kilt",title:"What is KILT?"},r=void 0,a={id:"concepts/what-is-kilt",title:"What is KILT?",description:"KILT is a protocol for self-sovereign data and interoperability built on top of the permissionless KILT blockchain.",source:"@site/docs/concepts/01_what_is_kilt.md",sourceDirName:"concepts",slug:"/concepts/what-is-kilt",permalink:"/docs/concepts/what-is-kilt",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/01_what_is_kilt.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:1,frontMatter:{id:"what-is-kilt",title:"What is KILT?"},sidebar:"concepts",next:{title:"KILT Decentralized Identifiers (DIDs)",permalink:"/docs/concepts/did"}},l={},d=[{value:"What KILT provides",id:"what-kilt-provides",level:2},{value:"The problem",id:"the-problem",level:2},{value:"The solution",id:"the-solution",level:2}];function c(e){const t={a:"a",h2:"h2",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"KILT is a protocol for self-sovereign data and interoperability built on top of the permissionless KILT blockchain."}),"\n",(0,i.jsx)(t.p,{children:"The core component of KILT is a digital identity protocol for:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Generating and managing ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#Decentralized-Identifiers-(DID)",children:(0,i.jsx)(t.strong,{children:"decentralized identifiers (DIDs)"})})]}),"\n",(0,i.jsxs)(t.li,{children:["Issuing and presenting digital ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#verifiable-credentials",children:(0,i.jsx)(t.strong,{children:"verifiable credentials (VCs)"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["In contrast to other centralized alternatives, KILT features self-sovereign data and revocable ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#credential",children:"credentials"})," anchored to the KILT blockchain."]}),"\n",(0,i.jsx)(t.p,{children:"KILT was built to be a business enabler, not only for the software industry but also for any entity.\nSuch entities can establish a business model based on the trust infrastructure KILT provides, which is an essential building block of Web 3.0."}),"\n",(0,i.jsx)(t.h2,{id:"what-kilt-provides",children:"What KILT provides"}),"\n",(0,i.jsx)(t.p,{children:"In particular, KILT provides:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.strong,{children:"universal identity protocol"})," for individuals, organizations, objects, and intelligent agents to obtain credentials for arbitrary attributes about themselves issued by trusted ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#attester",children:"Attesters"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.strong,{children:"self-sovereign mechanism"})," for putting credential holders in control of their own data, allowing them to choose if and where they make their credentials public and how much information from those credentials they wish to share."]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsxs)(t.strong,{children:[(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#trust-market",children:"Trust Market"})," for ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#attester",children:"Attesters"})]})," of such credentials, allowing widely trusted entities to be compensated for their valuable attestation work."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"KILT's main goal is to generate a level playing field for companies to explore new business models related to trust relationships and data sovereignty.\nKILT enables businesses and governments to rely on a common standard owned by everyone participating and not by a single company or set thereof."}),"\n",(0,i.jsx)(t.h2,{id:"the-problem",children:"The problem"}),"\n",(0,i.jsx)(t.p,{children:"In the beginning, identity and trust between entities were organized in a fully decentralized way.\nIndividuals created trust relationships directly between them based on their observations.\nOf course, this had major drawbacks:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"The size of the personal social network is limited"}),"\n",(0,i.jsx)(t.li,{children:"It's not trivial to judge the trustworthiness of an individual"}),"\n",(0,i.jsx)(t.li,{children:"It's hard to prove one's own identity to outsiders"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"When people started to organize themselves in bigger groups, founding villages and cities, those drawbacks were amplified and people needed to address them.\nPeople introduced mechanisms to create trust relationships between groups by issuing some form of attestation.\nIn this way, people who don't know the individual directly but who trusted the group that gave the attestation. For example, a carpenter's guild, a monastery or a Scottish clan could verify certain properties about another individual.\nWhen the organizational structures grew further and large bureaucratic nations emerged, the authorities issuing those attestations and the scope of the trust relationships also grew."}),"\n",(0,i.jsx)(t.p,{children:"While there is now a more centralized way of organizing trust, the actual information that makes up an identity is still handed out directly to the individual, who is still responsible for their data.\nTake official personal documents like passports as an example.\nTrusted entities issue them and hand them out to the holder.\nThat holder then has full control of their credential (their passport) and can use it wherever needed."}),"\n",(0,i.jsx)(t.p,{children:"With the invention of the internet, and later of Web 2.0, services evolved and merged into totally centralized solutions including Google, Meta, and X among others.\nThey no longer attest to someone's email account, but due to their business model, those same service providers store and control our personal data (i.e., our identity).\nFor instance, they could stop allowing us to log into a certain website if they decide to.\nMore often than not, companies store the data out of necessity and for their own business purpose.\nEvery time users log into any service, they generate new data points which are then aggregated and sold for advertising purposes."}),"\n",(0,i.jsx)(t.p,{children:"KILT Protocol aims to change that and give users back control over their data."}),"\n",(0,i.jsx)(t.h2,{id:"the-solution",children:"The solution"}),"\n",(0,i.jsxs)(t.p,{children:["KILT provides a protocol and the tools for people to manage their own data, and to build a ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#digital-identity",children:"digital identity"})," by collecting credentials issued by trusted entities.\nSuch credentials aren't publicly available but stay within the user's control.\nThis is similar to the approach used for centuries before big corporations monetized our data."]}),"\n",(0,i.jsx)(t.p,{children:"The core ideas are:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Managing user identities in the form of ",(0,i.jsx)(t.a,{href:"https://w3c-ccg.github.io/did-spec/",children:"decentralized identifiers (DIDs)"}),", with the support of the KILT blockchain"]}),"\n",(0,i.jsxs)(t.li,{children:["Obtaining digital ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#verifiable-credentials",children:"verifiable credentials"})," for user-specified claims"]}),"\n",(0,i.jsx)(t.li,{children:"Supporting revocation of verifiable credentials by their Attesters"}),"\n",(0,i.jsx)(t.li,{children:"Presenting and verifying verifiable credentials in a privacy-preserving and user-controlled way"}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>a,M:()=>r});var i=n(11504);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[888],{1664:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var i=n(17624),s=n(4552);const o={id:"what-is-kilt",title:"What is KILT?"},r=void 0,a={id:"concepts/what-is-kilt",title:"What is KILT?",description:"KILT is a protocol for self-sovereign data and interoperability built on top of the permissionless KILT blockchain.",source:"@site/docs/concepts/01_what_is_kilt.md",sourceDirName:"concepts",slug:"/concepts/what-is-kilt",permalink:"/docs/concepts/what-is-kilt",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/01_what_is_kilt.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:1,frontMatter:{id:"what-is-kilt",title:"What is KILT?"},sidebar:"concepts",next:{title:"KILT Decentralized Identifiers (DIDs)",permalink:"/docs/concepts/did"}},l={},d=[{value:"What KILT provides",id:"what-kilt-provides",level:2},{value:"The problem",id:"the-problem",level:2},{value:"The solution",id:"the-solution",level:2}];function c(e){const t={a:"a",h2:"h2",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.p,{children:"KILT is a protocol for self-sovereign data and interoperability built on top of the permissionless KILT blockchain."}),"\n",(0,i.jsx)(t.p,{children:"The core component of KILT is a digital identity protocol for:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Generating and managing ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#Decentralized-Identifiers-(DID)",children:(0,i.jsx)(t.strong,{children:"decentralized identifiers (DIDs)"})})]}),"\n",(0,i.jsxs)(t.li,{children:["Issuing and presenting digital ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#verifiable-credentials",children:(0,i.jsx)(t.strong,{children:"verifiable credentials (VCs)"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["In contrast to other centralized alternatives, KILT features self-sovereign data and revocable ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#credential",children:"credentials"})," anchored to the KILT blockchain."]}),"\n",(0,i.jsx)(t.p,{children:"KILT was built to be a business enabler, not only for the software industry but also for any entity.\nSuch entities can establish a business model based on the trust infrastructure KILT provides, which is an essential building block of Web 3.0."}),"\n",(0,i.jsx)(t.h2,{id:"what-kilt-provides",children:"What KILT provides"}),"\n",(0,i.jsx)(t.p,{children:"In particular, KILT provides:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.strong,{children:"universal identity protocol"})," for individuals, organizations, objects, and intelligent agents to obtain credentials for arbitrary attributes about themselves issued by trusted ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#attester",children:"Attesters"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsx)(t.strong,{children:"self-sovereign mechanism"})," for putting credential holders in control of their own data, allowing them to choose if and where they make their credentials public and how much information from those credentials they wish to share."]}),"\n",(0,i.jsxs)(t.li,{children:["A ",(0,i.jsxs)(t.strong,{children:[(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#trust-market",children:"Trust Market"})," for ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#attester",children:"Attesters"})]})," of such credentials, allowing widely trusted entities to be compensated for their valuable attestation work."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"KILT's main goal is to generate a level playing field for companies to explore new business models related to trust relationships and data sovereignty.\nKILT enables businesses and governments to rely on a common standard owned by everyone participating and not by a single company or set thereof."}),"\n",(0,i.jsx)(t.h2,{id:"the-problem",children:"The problem"}),"\n",(0,i.jsx)(t.p,{children:"In the beginning, identity and trust between entities were organized in a fully decentralized way.\nIndividuals created trust relationships directly between them based on their observations.\nOf course, this had major drawbacks:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"The size of the personal social network is limited"}),"\n",(0,i.jsx)(t.li,{children:"It's not trivial to judge the trustworthiness of an individual"}),"\n",(0,i.jsx)(t.li,{children:"It's hard to prove one's own identity to outsiders"}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"When people started to organize themselves in bigger groups, founding villages and cities, those drawbacks were amplified and people needed to address them.\nPeople introduced mechanisms to create trust relationships between groups by issuing some form of attestation.\nIn this way, people who don't know the individual directly but who trusted the group that gave the attestation. For example, a carpenter's guild, a monastery or a Scottish clan could verify certain properties about another individual.\nWhen the organizational structures grew further and large bureaucratic nations emerged, the authorities issuing those attestations and the scope of the trust relationships also grew."}),"\n",(0,i.jsx)(t.p,{children:"While there is now a more centralized way of organizing trust, the actual information that makes up an identity is still handed out directly to the individual, who is still responsible for their data.\nTake official personal documents like passports as an example.\nTrusted entities issue them and hand them out to the holder.\nThat holder then has full control of their credential (their passport) and can use it wherever needed."}),"\n",(0,i.jsx)(t.p,{children:"With the invention of the internet, and later of Web 2.0, services evolved and merged into totally centralized solutions including Google, Meta, and X among others.\nThey no longer attest to someone's email account, but due to their business model, those same service providers store and control our personal data (i.e., our identity).\nFor instance, they could stop allowing us to log into a certain website if they decide to.\nMore often than not, companies store the data out of necessity and for their own business purpose.\nEvery time users log into any service, they generate new data points which are then aggregated and sold for advertising purposes."}),"\n",(0,i.jsx)(t.p,{children:"KILT Protocol aims to change that and give users back control over their data."}),"\n",(0,i.jsx)(t.h2,{id:"the-solution",children:"The solution"}),"\n",(0,i.jsxs)(t.p,{children:["KILT provides a protocol and the tools for people to manage their own data, and to build a ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#digital-identity",children:"digital identity"})," by collecting credentials issued by trusted entities.\nSuch credentials aren't publicly available but stay within the user's control.\nThis is similar to the approach used for centuries before big corporations monetized our data."]}),"\n",(0,i.jsx)(t.p,{children:"The core ideas are:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["Managing user identities in the form of ",(0,i.jsx)(t.a,{href:"https://w3c-ccg.github.io/did-spec/",children:"decentralized identifiers (DIDs)"}),", with the support of the KILT blockchain"]}),"\n",(0,i.jsxs)(t.li,{children:["Obtaining digital ",(0,i.jsx)(t.a,{href:"/docs/concepts/glossary#verifiable-credentials",children:"verifiable credentials"})," for user-specified claims"]}),"\n",(0,i.jsx)(t.li,{children:"Supporting revocation of verifiable credentials by their Attesters"}),"\n",(0,i.jsx)(t.li,{children:"Presenting and verifying verifiable credentials in a privacy-preserving and user-controlled way"}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.M)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},4552:(e,t,n)=>{n.d(t,{I:()=>a,M:()=>r});var i=n(11504);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2d31ba6c.8f4d004d.js b/assets/js/2d31ba6c.2e1a3cb7.js similarity index 95% rename from assets/js/2d31ba6c.8f4d004d.js rename to assets/js/2d31ba6c.2e1a3cb7.js index 5b8b345bb..43decb96c 100644 --- a/assets/js/2d31ba6c.8f4d004d.js +++ b/assets/js/2d31ba6c.2e1a3cb7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9256],{8964:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=s(17624),c=s(4552);const o={id:"nested-ctypes",title:"Nested CTypes"},r=void 0,a={id:"concepts/advanced_concepts/nested-ctypes",title:"Nested CTypes",description:"A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them.",source:"@site/docs/concepts/09_advanced_concepts/02_nested_ctypes.md",sourceDirName:"concepts/09_advanced_concepts",slug:"/concepts/advanced_concepts/nested-ctypes",permalink:"/docs/concepts/advanced_concepts/nested-ctypes",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/09_advanced_concepts/02_nested_ctypes.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:2,frontMatter:{id:"nested-ctypes",title:"Nested CTypes"},sidebar:"concepts",previous:{title:"Terms and Quotes",permalink:"/docs/concepts/advanced_concepts/terms-and-quotes"},next:{title:"KILT Glossary",permalink:"/docs/concepts/glossary"}},i={},d=[{value:"Referencing",id:"referencing",level:2}];function p(e){const t={code:"code",h2:"h2",p:"p",...(0,c.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them.\nFor example, a company could use a Nested CType that includes the required credentials, qualifications, health and safety certificates, etc. of its current employees.\nWhen verifying a Nested CType, the sub-CTypes need to be available."}),"\n",(0,n.jsx)(t.h2,{id:"referencing",children:"Referencing"}),"\n",(0,n.jsxs)(t.p,{children:["JSON-schema provides a referencing keyword ",(0,n.jsx)(t.code,{children:"$ref"})," that can be used as a pointer from other JSON schemas.\nThis allows CTypes to either reference fields in other CTypes or nest entire CTypes within one another, providing flexibility for several different use cases.\nA claim from a Nested CType requires the given CType, a list of comprised schemas, the claim content and the address of the owner."]}),"\n",(0,n.jsx)(t.p,{children:"This facility requires all JSON objects to build the schema and allows the reuse of previous schemas, reducing the need for copy-and-paste."})]})}function l(e={}){const{wrapper:t}={...(0,c.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},4552:(e,t,s)=>{s.d(t,{I:()=>a,M:()=>r});var n=s(11504);const c={},o=n.createContext(c);function r(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[9256],{8964:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=s(17624),c=s(4552);const o={id:"nested-ctypes",title:"Nested CTypes"},r=void 0,a={id:"concepts/advanced_concepts/nested-ctypes",title:"Nested CTypes",description:"A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them.",source:"@site/docs/concepts/09_advanced_concepts/02_nested_ctypes.md",sourceDirName:"concepts/09_advanced_concepts",slug:"/concepts/advanced_concepts/nested-ctypes",permalink:"/docs/concepts/advanced_concepts/nested-ctypes",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/concepts/09_advanced_concepts/02_nested_ctypes.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:2,frontMatter:{id:"nested-ctypes",title:"Nested CTypes"},sidebar:"concepts",previous:{title:"Terms and Quotes",permalink:"/docs/concepts/advanced_concepts/terms-and-quotes"},next:{title:"KILT Glossary",permalink:"/docs/concepts/glossary"}},i={},d=[{value:"Referencing",id:"referencing",level:2}];function p(e){const t={code:"code",h2:"h2",p:"p",...(0,c.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them.\nFor example, a company could use a Nested CType that includes the required credentials, qualifications, health and safety certificates, etc. of its current employees.\nWhen verifying a Nested CType, the sub-CTypes need to be available."}),"\n",(0,n.jsx)(t.h2,{id:"referencing",children:"Referencing"}),"\n",(0,n.jsxs)(t.p,{children:["JSON-schema provides a referencing keyword ",(0,n.jsx)(t.code,{children:"$ref"})," that can be used as a pointer from other JSON schemas.\nThis allows CTypes to either reference fields in other CTypes or nest entire CTypes within one another, providing flexibility for several different use cases.\nA claim from a Nested CType requires the given CType, a list of comprised schemas, the claim content and the address of the owner."]}),"\n",(0,n.jsx)(t.p,{children:"This facility requires all JSON objects to build the schema and allows the reuse of previous schemas, reducing the need for copy-and-paste."})]})}function l(e={}){const{wrapper:t}={...(0,c.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},4552:(e,t,s)=>{s.d(t,{I:()=>a,M:()=>r});var n=s(11504);const c={},o=n.createContext(c);function r(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2e697b7b.b3b510e4.js b/assets/js/2e697b7b.3b9c5490.js similarity index 95% rename from assets/js/2e697b7b.b3b510e4.js rename to assets/js/2e697b7b.3b9c5490.js index 2e125978b..e5b79514d 100644 --- a/assets/js/2e697b7b.b3b510e4.js +++ b/assets/js/2e697b7b.3b9c5490.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5904],{79216:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>a});var n=i(17624),o=i(4552);const s={id:"specifications",title:"Technical Specifications"},c=void 0,r={id:"develop/specifications",title:"Technical Specifications",description:"This section is a WIP.",source:"@site/docs/develop/04_specifications.md",sourceDirName:"develop",slug:"/develop/specifications",permalink:"/docs/develop/specifications",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/04_specifications.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:4,frontMatter:{id:"specifications",title:"Technical Specifications"}},l={},a=[];function d(e){const t={a:"a",admonition:"admonition",li:"li",p:"p",ul:"ul",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsx)(t.p,{children:"This section is a WIP.\nThe end goal is for it to host all KILT specifications."})}),"\n",(0,n.jsx)(t.p,{children:"List of core specifications KILT has defined in an effort to standardize APIs and data structures across applications:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-kilt-did",children:"KILT DID Method (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-KiltPublishedCredentialCollectionV1",children:"KiltPublishedCredentialCollectionV1 Service Type (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-asset-did",children:"Asset DID Method (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-KiltTransferAssetRecipientV1",children:"KiltTransferAssetRecipientV1 Service Type (GitHub repo)"})}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"List of extensions to the core KILT protocol that standardize communication with the core KILT components (e.g., API for wallets to present credentials):"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-credential-api",children:"Wallet Credential API (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-didsign-api",children:"Wallet DIDSign API (GitHub repo)"})}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},4552:(e,t,i)=>{i.d(t,{I:()=>r,M:()=>c});var n=i(11504);const o={},s=n.createContext(o);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[5904],{79216:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>a});var n=i(17624),o=i(4552);const s={id:"specifications",title:"Technical Specifications"},c=void 0,r={id:"develop/specifications",title:"Technical Specifications",description:"This section is a WIP.",source:"@site/docs/develop/04_specifications.md",sourceDirName:"develop",slug:"/develop/specifications",permalink:"/docs/develop/specifications",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/04_specifications.md",tags:[],version:"current",lastUpdatedAt:1718264724,formattedLastUpdatedAt:"Jun 13, 2024",sidebarPosition:4,frontMatter:{id:"specifications",title:"Technical Specifications"}},l={},a=[];function d(e){const t={a:"a",admonition:"admonition",li:"li",p:"p",ul:"ul",...(0,o.M)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsx)(t.p,{children:"This section is a WIP.\nThe end goal is for it to host all KILT specifications."})}),"\n",(0,n.jsx)(t.p,{children:"List of core specifications KILT has defined in an effort to standardize APIs and data structures across applications:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-kilt-did",children:"KILT DID Method (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-KiltPublishedCredentialCollectionV1",children:"KiltPublishedCredentialCollectionV1 Service Type (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-asset-did",children:"Asset DID Method (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-KiltTransferAssetRecipientV1",children:"KiltTransferAssetRecipientV1 Service Type (GitHub repo)"})}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"List of extensions to the core KILT protocol that standardize communication with the core KILT components (e.g., API for wallets to present credentials):"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-credential-api",children:"Wallet Credential API (GitHub repo)"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/KILTprotocol/spec-ext-didsign-api",children:"Wallet DIDSign API (GitHub repo)"})}),"\n"]})]})}function p(e={}){const{wrapper:t}={...(0,o.M)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},4552:(e,t,i)=>{i.d(t,{I:()=>r,M:()=>c});var n=i(11504);const o={},s=n.createContext(o);function c(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3185209f.ed926877.js b/assets/js/3185209f.ef39d14e.js similarity index 93% rename from assets/js/3185209f.ed926877.js rename to assets/js/3185209f.ef39d14e.js index e711033e3..e72c8c316 100644 --- a/assets/js/3185209f.ed926877.js +++ b/assets/js/3185209f.ef39d14e.js @@ -1 +1 @@ -(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2752],{48952:e=>{function n(e){var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}n.keys=()=>[],n.resolve=n,n.id=48952,e.exports=n},38240:(e,n,t)=>{"use strict";t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>y,frontMatter:()=>d,metadata:()=>c,toc:()=>h});var i=t(17624),s=t(4552),o=t(96020);const r="import * as Kilt from '@kiltprotocol/sdk-js'\n\n// `window` object: Should be used only in the following example.\n// Otherwise import directly from the KILT extension library.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nlet window: {\n kilt: {\n sporran: {\n startSession: (\n dAppName: string,\n dAppEncryptionKeyUri: Kilt.DidResourceUri,\n challenge: string\n ) => Promise\n }\n }\n}\n\nexport async function main() {\n const api = Kilt.ConfigService.get('api')\n\n const did = 'did:kilt:4smcAoiTiCLaNrGhrAM4wZvt5cMKEGm8f3Cu9aFrpsh5EiNV'\n const dAppName = 'Your dApp Name'\n\n const encodedFullDid = await api.call.did.query(Kilt.Did.toChain(did))\n const { document } = Kilt.Did.linkedInfoFromChain(encodedFullDid)\n // If there is no DID, or the DID does not have any key agreement key, return\n if (!document.keyAgreement || !document.keyAgreement[0]) {\n return\n }\n const dAppEncryptionKeyUri =\n `${document.uri}${document.keyAgreement[0].id}` as Kilt.DidResourceUri\n\n // Generate and store challenge on the server side for the next step.\n const response = await fetch('/challenge')\n const challenge = await response.text()\n\n const session = await window.kilt.sporran.startSession(\n dAppName,\n dAppEncryptionKeyUri,\n challenge\n )\n\n return session\n}\n",a="import * as Kilt from '@kiltprotocol/sdk-js'\n\nexport async function main({\n session,\n keyAgreementKeyPair,\n originalChallenge\n}: {\n session: {\n encryptionKeyUri: Kilt.DidResourceUri\n encryptedChallenge: string\n nonce: string\n }\n keyAgreementKeyPair: Kilt.KiltEncryptionKeypair\n originalChallenge: `0x{string}`\n}) {\n const { encryptionKeyUri, encryptedChallenge, nonce } = session\n const encryptionKey = await Kilt.Did.resolveKey(encryptionKeyUri)\n if (!encryptionKey) {\n throw new Error('an encryption key is required')\n }\n\n const decryptedBytes = Kilt.Utils.Crypto.decryptAsymmetric(\n { box: encryptedChallenge, nonce },\n encryptionKey.publicKey,\n keyAgreementKeyPair.secretKey // derived from your seed phrase\n )\n // If it fails to decrypt, return.\n if (!decryptedBytes) {\n throw new Error('Could not decode')\n }\n\n const decryptedChallenge = Kilt.Utils.Crypto.u8aToHex(decryptedBytes)\n\n // Compare the decrypted challenge to the challenge you stored earlier.\n if (decryptedChallenge !== originalChallenge) {\n throw new Error('Invalid challenge')\n }\n return session\n}\n",d={id:"session",title:"Setting Up the Communication Session"},l=void 0,c={id:"develop/dApp/session",title:"Setting Up the Communication Session",description:"The first step in creating your dapp is to set up the communication session.",source:"@site/docs/develop/07_dApp/03_session.md",sourceDirName:"develop/07_dApp",slug:"/develop/dApp/session",permalink:"/docs/develop/dApp/session",draft:!1,unlisted:!1,editUrl:"https://github.com/KILTprotocol/docs/edit/master/docs/develop/07_dApp/03_session.md",tags:[],version:"current",lastUpdatedAt:1717145747,formattedLastUpdatedAt:"May 31, 2024",sidebarPosition:3,frontMatter:{id:"session",title:"Setting Up the Communication Session"},sidebar:"dApp",previous:{title:"Well-Known DID Configuration",permalink:"/docs/develop/dApp/well-known-did-config"},next:{title:"Verifying a Credential",permalink:"/docs/develop/dApp/dapp-verifier"}},p={},h=[{value:"Dapp Indicates Credential API Support",id:"dapp-indicates-credential-api-support",level:2},{value:"Dapp Introduces Itself",id:"dapp-introduces-itself",level:2},{value:"Dapp checks the session values",id:"dapp-checks-the-session-values",level:2}];function u(e){const n={code:"code",h2:"h2",p:"p",pre:"pre",...(0,s.M)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"The first step in creating your dapp is to set up the communication session.\nThe purpose of the session is to pass encrypted messages back and forth between your dapp and the extension."}),"\n",(0,i.jsx)(n.h2,{id:"dapp-indicates-credential-api-support",children:"Dapp Indicates Credential API Support"}),"\n",(0,i.jsxs)(n.p,{children:["In order to indicate its support of the extension's API, the dapp creates the ",(0,i.jsx)(n.code,{children:"window.kilt"})," object as soon as possible.\nTo indicate the API version that the dapp supports, we also create the properties ",(0,i.jsx)(n.code,{children:"window.kilt.meta.versions.credentials"}),".\nSince ",(0,i.jsx)(n.code,{children:"meta"})," is not an extension, this property is not enumerable.\nFor example:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-html",children:"\n - + + -

Nested CTypes

A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them. +

Nested CTypes

A Nested CType is a hierarchical composite schema that includes other CTypes as substructures by referencing them. For example, a company could use a Nested CType that includes the required credentials, qualifications, health and safety certificates, etc. of its current employees. When verifying a Nested CType, the sub-CTypes need to be available.

Referencing

JSON-schema provides a referencing keyword $ref that can be used as a pointer from other JSON schemas. This allows CTypes to either reference fields in other CTypes or nest entire CTypes within one another, providing flexibility for several different use cases. A claim from a Nested CType requires the given CType, a list of comprised schemas, the claim content and the address of the owner.

-

This facility requires all JSON objects to build the schema and allows the reuse of previous schemas, reducing the need for copy-and-paste.

+

This facility requires all JSON objects to build the schema and allows the reuse of previous schemas, reducing the need for copy-and-paste.

\ No newline at end of file diff --git a/docs/concepts/advanced_concepts/terms-and-quotes/index.html b/docs/concepts/advanced_concepts/terms-and-quotes/index.html index 3c8257060..8893e3525 100644 --- a/docs/concepts/advanced_concepts/terms-and-quotes/index.html +++ b/docs/concepts/advanced_concepts/terms-and-quotes/index.html @@ -4,11 +4,11 @@ Terms and Quotes | KILT Protocol - - + + -

Terms and Quotes

During the attestation flow, it can happen that either the Claimer requests or the Attester sends the terms of the attestation, i.e., the requirements set by the both parties (the Claimer and the Attester) for the conditions of the attestation.

+

Terms and Quotes

During the attestation flow, it can happen that either the Claimer requests or the Attester sends the terms of the attestation, i.e., the requirements set by the both parties (the Claimer and the Attester) for the conditions of the attestation.

These terms are defined and agreed upon before the credential is issued. This part of the process requires interaction and communication between both parties. This communication can be done independently, e.g., in person, via messaging, on social media etc., or via the KILT Software Development Kit (SDK).

@@ -47,6 +47,6 @@

Defining a If the Attester wishes to add a Quote to their Terms, the Attester signs the Quote object before sending it as part of the "submit terms" message to the Claimer. After the Claimer has received the signed Quote and accepts it, the Claimer counter-signs it and attaches the credential hash for linking the Quote to the credential that it refers to. After the final exchange, the Attester checks all the information and issues the credential.

-

+
\ No newline at end of file diff --git a/docs/concepts/asset-dids/index.html b/docs/concepts/asset-dids/index.html index 959c3e6fa..cd0d9c489 100644 --- a/docs/concepts/asset-dids/index.html +++ b/docs/concepts/asset-dids/index.html @@ -4,11 +4,11 @@ AssetDIDs | KILT Protocol - - + + -

AssetDIDs

KILT DIDs are suitable for use cases that involve "active" participants. +

AssetDIDs

KILT DIDs are suitable for use cases that involve "active" participants. For example, entities that can act of their will (a person, an organization, a DAO).

There are classes of entities that represent "passive" participants. That is, they can be "used" by active participants within a given use case. @@ -36,6 +36,6 @@

CryptoPunk piece #1005 rather than to the CryptoPunks collection as a whole.

Credits to OpenSea for the NFT image above.

-

For a more technical explanation of AssetDIDs, please visit our official specification.

+

For a more technical explanation of AssetDIDs, please visit our official specification.

\ No newline at end of file diff --git a/docs/concepts/credentials/attestation/index.html b/docs/concepts/credentials/attestation/index.html index 27ab69b37..555e6bb22 100644 --- a/docs/concepts/credentials/attestation/index.html +++ b/docs/concepts/credentials/attestation/index.html @@ -4,11 +4,11 @@ Attestations | KILT Protocol - - + + -

Attestations

In KILT, the terms Attestation and Credential are often used interchangeably, albeit their meaning is slightly different. +

Attestations

In KILT, the terms Attestation and Credential are often used interchangeably, albeit their meaning is slightly different. Precisely 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.

To write an attestation on the blockchain, the Attester checks the validity of the received to-be-attested Credential, ensuring that the data inside it match the requirements of the attestation (e.g., that the user's name is indeed Alice).

After that, the Attester writes the Credential's root hash on the KILT blockchain, basically certifying that a credential with that root hash is valid. @@ -18,6 +18,6 @@

Storing Attestations

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. The deposit serves as a security measure to ensure the integrity of the blockchain and incentivize users to manage their attestation responsibly. By requiring a deposit, it discourages spamming or unnecessary creation of attestation. -The deposit can be reclaimed by the attester by deleting their attestation. Revoking them is not sufficient.

+The deposit can be reclaimed by the attester by deleting their attestation. Revoking them is not sufficient.

\ No newline at end of file diff --git a/docs/concepts/credentials/claiming/index.html b/docs/concepts/credentials/claiming/index.html index c26f2b901..7f8f76176 100644 --- a/docs/concepts/credentials/claiming/index.html +++ b/docs/concepts/credentials/claiming/index.html @@ -4,11 +4,11 @@ Claims | KILT Protocol - - + + -

Claims

As KILT is an open system, entities can make claims about any other entities, including themselves. +

Claims

As KILT is an open system, entities can make claims about any other entities, including themselves. A claim (as in the real world) can only be trusted if another trusted entity (we call them Attesters) certifies this claim. Therefore, Verifiers might trust different Attesters for distinct scenarios.

Creating a Claim

@@ -20,6 +20,6 @@

Requ

Once the Claimer has created a claim, they need to get it certified, i.e., attested, by an Attester. The resulting Credential must then be sent to the chosen Attester using any messaging system.

The to-be-attested Credential contains the original claim, data needed for future selective disclosure (more on that in the Verification section) of the claim contents, the legitimation and / or delegation ID of the Attester and the credential root hash, which is used to identify both the credential and its on-chain attestation.

-

For a detailed developer-oriented guide to KILT claims, see our Claim Cookbook section.

+

For a detailed developer-oriented guide to KILT claims, see our Claim Cookbook section.

\ No newline at end of file diff --git a/docs/concepts/credentials/ctypes/index.html b/docs/concepts/credentials/ctypes/index.html index dbffe3bdd..a9e1a02be 100644 --- a/docs/concepts/credentials/ctypes/index.html +++ b/docs/concepts/credentials/ctypes/index.html @@ -4,11 +4,11 @@ CTypes | KILT Protocol - - + + -

CTypes

CTypes are data types specific to KILT that define the structure of a claim (i.e., its data model). +

CTypes

CTypes are data types specific to KILT that define the structure of a claim (i.e., its data model). CTypes are based on JSON Schema, a standard used to annotate and validate JSON documents. The schema defines which properties exist and what their type should be, e.g., a string, a number, an object, etc.

JSON Schema

@@ -75,6 +75,6 @@

Querying the full content of a CType then becomes trivial, since the CType hash can be used to look up its creation block number, and then that information can be used to ask any KILT archive node for the extrinsic information about the CType creation. The information includes the whole CType, which is now available for the user to, e.g., verify credentials against it.

For adding a CType, a constant fee of 0.001 KILT is required.

-

For a detailed developer-oriented guide to KILT CTypes, see our CType Cookbook section.

+

For a detailed developer-oriented guide to KILT CTypes, see our CType Cookbook section.

\ No newline at end of file diff --git a/docs/concepts/credentials/overview/index.html b/docs/concepts/credentials/overview/index.html index e7a42776c..b4dbcf3b2 100644 --- a/docs/concepts/credentials/overview/index.html +++ b/docs/concepts/credentials/overview/index.html @@ -4,11 +4,11 @@ Overview | KILT Protocol - - + + -

Overview

Credentials consist of a set of claims which belong to a Claimer, are attested by an Attester and can be verified by Verifiers.

+

Overview

Credentials consist of a set of claims which belong to a Claimer, are attested by an Attester and can be verified by Verifiers.

Credential Overview DiagramCredential Overview Diagram

To get a credential, a Claimer needs to go through following process:

    @@ -26,6 +26,6 @@
  1. The Verifier checks the presentation structure, content and signature, and decides whether they trust the Attester of the presented credential.

Each step is described in more detail in the next sections.

-

If you want to learn about how implement the above flow in a dapp that interacts with a browser extension, please refer to the Credential API specification.

+

If you want to learn about how implement the above flow in a dapp that interacts with a browser extension, please refer to the Credential API specification.

\ No newline at end of file diff --git a/docs/concepts/credentials/public-credentials/index.html b/docs/concepts/credentials/public-credentials/index.html index 68787d717..3456275d6 100644 --- a/docs/concepts/credentials/public-credentials/index.html +++ b/docs/concepts/credentials/public-credentials/index.html @@ -4,16 +4,16 @@ Public Credentials for Assets | KILT Protocol - - + + -

Public Credentials for Assets

Given that with AssetDIDs there is now a way to uniquely identify assets regardless of the chain they live on or their current owner, KILT also allows owners of an on-chain DID with an assertion key (a.k.a. attesters) to issue credentials to those assets.

+

Public Credentials for Assets

Given that with AssetDIDs there is now a way to uniquely identify assets regardless of the chain they live on or their current owner, KILT also allows owners of an on-chain DID with an assertion key (a.k.a. attesters) to issue credentials to those assets.

Public credentials are not very different in their structure from traditional KILT credentials. The main difference is that, since they are public, public credentials do not have any selective disclosure capabilities, hence all the cryptographic information required to enable those is stripped away from the credential content. Everything else remains as for regular credentials, including the requirement for its structure to match a given CType, and optionally the presence of some delegation information.

Public credential example
{
"claims": {
"name": "Alice",
"age": 29
},
"cTypeHash": "0xc22f85da01c18c1b48acf9556ac7167247ce253cc10373ea77f50fc91521d478",
"delegationId": null,
"subject": "did:asset:eip155:1.erc721:0xb47e3cd837ddf8e4c57f05d70ab865de6e193bbb:1005"
}
Anyone can be an attester!

While traditional KILT credentials are held in the wallet of their owner, who then decides what credential to share with whom, public credentials are, as the name suggests, public by design. -This means that when reading all the credentials issued for a given asset, consumers should be aware of the level of trust they have towards the issuer of each credential, as is the case for traditional KILT credentials.

+This means that when reading all the credentials issued for a given asset, consumers should be aware of the level of trust they have towards the issuer of each credential, as is the case for traditional KILT credentials.

\ No newline at end of file diff --git a/docs/concepts/credentials/verification/index.html b/docs/concepts/credentials/verification/index.html index 2abac4733..3675471ad 100644 --- a/docs/concepts/credentials/verification/index.html +++ b/docs/concepts/credentials/verification/index.html @@ -4,11 +4,11 @@ Verification | KILT Protocol - - + + -

Verification

KILT allows a Verifier to check if the information in a credential presented by a Claimer is correct and valid. +

Verification

KILT allows a Verifier to check if the information in a credential presented by a Claimer is correct and valid. With the presentation of the credential, the Claimer also presents evidence that a third party (i.e., an Attester) ensured the correctness of the Claimer’s attributes.

The Verifier trusts this third party either because they trust their reputation directly or they trust a delegation structure that this Attester is part of (e.g., a State department issuing driving licenses).

For the verification process:

@@ -53,6 +53,6 @@

Verification Cookbook section.

+

For a detailed developer-oriented guide to KILT credential verification, see our Verification Cookbook section.

\ No newline at end of file diff --git a/docs/concepts/did/index.html b/docs/concepts/did/index.html index a76237630..4c689e6c7 100644 --- a/docs/concepts/did/index.html +++ b/docs/concepts/did/index.html @@ -4,11 +4,11 @@ KILT Decentralized Identifiers (DIDs) | KILT Protocol - - + + -

KILT Decentralized Identifiers (DIDs)

A KILT decentralized identifier (DID) is a string of letters and numbers uniquely identifying each KILT user.

+

KILT Decentralized Identifiers (DIDs)

A KILT decentralized identifier (DID) is a string of letters and numbers uniquely identifying each KILT user.

Think of a DID as a container of different keys all under the control of the same DID subject.

DID spec

For the official W3C DID spec, read the DID Core spec page; for the official KILT DID method specification, read the KILT DID spec page.

The simplest type of KILT DID is a light DID, because you can generate and use it offline and no connection with the KILT blockchain. @@ -42,6 +42,6 @@

Storing a DID<

The inclusion of services and keys determines the overall size of the DID. The more services and keys in the DID, the larger the storage space required and, consequently, the higher the additional deposit.

When updating the DID, the deposit is automatically adjusted to match the updated size. This ensures that the deposit accurately reflects the current storage requirements of the DID, whether they increase or decrease.

-

You can reclaim the deposit when the DID is deleted from the blockchain, allowing users to retrieve the deposited amount. However, the additional fee can't be refunded once paid.

+

You can reclaim the deposit when the DID is deleted from the blockchain, allowing users to retrieve the deposited amount. However, the additional fee can't be refunded once paid.

\ No newline at end of file diff --git a/docs/concepts/dip/consumer/index.html b/docs/concepts/dip/consumer/index.html index b805a74dd..59dfa3be3 100644 --- a/docs/concepts/dip/consumer/index.html +++ b/docs/concepts/dip/consumer/index.html @@ -4,11 +4,11 @@ Decentralized Identity Provider (DIP) provider consumer pallet | KILT Protocol - - + + -

Decentralized Identity Provider (DIP) provider consumer pallet

+

Decentralized Identity Provider (DIP) provider consumer pallet

This pallet is a core component of the Decentralized Identity Provider protocol. It enables entities with an identity on a connected Substrate-based chain (provider) to use those identities on the chain this pallet is deployed (consumers) without requiring those entities to set up a new identity locally. A consumer chain is connected to a provider if there is a way for the consumer chain to verify state proofs about parts of the state of the provider chain.

@@ -57,6 +57,6 @@

OriginCalls (bullet numbers represent each call's encoded index)

  1. pub fn dispatch_as(origin: OriginFor<T>, identifier: T::Identifier, proof: IdentityProofOf<T>, call: Box<RuntimeCallOf<T>>) -> DispatchResult: Try to dispatch a new local call only if it passes all the DIP requirements. Specifically, the call will be dispatched if it passes the preliminary DipCallOriginFilter and if the proof verifier returns an Ok(verification_result) value. The value is then added to the DipOrigin and passed down as the origin for the specified Call. If the whole execution terminates successfully, any changes applied to the LocalIdentityInfo by the proof verifier are persisted to the pallet storage.
  2. -
+
\ No newline at end of file diff --git a/docs/concepts/dip/dapp-developer/index.html b/docs/concepts/dip/dapp-developer/index.html index f05f09341..8bf9603d3 100644 --- a/docs/concepts/dip/dapp-developer/index.html +++ b/docs/concepts/dip/dapp-developer/index.html @@ -4,11 +4,11 @@ Dapp developer | KILT Protocol - - + + -

Dapp developer

DIP feature support
  • 1.13.0 Peregrine
  • 1.12.1 Peregrine
  • +

    Dapp developer

    DIP feature support
  • 1.13.0 Peregrine
  • 1.12.1 Peregrine
  • The Decentralized Identity Provider (DIP) SDK helps Dapp developers build DIP functionality into their apps.

    Installation

    Add the SDK as a dependency:

    @@ -71,6 +71,6 @@

    on GitHub.

    To add the extension, use the generateDipSubmittableExtrinsic method and pass the additional proof elements along with consumer chain specific components.

    const dipSubmittable = DipSdk.generateDipSubmittableExtrinsic({
    additionalProofElements:
    DipSdk.dipProof.extensions.timeBoundDidSignature.toChain(
    crossChainDidSignature
    ),
    api: consumerApi,
    baseDipProof,
    call,
    didUri: did.uri,
    })
    -
    info

    Read the auto-generated API documentation for more details on the methods the SDK provides.

    +
    info

    Read the auto-generated API documentation for more details on the methods the SDK provides.

    \ No newline at end of file diff --git a/docs/concepts/dip/dip-accounts-kilt/index.html b/docs/concepts/dip/dip-accounts-kilt/index.html index e279cbcaa..318d5e8d0 100644 --- a/docs/concepts/dip/dip-accounts-kilt/index.html +++ b/docs/concepts/dip/dip-accounts-kilt/index.html @@ -4,11 +4,11 @@ Enabling DIP for user accounts on the KILT blockchain | KILT Protocol - - + + -

    Enabling DIP for user accounts on the KILT blockchain

    DIP feature support
  • 1.13.0 Peregrine
  • 1.12.1 Peregrine
  • +

    Enabling DIP for user accounts on the KILT blockchain

    DIP feature support
  • 1.13.0 Peregrine
  • 1.12.1 Peregrine
  • For an account to take advantage of DIP it needs a decentralized identity (DID) and to create a transaction on the provider chain to generate a cross-chain identity commitment.

    For an account to be able to do this, a Dapp developer needs to build the functionality into their app for a user using the DIP SDK.

    The implementation of this transaction is per-chain and this documentation provides an example of how to do this on the KILT blockchain.

    @@ -42,6 +42,6 @@

    Using
  • identityDetailsRuntimeType The runtime type definition for the IdentityDetails on the consumer chain. Uses the Option<u128> type, representing a simple nonce if not provided.
  • includeWeb3Name Flag indicating whether the generated DIP proof should include the web3name of the DID subject. If not provided, the web3name is not revealed.
  • linkedAccounts The list of linked accounts to revealed in the generated DIP proof. No account is revealed if not provided.
  • -

    +
    \ No newline at end of file diff --git a/docs/concepts/dip/provider/index.html b/docs/concepts/dip/provider/index.html index 9a9b6040c..da286e2a0 100644 --- a/docs/concepts/dip/provider/index.html +++ b/docs/concepts/dip/provider/index.html @@ -4,11 +4,11 @@ Provider pallet | KILT Protocol - - + + -

    Provider pallet

    +

    Provider pallet

    This pallet is a core component of the Decentralized Identity Provider protocol. It enables a Substrate-based chain (provider) to bridge the identities of its users to other connected chains (consumers) trustlessly. A consumer chain is connected to a provider if there is a way for the consumer chain to verify state proofs about parts of the state of the provider chain.

    @@ -44,6 +44,6 @@

  • pub fn commit_identity(origin: OriginFor<T>, identifier: T::Identifier, version: Option<IdentityCommitmentVersion> ) -> DispatchResult: Generate a new versioned commitment for the subject identified by the provided Identifier. If an old commitment for the same version is present, it is overridden. Hooks are called before the new commitment is stored, and optionally before the old one is replaced.
  • pub fn delete_identity_commitment(origin: OriginFor<T>, identifier: T::Identifier, version: Option<IdentityCommitmentVersion>) -> DispatchResult: Delete an identity commitment of a specific version for a specific Identifier. If a commitment of the provided version does not exist for the given Identifier, an error is returned. Hooks are called after the commitment has been removed.
  • -

    +
    \ No newline at end of file diff --git a/docs/concepts/dip/what-is-dip/index.html b/docs/concepts/dip/what-is-dip/index.html index 4f8a67d57..1ca5c750e 100644 --- a/docs/concepts/dip/what-is-dip/index.html +++ b/docs/concepts/dip/what-is-dip/index.html @@ -4,11 +4,11 @@ Overview | KILT Protocol - - + + -

    Overview

    DIP feature support
  • 1.13.0 Peregrine
  • 1.12.1 Peregrine
  • +

    Overview

    DIP feature support
  • 1.13.0 Peregrine
  • 1.12.1 Peregrine
  • The Decentralized Identity Provider (DIP) enables a cross-chain decentralized identity system that mirrors the functionality of OpenID.

    DIP has three key roles: the identity provider, the consumer, and the user.

      @@ -42,6 +42,6 @@

      User a
      info

      Find more details in the user account section.

      Dapp developer

      The DIP SDK is a JavaScript library that makes it easier for Dapp developers to integrate DIP into their apps. The SDK includes methods for interacting with runtimes, generating proofs, and more.

      -
      info

      Find more details in the Dapp developer section.

    +
    info

    Find more details in the Dapp developer section.

    \ No newline at end of file diff --git a/docs/concepts/distributed_trust/index.html b/docs/concepts/distributed_trust/index.html index e6571f7ae..75d4e87a6 100644 --- a/docs/concepts/distributed_trust/index.html +++ b/docs/concepts/distributed_trust/index.html @@ -4,11 +4,11 @@ Distributed Trust | KILT Protocol - - + + -

    Distributed Trust

    Sometimes, Attesters are individuals that attest to the validity of claims made by Claimers. +

    Distributed Trust

    Sometimes, Attesters are individuals that attest to the validity of claims made by Claimers. However, usually multiple Attesters group together to build up trust in a brand. In this way, Verifiers no longer need to trust each and every Attester individually. They can put trust in the brand as a whole, which in return ensures that all Attesters working for this brand are credible. @@ -44,6 +44,6 @@

    RevocationStoring delegation node

    Adding a new node in the delegation hierarchies requires providing a constant deposit, which is currently 1 KILT. The deposit serves as a security measure to ensure the integrity of the blockchain and incentivize users to manage their nodes responsibly. By requiring a deposit, it discourages spamming or unnecessary creation of nodes. -When a user deletes their node, they can reclaim the deposit.

    +When a user deletes their node, they can reclaim the deposit.

    \ No newline at end of file diff --git a/docs/concepts/glossary/index.html b/docs/concepts/glossary/index.html index 2ff4c4de7..48dda5bc2 100644 --- a/docs/concepts/glossary/index.html +++ b/docs/concepts/glossary/index.html @@ -4,11 +4,11 @@ KILT Glossary | KILT Protocol - - + + -

    KILT Glossary

    Here is a glossary of terms related to the KILT Protocol:

    +

    KILT Glossary

    Here is a glossary of terms related to the KILT Protocol:

    W3C: Self-Sovereign Identity (SSI)

    Decentralized Identifier (DID) – a unique digital identifier for entities (people, machines, services, and anything that identities can be built on) which can be anchored to a blockchain to provide the core of a verifiable digital identity. For example, did:kilt:4sxSYXakw1ZXBymzT9t3Yw91mUaqKST5bFUEjGEpvkTuckar. @@ -69,6 +69,6 @@

    Ecosystem Te

    Substrate - a modular blockchain development framework used to build custom blockchain solutions, including the KILT Protocol blockchain. More details about Substrate can be found in the official Polkadot documentation

    Relay Chain - the central chain in the Polkadot network that coordinates communication and consensus between different parachains. -More details about parachains can be found in the official Polkadot documentation

    +More details about parachains can be found in the official Polkadot documentation

    \ No newline at end of file diff --git a/docs/concepts/messaging/index.html b/docs/concepts/messaging/index.html index 1d6062e71..c307295f6 100644 --- a/docs/concepts/messaging/index.html +++ b/docs/concepts/messaging/index.html @@ -4,11 +4,11 @@ KILT Messaging | KILT Protocol - - + + -

    KILT Messaging

    Distributed trust on the internet only works if credentials and other information can be exchanged securely, and communicating parties can be confident that bad actors aren't fooling or eavesdropping on them. +

    KILT Messaging

    Distributed trust on the internet only works if credentials and other information can be exchanged securely, and communicating parties can be confident that bad actors aren't fooling or eavesdropping on them. KILT provides a transport-agnostic messaging layer that helps with securely exchanging data between the respective owners of two DIDs.

    This messaging layer provides authenticated end-to-end encryption, the gold standard in secure communication, in a way that hides the security of the technologies used for transporting the message over the internet – be it sending the encrypted messages via email, or posting them to and fetching them from a centralized or decentralized messaging service.

    info

    The messaging layer enables secure communication between two digital identities, DIDs. @@ -25,6 +25,6 @@

    The encrypted message not only references the DIDs of sender and recipient, it also references the unique identifier of the keys that used in encryption. Therefore, this scheme still works if a DID should expose multiple encryption keys from which a message sender may choose.

    caution

    While no one can read or change what's inside an encrypted message even if they intercept it while traveling on the network, a sophisticated attacker may try to guess what's inside and trick either side of the channel by resubmitting a copy of that message later. -For a detailed developer-oriented guide about how to protect against replay attacks, read the Replay Protection Cookbook section.

    +For a detailed developer-oriented guide about how to protect against replay attacks, read the Replay Protection Cookbook section.

    \ No newline at end of file diff --git a/docs/concepts/web3names/index.html b/docs/concepts/web3names/index.html index 5e8b2cc3f..637b63eb4 100644 --- a/docs/concepts/web3names/index.html +++ b/docs/concepts/web3names/index.html @@ -4,11 +4,11 @@ web3names | KILT Protocol - - + + -

    web3names

    web3names are user-friendly aliases for KILT DIDs. +

    web3names

    web3names are user-friendly aliases for KILT DIDs. They serve the same purpose as domain names for IP addresses. Do you know the IP address for the "kilt.io" domain name? 🤷🏽‍♀️ There is a one-to-one relationship between DIDs and web3names. @@ -45,6 +45,6 @@

    K

    The cost for storing a web3name

    Storing a web3name on the KILT blockchain requires providing a constant deposit, which is currently around 0.11 KILT. The deposit amount is calculated based on the worst-case scenario for a web3name, which is when a user provides a name with 32 characters. The deposit serves as a security measure to ensure the integrity of the KILT blockchain and incentivize users to manage their web3names responsibly. -A deposit discourages spamming or unnecessary creation of web3names. You can reclaim the deposit can by deleting a web3name.

    +A deposit discourages spamming or unnecessary creation of web3names. You can reclaim the deposit can by deleting a web3name.

    \ No newline at end of file diff --git a/docs/concepts/what-is-kilt/index.html b/docs/concepts/what-is-kilt/index.html index aa63f6e67..1e0961e77 100644 --- a/docs/concepts/what-is-kilt/index.html +++ b/docs/concepts/what-is-kilt/index.html @@ -4,11 +4,11 @@ What is KILT? | KILT Protocol - - + + -

    What is KILT?

    KILT is a protocol for self-sovereign data and interoperability built on top of the permissionless KILT blockchain.

    +

    What is KILT?

    KILT is a protocol for self-sovereign data and interoperability built on top of the permissionless KILT blockchain.

    The core component of KILT is a digital identity protocol for:

    1. Generating and managing decentralized identifiers (DIDs)
    2. @@ -59,6 +59,6 @@

      The solutionObtaining digital verifiable credentials for user-specified claims
    3. Supporting revocation of verifiable credentials by their Attesters
    4. Presenting and verifying verifiable credentials in a privacy-preserving and user-controlled way
    5. -

    +
    \ No newline at end of file diff --git a/docs/develop/builtonkilt/index.html b/docs/develop/builtonkilt/index.html index 0b96ec061..32129fcba 100644 --- a/docs/develop/builtonkilt/index.html +++ b/docs/develop/builtonkilt/index.html @@ -4,11 +4,11 @@ Built on KILT | KILT Protocol - - + + -

    Built on KILT

    This section contains a non-exhaustive list of apps, wallets and websites that are built on KILT. +

    Built on KILT

    This section contains a non-exhaustive list of apps, wallets and websites that are built on KILT. If you are not on the list and want to be added, you are welcome to open a PR.

    Wallets

    Wallets are the gateway to Web3. @@ -29,6 +29,6 @@

    Web Apps
    bte-socialkyc-logobte-socialkyc-logo
    Get your first KILT credential today! SocialKYC issues credentials that prove ownership of several social profiles, including email addresses, and Telegram, Twitter and GitHub accounts, with more being continuously added. -It's free to use, and credentials expire after one year.

    +It's free to use, and credentials expire after one year. \ No newline at end of file diff --git a/docs/develop/chain/deployments/index.html b/docs/develop/chain/deployments/index.html index 95c08142a..380b7e49c 100644 --- a/docs/develop/chain/deployments/index.html +++ b/docs/develop/chain/deployments/index.html @@ -4,14 +4,14 @@ Deployments and Services | KILT Protocol - - + + -

    Deployments and Services

    KILT has two public deployments: a production one, called Spiritnet, and a test/dev one, called Peregrine. +

    Deployments and Services

    KILT has two public deployments: a production one, called Spiritnet, and a test/dev one, called Peregrine. To learn more about how to set up a node for either environment, please check our fullnode set up guide.

    Spiritnet is the production blockchain, and has been live since September 2021.

    Peregrine is the public testnet, which can be used to build and test products that use the KILT blockchain, before switching to Spiritnet.

    -
    ServiceSpiritnetPeregrine
    Faucet-Peregrine Faucet
    Public EndpointsBOTLabs: wss://spiritnet.kilt.io
    OnFinality: wss://spiritnet.api.onfinality.io/public-ws
    Dwellir: wss://kilt-rpc.dwellir.com
    BOTLabs: wss://peregrine.kilt.io
    WalletSporranGitHub (manual loading into the browser)
    Staking UICollators' performance (view only): Stakekilt
    Delegation staking platform: Stakeboard
    -
    Governance UIPolkassembly-
    Chain ExplorerSubscanSubscan
    w3n Servicew3n.idtest.w3n.id
    Link Accountslinking.trusted-entity.iotest.linking.trusted-entity.io
    DIDsigndidsign.iotest.didsign.io
    SocialKYCsocialkyc.iotest.socialkyc.io
    +
    ServiceSpiritnetPeregrine
    Faucet-Peregrine Faucet
    Public EndpointsBOTLabs: wss://spiritnet.kilt.io
    OnFinality: wss://spiritnet.api.onfinality.io/public-ws
    Dwellir: wss://kilt-rpc.dwellir.com
    BOTLabs: wss://peregrine.kilt.io
    WalletSporranGitHub (manual loading into the browser)
    Staking UICollators' performance (view only): Stakekilt
    Delegation staking platform: Stakeboard
    -
    Governance UIPolkassembly-
    Chain ExplorerSubscanSubscan
    w3n Servicew3n.idtest.w3n.id
    Link Accountslinking.trusted-entity.iotest.linking.trusted-entity.io
    DIDsigndidsign.iotest.didsign.io
    SocialKYCsocialkyc.iotest.socialkyc.io
    \ No newline at end of file diff --git a/docs/develop/chain/fullnode-setup/index.html b/docs/develop/chain/fullnode-setup/index.html index b1e65798a..7f5867764 100644 --- a/docs/develop/chain/fullnode-setup/index.html +++ b/docs/develop/chain/fullnode-setup/index.html @@ -4,11 +4,11 @@ Set Up a KILT Full Node | KILT Protocol - - + + -

    Set Up a KILT Full Node

    We will guide you through the process of setting up and connecting to a KILT full node. +

    Set Up a KILT Full Node

    We will guide you through the process of setting up and connecting to a KILT full node. In contrast to a collator, full nodes do not author blocks. They act as a backend for websites and help to verify new blocks or validate extrinsics (e.g., coin transfers and other transactions) directly on the network without relying on a centralized infrastructure provider.

    Setup

    @@ -50,6 +50,6 @@

    Sy

    Once started, the full node needs to fully sync up with both the parachain and the Relay Chain states. Depending on the size of both blockchain states and the node hardware specs, it may take from a number of hours to a few days for the node to fully synchronize. More details can be found in the Polkadot network documentation.

    -
    Example of node sync
    2021-06-17 02:34:34 🔍 Discovered new external address for our node: /ip4/100.102.231.64/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:36 ⚙️ Syncing 409.2 bps, target=#8062689 (5 peers), best: #3477 (0x63ad…e046), finalized #3072 (0x0e4c…f587), ⬇ 153.2kiB/s ⬆ 12.9kiB/s
    2021-06-17 02:34:37 🔍 Discovered new external address for our node: /ip4/100.111.175.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:38 🔍 Discovered new external address for our node: /ip4/100.100.176.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:41 ⚙️ Syncing 386.2 bps, target=#8062690 (7 peers), best: #5409 (0x1d76…8c3d), finalized #5121 (0x8ad1…b6dc), ⬇ 96.1kiB/s ⬆ 10.9kiB/s
    2021-06-17 02:34:46 ⚙️ Syncing 394.8 bps, target=#8062691 (11 peers), best: #7383 (0x0689…6f1e), finalized #7168 (0x72a9…8d8c), ⬇ 352.9kiB/s ⬆ 5.1kiB/s
    2021-06-17 02:34:51 ⚙️ Syncing 347.0 bps, target=#8062692 (12 peers), best: #9118 (0x66fc…cce3), finalized #8704 (0x14c9…705e), ⬇ 62.7kiB/s ⬆ 1.7kiB/s

    +
    Example of node sync
    2021-06-17 02:34:34 🔍 Discovered new external address for our node: /ip4/100.102.231.64/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:36 ⚙️ Syncing 409.2 bps, target=#8062689 (5 peers), best: #3477 (0x63ad…e046), finalized #3072 (0x0e4c…f587), ⬇ 153.2kiB/s ⬆ 12.9kiB/s
    2021-06-17 02:34:37 🔍 Discovered new external address for our node: /ip4/100.111.175.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:38 🔍 Discovered new external address for our node: /ip4/100.100.176.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:41 ⚙️ Syncing 386.2 bps, target=#8062690 (7 peers), best: #5409 (0x1d76…8c3d), finalized #5121 (0x8ad1…b6dc), ⬇ 96.1kiB/s ⬆ 10.9kiB/s
    2021-06-17 02:34:46 ⚙️ Syncing 394.8 bps, target=#8062691 (11 peers), best: #7383 (0x0689…6f1e), finalized #7168 (0x72a9…8d8c), ⬇ 352.9kiB/s ⬆ 5.1kiB/s
    2021-06-17 02:34:51 ⚙️ Syncing 347.0 bps, target=#8062692 (12 peers), best: #9118 (0x66fc…cce3), finalized #8704 (0x14c9…705e), ⬇ 62.7kiB/s ⬆ 1.7kiB/s
    \ No newline at end of file diff --git a/docs/develop/chain/introduction/index.html b/docs/develop/chain/introduction/index.html index 782e5eaf5..5b351875a 100644 --- a/docs/develop/chain/introduction/index.html +++ b/docs/develop/chain/introduction/index.html @@ -4,15 +4,15 @@ Introduction | KILT Protocol - - + + -

    Introduction

    The section covers KILT chain specific topics.

    +
    +
    \ No newline at end of file diff --git a/docs/develop/chain/pallets/pallet-did/index.html b/docs/develop/chain/pallets/pallet-did/index.html index bba93372c..85c1d3e91 100644 --- a/docs/develop/chain/pallets/pallet-did/index.html +++ b/docs/develop/chain/pallets/pallet-did/index.html @@ -4,11 +4,11 @@ DID pallet | KILT Protocol - - + + -

    DID pallet

    In KILT a DID is a decentralized identifier that the user owns and controls. +

    DID pallet

    In KILT a DID is a decentralized identifier that the user owns and controls. It consists of a unique set of keys that can be used for different operations on the blockchain. For an in-depth explanation see the KILT DID spec.

    A DID may be a "light" DID, which is not stored on-chain, or a "full" on-chain DID. @@ -126,6 +126,6 @@

    What
  • The deposit owner can decide to claim their deposit back using the did::reclaim_deposit extrinsic. This will also cause the DID to be fully deleted but it doesn't require a signature from the DID. Only the signature of the account that created the DID is needed for this.
  • -

    +
    \ No newline at end of file diff --git a/docs/develop/contribute/index.html b/docs/develop/contribute/index.html index 962c9ca22..cd595eed5 100644 --- a/docs/develop/contribute/index.html +++ b/docs/develop/contribute/index.html @@ -4,11 +4,11 @@ Contribution Guidelines | KILT Protocol - - + + -

    Contribution Guidelines

    As a decentralized network, KILT depends on the support of its community. +

    Contribution Guidelines

    As a decentralized network, KILT depends on the support of its community. There are many ways to contribute to KILT Protocol and the products and services built on it. The following guide is to help builders and contributors find the resources needed to take action and work under the guidance of the core developers.

    If you are interested in contributing but unsure how to begin, start in our Clan KILT Discord channel. @@ -79,6 +79,6 @@

    Pull Requests< Open an issue or directly contact some of the developers on Discord to kick off the discussion and present the proposal. Once approved, contributors can open a PR for review. The PR will be reviewed and, if accepted, merged into the corresponding repository.

    -

    The following section is inspired by the Rust Programming Language Bug Report contribution guide.

    +

    The following section is inspired by the Rust Programming Language Bug Report contribution guide.

    \ No newline at end of file diff --git a/docs/develop/dApp/dapp-verifier/index.html b/docs/develop/dApp/dapp-verifier/index.html index 8df279a04..96cb3ad22 100644 --- a/docs/develop/dApp/dapp-verifier/index.html +++ b/docs/develop/dApp/dapp-verifier/index.html @@ -4,11 +4,11 @@ Verifying a Credential | KILT Protocol - - + + -

    Verifying a Credential

    This section demonstrates how to build a basic verifier according to the Credential API Specification. +

    Verifying a Credential

    This section demonstrates how to build a basic verifier according to the Credential API Specification. Before continuing, please make sure you have already set up the communication session and Well-Known DID Configuration.

    This guide explains specifically how a web server can request a credential presentation from one of its visitors (the claimer). After the browser extension verified the Well-Known DID Configuration and the encrypted communication channel between the extension and the server was established, the web server can request the credential presentation. @@ -45,6 +45,6 @@

    Veri

    After the response from the extension is received, forwarded to the server and decrypted, the verifier must check that it has the expected CType and that it contains a valid credential. Since everyone can run an attestation service, you need to make sure that you also verify that the attester is trusted.

    async function processInBackend(message: Kilt.IEncryptedMessage) {
    // Create a callback that uses the DID encryption key to decrypt the message.
    const decryptCallback: Kilt.DecryptCallback = async ({
    data,
    nonce,
    peerPublicKey
    }) => {
    const result = Kilt.Utils.Crypto.decryptAsymmetric(
    { box: data, nonce },
    peerPublicKey,
    verifierKeys.encryption.secretKey
    )
    if (!result) {
    throw new Error('Cannot decrypt')
    }
    return {
    data: result
    }
    }

    const decryptedMessage = await Kilt.Message.decrypt(
    message,
    decryptCallback
    )

    if (decryptedMessage.body.type !== 'submit-credential') {
    throw new Error('Unexpected message type')
    }
    const credential = decryptedMessage.body.content[0]

    const { revoked, attester } =
    await Kilt.Credential.verifyPresentation(credential)

    if (revoked) {
    throw new Error("Credential has been revoked and hence it's not valid.")
    }
    if (isTrustedAttester(attester)) {
    console.log(
    "The claim is valid. Claimer's email:",
    credential.claim.contents.Email
    )
    }
    }

    // In the frontend we wait for messages from the browser extension and forward them to the server.
    await session.listen(async (message: Kilt.IEncryptedMessage) => {
    processInBackend(message)
    })
    -

    That's it! Your verifier has successfully requested and verified a credential.

    +

    That's it! Your verifier has successfully requested and verified a credential.

    \ No newline at end of file diff --git a/docs/develop/dApp/session/index.html b/docs/develop/dApp/session/index.html index 5a964dcc8..77ec510b5 100644 --- a/docs/develop/dApp/session/index.html +++ b/docs/develop/dApp/session/index.html @@ -4,11 +4,11 @@ Setting Up the Communication Session | KILT Protocol - - + + -

    Setting Up the Communication Session

    The first step in creating your dapp is to set up the communication session. +

    Setting Up the Communication Session

    The first step in creating your dapp is to set up the communication session. The purpose of the session is to pass encrypted messages back and forth between your dapp and the extension.

    Dapp Indicates Credential API Support

    In order to indicate its support of the extension's API, the dapp creates the window.kilt object as soon as possible. @@ -27,6 +27,6 @@

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function main({
    session,
    keyAgreementKeyPair,
    originalChallenge
    }: {
    session: {
    encryptionKeyUri: Kilt.DidResourceUri
    encryptedChallenge: string
    nonce: string
    }
    keyAgreementKeyPair: Kilt.KiltEncryptionKeypair
    originalChallenge: `0x{string}`
    }) {
    const { encryptionKeyUri, encryptedChallenge, nonce } = session
    const encryptionKey = await Kilt.Did.resolveKey(encryptionKeyUri)
    if (!encryptionKey) {
    throw new Error('an encryption key is required')
    }

    const decryptedBytes = Kilt.Utils.Crypto.decryptAsymmetric(
    { box: encryptedChallenge, nonce },
    encryptionKey.publicKey,
    keyAgreementKeyPair.secretKey // derived from your seed phrase
    )
    // If it fails to decrypt, return.
    if (!decryptedBytes) {
    throw new Error('Could not decode')
    }

    const decryptedChallenge = Kilt.Utils.Crypto.u8aToHex(decryptedBytes)

    // Compare the decrypted challenge to the challenge you stored earlier.
    if (decryptedChallenge !== originalChallenge) {
    throw new Error('Invalid challenge')
    }
    return session
    }

    -

    That's it! The communication session has been securely established and you're ready to start sending and receiving messages.

    +

    That's it! The communication session has been securely established and you're ready to start sending and receiving messages.

    \ No newline at end of file diff --git a/docs/develop/dApp/welcome/index.html b/docs/develop/dApp/welcome/index.html index a0b0c5042..ed46a85c5 100644 --- a/docs/develop/dApp/welcome/index.html +++ b/docs/develop/dApp/welcome/index.html @@ -4,17 +4,17 @@ Overview | KILT Protocol - - + + -

    Overview

    This section expands on the Credential API Specification and includes code examples to help you build a decentralized application (dapp).

    +
    +
    \ No newline at end of file diff --git a/docs/develop/dApp/well-known-did-config/index.html b/docs/develop/dApp/well-known-did-config/index.html index 582f34ca0..cbe0ce9d5 100644 --- a/docs/develop/dApp/well-known-did-config/index.html +++ b/docs/develop/dApp/well-known-did-config/index.html @@ -4,11 +4,11 @@ Well-Known DID Configuration | KILT Protocol - - + + -

    Well-Known DID Configuration

    This is a working draft

    The KILT support of the Well-Known DID Configuration uses unpublished specifications and will change in the future.

    +

    Well-Known DID Configuration

    This is a working draft

    The KILT support of the Well-Known DID Configuration uses unpublished specifications and will change in the future.

    The Well-Known DID Configuration is implemented as a security measure when setting up the communication session between the dapp and extension. It ensures that the DID the browser extension is communicating to is linked to the domain that is visited by the browser. This rule is currently enforced by the KILT Wallet reference implementation (Sporran Extension), but might be relaxed in the future. @@ -62,6 +62,6 @@

    Host t

    Now that you generated a presentation, you need to host it in your web app, so that the extension can query the presentation. The extension will make an HTTP GET request to the following URI, and your dapp must respond with the presentation.

    /.well-known/did-configuration.json

    -

    How the file is hosted depends on your project setup and is out of scope for this guide.

    +

    How the file is hosted depends on your project setup and is out of scope for this guide.

    \ No newline at end of file diff --git a/docs/develop/opendid/advanced/index.html b/docs/develop/opendid/advanced/index.html new file mode 100644 index 000000000..4910715cd --- /dev/null +++ b/docs/develop/opendid/advanced/index.html @@ -0,0 +1,31 @@ + + + + + +Advanced Usage | KILT Protocol + + + + +

    Advanced Usage

    Use dynamic client management with etcd

    +

    To dynamically create or remove OpenID Connect clients, configure the service to get its configuration from an etcd cluster by adding the connection parameters for the cluster in the config.yaml file.

    +
    etcd:
    endpoints: ['localhost:2379']
    user: etcd-user
    password: my-password
    tlsDomainName: my.etcd.cluster.example.com
    tlsCaCert: |
    -----BEGIN CERTIFICATE-----
    <ca certificate data>
    -----END CERTIFICATE-----
    tlsClientCert: |
    -----BEGIN CERTIFICATE-----
    <client certificate data>
    -----END CERTIFICATE-----
    tlsClientKey: |
    -----BEGIN RSA PRIVATE KEY-----
    <client key data>
    -----END RSA PRIVATE KEY-----
    +

    All fields except endpoints are optional. +When everything is set up you can start adding client configurations into the etcd cluster.

    +
    CLIENT_SPEC=$(cat <<EOF
    {
    "requirements": [{
    "cTypeHash":"0x3291bb126e33b4862d421bfaa1d2f272e6cdfc4f96658988fbcffea8914bd9ac",
    "trustedAttesters": [
    "did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY",
    "did:kilt:4pnfkRn5UurBJTW92d9TaVLR2CqJdY4z5HPjrEbpGyBykare"
    ],
    "requiredProperties": ["Email"]
    }],
    "redirectUrls": ["http://localhost:1606/callback.html"]
    }
    EOF
    )
    CLIENT_SPEC=$(echo $CLIENT_SPEC | jq -c)
    etcdctl put /opendid/clients/new-client "${CLIENT_SPEC}"
    +

    If you want to try this out, first generate a configuration file using the setup image as described in the OpenDID service step. +Then add the etcd configuration and start the service using the example script in ./scripts/start-demo-etcd.sh.

    +

    Add advanced claim checks using RHAI scripts

    +

    To add custom checks executed on the claims of the Verifiable Credential, use Rhai scripts. +To try it, add a checksDirectory entry to the client configuration in the config.yaml file.

    +

    Example:

    +
    ---
    clients:
    example-client:
    requirements:
    - cTypeHash: '0x3291bb126e33b4862d421bfaa1d2f272e6cdfc4f96658988fbcffea8914bd9ac'
    trustedAttesters:
    [
    'did:kilt:4pehddkhEanexVTTzWAtrrfo2R7xPnePpuiJLC7shQU894aY',
    'did:kilt:4pnfkRn5UurBJTW92d9TaVLR2CqJdY4z5HPjrEbpGyBykare',
    ]
    requiredProperties: ['Email']
    redirectUrls:
    - http://localhost:1606/callback.html
    checksDirectory: /app/checks
    +

    Create a checks directory in the same directory as the config.yaml file and add a example-check.rhai file with the following content:

    +
    // This is an example of a simple login policy that allows only users with an email address ending with `kilt.io` to login.

    let SUFFIX = "kilt.io";

    // ID_TOKEN contains the id_token to send to the user from the OpenID connect (OIDC) provider
    let token = parse_id_token(ID_TOKEN);

    // Inspect the token and the `pro` sub-object that contains the users claims
    if token.pro.Email.ends_with(SUFFIX) {
    // The user is allowed to login
    return true;
    }

    // The user is not allowed to login
    return false;
    +

    Start the service bind-mounting the script:

    +
    docker run -d --rm \
    -v $(pwd)/config.yaml:/app/config.yaml \
    -v $(pwd)/checks:/app/checks \
    -e RUNTIME=spiritnet \
    -p 3001:3001 \
    docker.io/kiltprotocol/opendid:latest
    +

    When you now log in with a user that has an email address ending with kilt.io as attested by the configured attester, the service allows you to log in. +If you use a different email address, the service denies you access.

    + + \ No newline at end of file diff --git a/docs/develop/opendid/demo_project/index.html b/docs/develop/opendid/demo_project/index.html new file mode 100644 index 000000000..09b38d732 --- /dev/null +++ b/docs/develop/opendid/demo_project/index.html @@ -0,0 +1,26 @@ + + + + + +Demo Project | KILT Protocol + + + + +

    Demo Project

    The example code at demo-project contains a minimal application that uses OpenDID. +It's an express application that exposes three things:

    +
      +
    • A login page that handles the dispatching of the user to the OpenDID service.
    • +
    • A callback page for one of the OpenID Connect flows supported to accept the token.
    • +
    • A protected resource that only authenticated users can access.
    • +
    +

    For the demo application to work you need a running OpenDID Service and an identity wallet that follows the Credential API spec (e.g. Sporran) with a DID and Credential issued by the required attester specified in the config.yaml file (Default is SocialKYC). +If you follow the steps in this section in order, you have all the necessary components for the demo application to run.

    +

    Run the pre-configured demo application with the following command:

    +
    docker run -d -it --rm \
    --name demo-frontend \
    -p 1606:1606 \
    docker.io/kiltprotocol/opendid-demo
    +

    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.

    +
    note

    You can set the JSON web token (JWT) secret can with the TOKEN_SECRET environment variable inside the docker container. It must match +the one specified in the config.yaml file to correctly verify the id_token. The default is super-secret-jwt-secret.

    + + \ No newline at end of file diff --git a/docs/develop/opendid/flow/index.html b/docs/develop/opendid/flow/index.html new file mode 100644 index 000000000..fcafdc88e --- /dev/null +++ b/docs/develop/opendid/flow/index.html @@ -0,0 +1,40 @@ + + + + + +OpenDID Flow | KILT Protocol + + + + +

    OpenDID Flow

    This guide explains the internal workings of OpenDID. +Understanding this flow is helpful for setting up and configuring an OpenDID Service but less important if you only need to integrate it in an application.

    +

    OpenDID includes interactions between multiple apps to authenticate and authorize users. +Common use cases include the following:

    +
      +
    • Web app front end (app that includes the login button, for example, the demo app)
    • +
    • Web app back end
    • +
    • OpenDID front end
    • +
    • OpenDID back end
    • +
    • Identity wallet that follows the Credential API spec (typically a browser extension, for example, Sporran)
    • +
    +

    The following steps outline the interactions necessary to implement the implicit flow:

    +
      +
    1. The user clicks the login button on the web app front end.
    2. +
    3. The web app front end redirects the user to the OpenDID front end.
    4. +
    5. The user chooses what wallet to authenticate with.
    6. +
    7. The OpenDID back end establishes a secure session with the identity wallet.
    8. +
    9. The OpenDID back end optionally requests a credential that implements a specific CType.
    10. +
    11. The identity wallet provides the OpenDID back end with the requested credential, after authenticating the DID holder.
    12. +
    13. The OpenDID back end returns a id_token as a JSON web token (JWT) to the OpenDID front end.
    14. +
    15. OpenDID front end redirects the user back to a specific redirect_url on the web app front end including the id_token.
    16. +
    17. The web app front end detects the id_token and sends it to the web app back end.
    18. +
    19. The web app back end verifies the id_token and ensures the validity of the credential.
    20. +
    +

    The following sequence diagram summarizes the flow:

    + +
    info

    Although this example describes the implicit flow, the authorization code flow is similar. +Instead of returning an id_token directly, the OpenDID service instead returns a code to exchange for an id_token using the token endpoint.

    + + \ No newline at end of file diff --git a/docs/develop/opendid/integrate_opendid/index.html b/docs/develop/opendid/integrate_opendid/index.html new file mode 100644 index 000000000..41967cb19 --- /dev/null +++ b/docs/develop/opendid/integrate_opendid/index.html @@ -0,0 +1,61 @@ + + + + + +Integrate OpenDID | KILT Protocol + + + + +

    Integrate OpenDID

    OpenDID follows the OpenID Connect 1.0 Specification and implements both the implicit flow +and the authorization code flow. +Read the demo project guide for an example of integrating OpenDID.

    +

    Authorization code flow

    +

    Initiate the flow by redirecting to the GET /api/v1/authorize endpoint on the OpenDID service and setting the following query URL-encoded parameters:

    +
      +
    • response_type: set value to code to indicate Authorization Code Flow.
    • +
    • client_id: The client ID set in the config.yaml file.
    • +
    • redirect_uri: OpenDID redirects to this URL after authentication.
    • +
    • scope: set value to openid.
    • +
    • state: set to a secure random number.
    • +
    • nonce: optional value, set to a secure random number.
    • +
    +

    Example:

    +
    GET /api/v1/authorize?
    response_type=code&
    client_id=example-client&
    redirect_uri=http://localhost:1606/callback.html&
    scope=openid&
    state=rkw49cbvd4azu5dsln1xbl&
    nonce=vedur4om49ei8w91jt7wt HTTP/1.1
    +

    After successful authentication, the OpenDID service redirects back to the provided redirect_uri with code and state query parameters.

    +

    Example:

    +
    /callback.html?
    code=lwDS1ZpQBwR4Vdm53_L8bWpUJ1mx9A0mA_-86dubTqzqzwGazx1RyLX4Z_qf&
    state=rkw49cbvd4azu5dsln1xbl
    +

    You can retrieve the id_token by calling the POST /api/v1/token and providing the following values in the form serialization:

    +
      +
    • code: code value returned from authorize.
    • +
    • grant_type: set value to authorization_code.
    • +
    • redirect_uri: the same redirect_uri used in authorize.
    • +
    • client_id: the client ID set in the config.yaml file.
    • +
    • client_secret: the client secret value set in the config.yaml file.
    • +
    +

    Example:

    +
    POST /api/v1/token HTTP/1.1
    Content-Type: application/x-www-form-urlencoded

    code=lwDS1ZpQBwR4Vdm53_L8bWpUJ1mx9A0mA_-86dubTqzqzwGazx1RyLX4Z_qf&
    grant_type=authorization_code&
    redirect_uri=http%3A%2F%2Flocalhost%3A1606%2Fcallback.html&
    client_id=example-client&
    client_secret=insecure_client_secret
    +

    The OpenDID service returns the id_token in the response body serialized as a JSON object.

    +
    {
    "access_token": "SsFhhSBMWsLeDMxVUVGreKARNwYxMZtGFfBr0-ZiH6iondSmwPRvQDqkG6Fh",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4MTYwNjQsImlhdCI6MTcxNjgxNTQ2NCwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXV0aGVudGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoidmVkdXI0b200OWVpOHc5MWp0N3d0In0.yOmE_9jWKcAu8LpjVx7IsFyOOvlKbgo2oC4Imf-qrLY",
    "id_token": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4MTU1MjQsImlhdCI6MTcxNjgxNTQ2NCwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXBwbGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoidmVkdXI0b200OWVpOHc5MWp0N3d0In0.YlRE9EGnSExQCb5m2iy4__58PZJlZdCZMsSvsuW4oj8"
    }
    +
    note

    In full-stack applications, calling the token endpoint is usually done through the back end to improve security.

    +

    The id_token is a bearer JSON web token (JWT) signed by the JWT key-pair specified in the config.yaml file of the OpenDID service. +You must verify this using the JWT public key, for example, by the back end of the Web app.

    +

    Implicit flow

    +

    Initiate the flow by redirecting to the GET /api/v1/authorize endpoint on the OpenDID Service and setting the following query parameters:

    +
      +
    • response_type: set value to id_token to indicate Implicit Flow.
    • +
    • client_id: The client ID set in the config.yaml file.
    • +
    • redirect_uri: OpenDID redirects to this URL after authentication.
    • +
    • scope: set value to openid.
    • +
    • state: set to a secure random number.
    • +
    • nonce: optional value, set to a secure random number.
    • +
    +

    Example:

    +
    GET /api/v1/authorize?
    response_type=id_token&
    client_id=example-client&
    redirect_uri=http://localhost:1606/callback.html&
    scope=openid&
    state=o0fl4c9gwylymzw5f4ik&
    nonce=ia7sa06ungxdfzaqphk2 HTTP/1.1
    +

    After successful authentication, OpenDID redirects back to the provided redirect_uri with id_token and state +fragment components.

    +

    Example:

    +
    /callback.html#
    id_token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4ODQ5MDYsImlhdCI6MTcxNjg4NDg0NiwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXBwbGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoiOTFzN2ZnZDZvcjR3c2NkdGVtcXQifQ.xTy3Oyc5e-vlP10mGy0f9GqNU4LV97s77s-l7w5EwF0&
    refresh_token=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkaWQ6a2lsdDo0b0VkNENVV3RwbkxUVnZENVBFd2lMUmlqMWdzQmprS1JMbVpES2lCOEdqN2I2V0wiLCJ3M24iOiJjdXN0b20iLCJleHAiOjE3MTY4ODU0NDYsImlhdCI6MTcxNjg4NDg0NiwiaXNzIjoiZGlkOmtpbHQ6NHJzQkE3dEQ1S1E4TDlXSGpGallRdUhrTWtha2NmSGRDNUNhUVVjVXh5VWpEVkhBIiwiYXVkIjoiYXV0aGVudGljYXRpb24iLCJwcm8iOnsiRW1haWwiOiJhYmR1bEBraWx0LmlvIn0sIm5vbmNlIjoiOTFzN2ZnZDZvcjR3c2NkdGVtcXQifQ.87UHGid3OotxO8Wpfuw-1sc5fsQJVt5gc2cqp9dVHiw&
    state=nitctpl7nmqcpvob7xthrw&
    token_type=bearer
    + + \ No newline at end of file diff --git a/docs/develop/opendid/opendid_service/index.html b/docs/develop/opendid/opendid_service/index.html new file mode 100644 index 000000000..383c908a9 --- /dev/null +++ b/docs/develop/opendid/opendid_service/index.html @@ -0,0 +1,103 @@ + + + + + +Run OpenDID Service | KILT Protocol + + + + +

    Run OpenDID Service

    Configuration

    +

    Running the OpenDID service requires some configuration and a KILT DID. +The DID establishes a secure session with an identity wallet using a key agreement key of type X25519KeyAgreementKey2019 included in the DID Document generated by the setup container.

    +

    OpenDID serves a well-known DID configuration, which the identity wallet uses to ensure that the domain is linked to the specified DID.

    +

    Run setup container

    +

    Before running the opendid-setup container, set two environment variables:

    +
      +
    1. +

      SEED to provide an account with funds (minimum of 3 KILT) for the DID generation.

      +
      export SEED="dont try this seed its completely made up for this nice example"
      +
    2. +
    3. +

      ENDPOINT

      +

      Set to "spiritnet" if the account is on the spiritnet production network.

      +
      export ENDPOINT="spiritnet"
      +

      Set to "peregrine" if the account is on the peregrine test network.

      +
      export ENDPOINT="peregrine"
      +

      Then run the setup with the following command:

      +
      docker run --rm -it -e "ENDPOINT=${ENDPOINT}" -v $(pwd):/data docker.io/kiltprotocol/opendid-setup:latest "${SEED}"
      +
    4. +
    +

    The command generates a set of new mnemonics and then derives a DID from them and generates multiple files into the current directory:

    +
      +
    1. +

      config.yaml The configuration file used by the OpenDID service.

      +
      warning

      You only need the config.yaml to run the OpenDID service. +This file includes the generated mnemonic and secret keys and you should protect it from unauthorized access.

      +
    2. +
    3. +

      did-secrets.json This file contains the public and secret keys in the DID Document.

      +
      warning

      Keep a secure backup of this file as it contains all the secret keys.

      +
    4. +
    5. +

      did-document.json contains the DID Document generated by this setup.

      +
    6. +
    +

    The container generates sensible defaults in the config.yaml file, but here are some values you might want to change:

    +
      +
    • +

      Set production to true, this only allows secure connections.

      +
    • +
    • +

      Set the WellKnownDid > origin, which should match the host running the OpenDID service.

      +
    • +
    • +

      Set the keys used for JWT issuance in the jwt section.

      +
    • +
    • +

      The client section, including:

      +
        +
      • The client ID as a key (The default is: example-client).
      • +
      • The requirements section, including: +
          +
        • +

          What CTypes are required for authentication.

          +
        • +
        • +

          The trusted attesters as an address (The default is for the SocialKYC attester).

          +
          info

          The generated default config.yaml requires an email credential issued by an attester.

          +
        • +
        • +

          What redirect_urls the service accepts (The default is http://localhost:1606/callback.html for the demo project).

          +
        • +
        • +

          The clientSecret is optional but recommended. If you use the authorization code flow, the token endpoint requires it.

          +
        • +
        +
      • +
      +
    • +
    +

    Run the service

    +

    When you've made changes to the config.yaml file, you can run the OpenDID service.

    +
      +
    1. +

      Specify the runtime through the RUNTIME environment variable:

      +

      Set to "spiritnet" for production KILT

      +
      export RUNTIME="spiritnet"
      +

      Set to "peregrine" for the KILT test net.

      +
      export RUNTIME="peregrine"
      +
    2. +
    3. +

      Run the docker.io/kiltprotocol/opendid docker image.

      +
      docker run -d --rm \
      -v $(pwd)/config.yaml:/app/config.yaml \
      -v $(pwd)/checks:/app/checks \
      -e "RUNTIME=${RUNTIME}" \
      -p 3001:3001 \
      docker.io/kiltprotocol/opendid:latest
      +
    4. +
    5. +

      Open the login page at http://localhost:3001.

      +
    6. +
    +

    Next steps

    +

    With configuration in place and a service running, next you need to integrate OpenDID into an application so that a user can use the login page.

    + + \ No newline at end of file diff --git a/docs/develop/opendid/what-is-opendid/index.html b/docs/develop/opendid/what-is-opendid/index.html new file mode 100644 index 000000000..688a9765e --- /dev/null +++ b/docs/develop/opendid/what-is-opendid/index.html @@ -0,0 +1,30 @@ + + + + + +Overview | KILT Protocol + + + + +

    Overview

    OpenDID is an OpenID Provider implementation capable of authenticating users through their Decentralized Identifier (DID) and Verifiable Credentials.

    +

    It follows the OpenID Connect 1.0 Specification and acts as a bridge between the decentralized identity world and the centralized authentication world supporting both the implicit and Authorization Code Flow.

    +

    A major use of OpenDID is Single Sign-On (SSO), which allows users to use the same DID and credentials to sign into multiple platforms and web services. For instance, by adding a "Sign in with KILT" button to a webpage.

    +

    Although integrating that functionality into a webpage is relatively simple, configuring and running OpenDID is more involved.

    +
    info

    To learn more about the flow of OpenDID, see the OpenDID Flow documentation.

    +

    Project container structure

    +

    The project consist of multiple parts that supplement and interact with each other all shipped as Docker containers and released to Docker Hub.

    +

    opendid-setup container

    +

    The OpenDID Service needs configuration to run, which you can apply using this +container. +For example, it requires a DID to establish a session with an identity wallet. +This container creates a DID and the necessary configuration by providing an account with enough funds.

    +

    Learn more in the run setup container documentation.

    +

    kiltprotocol/opendid container

    +

    This container runs the OpenDID Service, both the OpenDID front and back end. +This container requires the configuration file created from the opendid-setup container.

    +

    kiltprotocol/opendid-demo

    +

    This container is a web app demo, including front and back end services to demonstrate the use of OpenDID.

    + + \ No newline at end of file diff --git a/docs/develop/sdk/chain_setup/index.html b/docs/develop/sdk/chain_setup/index.html index a25f4b012..662f98673 100644 --- a/docs/develop/sdk/chain_setup/index.html +++ b/docs/develop/sdk/chain_setup/index.html @@ -4,11 +4,11 @@ Chain Setup for Development | KILT Protocol - - + + -

    Chain Setup for Development

    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. +

    Chain Setup for Development

    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. For that purpose, you can either use the public KILT Peregrine testnet or run your own development blockchain.

    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. Any new features that we plan to add to our Spiritnet runtime will first undergo a testing period on Peregrine. @@ -23,6 +23,6 @@

    Set up your Project

    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. -If that is not the case, please take a look at our Quickstart section which will provide you with all necessary means to create and run a basic script.

    +If that is not the case, please take a look at our Quickstart section which will provide you with all necessary means to create and run a basic script.

    \ No newline at end of file diff --git a/docs/develop/sdk/chain_setup/peregrine-chain-setup/index.html b/docs/develop/sdk/chain_setup/peregrine-chain-setup/index.html index da49cedf3..61c961243 100644 --- a/docs/develop/sdk/chain_setup/peregrine-chain-setup/index.html +++ b/docs/develop/sdk/chain_setup/peregrine-chain-setup/index.html @@ -4,11 +4,11 @@ Connect to Peregrine | KILT Protocol - - + + -

    Connect to Peregrine

    Before connecting to the production Spiritnet, it is recommended to test applications using its canary network Peregrine. +

    Connect to Peregrine

    Before connecting to the production Spiritnet, it is recommended to test applications using its canary network Peregrine. In contrast to running your own blockchain, you will neither have control over the blockchain, nor have any initial funds.

    In this section we will guide you through the process of receiving funds on Peregrine and connecting to one of the network nodes. Additionally, we explain the difference between the Standalone and Parachain runtimes.

    @@ -18,6 +18,6 @@

    Conne

    Replace the WebSocket address of your script or application with wss://peregrine.kilt.io.

    You can either use your own frontend or the Polkadot JS Apps to interact with the chain. Moreover, you can use Subscan as a chain explorer. -For a full list of deployments and services, take a look here.

    +For a full list of deployments and services, take a look here.

    \ No newline at end of file diff --git a/docs/develop/sdk/chain_setup/prod-chain-setup/index.html b/docs/develop/sdk/chain_setup/prod-chain-setup/index.html index e9e794cd4..bf38f7cc9 100644 --- a/docs/develop/sdk/chain_setup/prod-chain-setup/index.html +++ b/docs/develop/sdk/chain_setup/prod-chain-setup/index.html @@ -4,11 +4,11 @@ Connect to Spiritnet | KILT Protocol - - + + -

    Connect to Spiritnet

    For production setups it is important to run your own full node. +

    Connect to Spiritnet

    For production setups it is important to run your own full node. Running your own full node has several advantages over relying on a public full node.

    The most important advantage is security. You rely on the full node to provide you with correct data. @@ -21,6 +21,6 @@

    Conne

    Replace the WebSocket address of your script or application with wss://kilt-rpc.dwellir.com.

    You can either use your own frontend or the Polkadot JS Apps to interact with the chain. Moreover, you can use Subscan as a chain explorer. -For a full list of deployments and services, see here.

    +For a full list of deployments and services, see here.

    \ No newline at end of file diff --git a/docs/develop/sdk/chain_setup/standalone-chain-setup/index.html b/docs/develop/sdk/chain_setup/standalone-chain-setup/index.html index 8cdfe06ac..f9c1088a6 100644 --- a/docs/develop/sdk/chain_setup/standalone-chain-setup/index.html +++ b/docs/develop/sdk/chain_setup/standalone-chain-setup/index.html @@ -4,11 +4,11 @@ BYOB - Bring Your Own Blockchain | KILT Protocol - - + + -

    BYOB - Bring Your Own Blockchain

    If you want to have full control over your blockchain deployment, e.g., if you want to reset the state repeatedly or need more funds than a faucet can provide for a single account, you will need to run your own blockchain. +

    BYOB - Bring Your Own Blockchain

    If you want to have full control over your blockchain deployment, e.g., if you want to reset the state repeatedly or need more funds than a faucet can provide for a single account, you will need to run your own blockchain. For this purpose, we provide a Docker image which runs in standalone mode. This means that the blockchain doesn't act as a parachain but as an independent chain. There is no need to run a Relay Chain and register the KILT chain as a parachain. @@ -58,6 +58,6 @@

    Transac

    Before transactions are sent to the chain, they are encoded and signed. The encoding depends on the runtime and can differ from chain to chain. Even the same call in the same pallet can have a different encoding for different chains, for instance, the vest()call of thevesting` pallet:

    -
    ChainEncoding of Vesting.vest()
    Spiritnet0x2900
    Standalone0x2100

    +
    ChainEncoding of Vesting.vest()
    Spiritnet0x2900
    Standalone0x2100
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/account_linking/account-link/index.html b/docs/develop/sdk/cookbook/account_linking/account-link/index.html index 75d0f3140..784949491 100644 --- a/docs/develop/sdk/cookbook/account_linking/account-link/index.html +++ b/docs/develop/sdk/cookbook/account_linking/account-link/index.html @@ -4,11 +4,11 @@ Link an Account to a KILT DID | KILT Protocol - - + + -

    Link an Account to a KILT DID

    Sometimes there is the need to link a DID to an account publicly. +

    Link an Account to a KILT DID

    Sometimes there is the need to link a DID to an account publicly. The link makes it possible to lookup a DID for an account. The other directions is also possible. With a DID you can lookup a list of linked account.

    @@ -35,6 +35,6 @@

    The proof contains the DID that the account will be linked to and an expiration date (in terms of blocks), to prevent replay attacks. The proof will only be valid up until the blocknumber is reached.

    With this option you can link addresses that are supported by the Spiritnet blockchain (Sr25519, Ed25519, Ecdsa), but also ethereum addresses.

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function linkAccountToDid(
    did: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    linkedAccount: Kilt.KeyringPair & { type: 'ed25519' | 'sr25519' | 'ecdsa' },
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the parameters for the extrinsic that links account and DID.
    // This will contain the signature of the account that will be linked to the DID
    // and therefore signals the agreement of the account to be linked.
    const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(
    linkedAccount.address,
    did,
    async (payload) => linkedAccount.sign(payload)
    )

    // Afterwards we build the extrinsic using the parameters from above.
    const accountLinkingTx = await api.tx.didLookup.associateAccount(
    ...accountLinkingParameters
    )

    // Next the DID signs the extrinsic.
    // This signals the agreement of the DID owner to be linked to the account.
    const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(
    did,
    accountLinkingTx,
    signCallback,
    submitterAccount.address
    )

    // finally we need to submit everything to the blockchain, so that the link gets
    // registered.
    // This account will provide the required deposit and pay the fees.
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedAccountLinkingTx,
    submitterAccount
    )
    }

    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function linkAccountToDid(
    did: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    linkedAccount: Kilt.KeyringPair & { type: 'ed25519' | 'sr25519' | 'ecdsa' },
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the parameters for the extrinsic that links account and DID.
    // This will contain the signature of the account that will be linked to the DID
    // and therefore signals the agreement of the account to be linked.
    const accountLinkingParameters = await Kilt.Did.associateAccountToChainArgs(
    linkedAccount.address,
    did,
    async (payload) => linkedAccount.sign(payload)
    )

    // Afterwards we build the extrinsic using the parameters from above.
    const accountLinkingTx = await api.tx.didLookup.associateAccount(
    ...accountLinkingParameters
    )

    // Next the DID signs the extrinsic.
    // This signals the agreement of the DID owner to be linked to the account.
    const authorizedAccountLinkingTx = await Kilt.Did.authorizeTx(
    did,
    accountLinkingTx,
    signCallback,
    submitterAccount.address
    )

    // finally we need to submit everything to the blockchain, so that the link gets
    // registered.
    // This account will provide the required deposit and pay the fees.
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedAccountLinkingTx,
    submitterAccount
    )
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/account_linking/account-name/index.html b/docs/develop/sdk/cookbook/account_linking/account-name/index.html index ea2650f60..3e5bf9265 100644 --- a/docs/develop/sdk/cookbook/account_linking/account-name/index.html +++ b/docs/develop/sdk/cookbook/account_linking/account-name/index.html @@ -4,15 +4,15 @@ Query the web3name of an Account | KILT Protocol - - + + -

    Query the web3name of an Account

    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.

    +

    Query the web3name of an Account

    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.

    This section shows how to perform the account -> web3name querying both with and without the support of the KILT SDK.

    Query an Account's web3name with the KILT SDK

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryAccountWeb3Name(
    lookupAccountAddress: Kilt.KiltAddress
    ): Promise<Kilt.Did.Web3Name | null> {
    const api = Kilt.ConfigService.get('api')

    const encodedLinkedDetails = await api.call.did.queryByAccount(
    Kilt.Did.accountToChain(lookupAccountAddress)
    )
    const { web3Name } = Kilt.Did.linkedInfoFromChain(encodedLinkedDetails)
    if (web3Name) {
    console.log(
    `web3name for account "${lookupAccountAddress}" -> "${web3Name}"`
    )
    } else {
    console.log(
    `Account "${lookupAccountAddress}" does not have a linked web3name.`
    )
    }

    return web3Name
    }

    Query an Account's web3name without the KILT SDK

    -
    import type { KeyringPair } from '@polkadot/keyring/types'

    import { ApiPromise, WsProvider } from '@polkadot/api'

    // Import needed to provide KILT Typescript support to the api object.
    import '@kiltprotocol/augment-api'
    import { typesBundle } from '@kiltprotocol/type-definitions'

    export async function queryAccountWeb3Name(
    endpoint: string,
    lookupAccountAddress: KeyringPair['address']
    ): Promise<string | null> {
    const api = await ApiPromise.create({
    provider: new WsProvider(endpoint),
    typesBundle
    })
    // Call to the KILT runtime API `did.queryByAccount`
    const didDetails = await api.call.did.queryByAccount({
    AccountId32: lookupAccountAddress
    })
    if (didDetails.isNone) {
    throw new Error(`No DID for the KILT account "${lookupAccountAddress}".`)
    }

    const { w3n } = didDetails.unwrap()
    if (w3n.isNone) {
    throw new Error(
    `No web3name for the KILT account "${lookupAccountAddress}".`
    )
    }

    const web3Name = w3n.unwrap().toHuman()
    console.log(
    `The provided account is identifiable by the following web3name: "w3n:${web3Name}"`
    )

    return web3Name
    }
    +
    import type { KeyringPair } from '@polkadot/keyring/types'

    import { ApiPromise, WsProvider } from '@polkadot/api'

    // Import needed to provide KILT Typescript support to the api object.
    import '@kiltprotocol/augment-api'
    import { typesBundle } from '@kiltprotocol/type-definitions'

    export async function queryAccountWeb3Name(
    endpoint: string,
    lookupAccountAddress: KeyringPair['address']
    ): Promise<string | null> {
    const api = await ApiPromise.create({
    provider: new WsProvider(endpoint),
    typesBundle
    })
    // Call to the KILT runtime API `did.queryByAccount`
    const didDetails = await api.call.did.queryByAccount({
    AccountId32: lookupAccountAddress
    })
    if (didDetails.isNone) {
    throw new Error(`No DID for the KILT account "${lookupAccountAddress}".`)
    }

    const { w3n } = didDetails.unwrap()
    if (w3n.isNone) {
    throw new Error(
    `No web3name for the KILT account "${lookupAccountAddress}".`
    )
    }

    const web3Name = w3n.unwrap().toHuman()
    console.log(
    `The provided account is identifiable by the following web3name: "w3n:${web3Name}"`
    )

    return web3Name
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/account_linking/account-unlink/index.html b/docs/develop/sdk/cookbook/account_linking/account-unlink/index.html index 7e41b1682..255c081cf 100644 --- a/docs/develop/sdk/cookbook/account_linking/account-unlink/index.html +++ b/docs/develop/sdk/cookbook/account_linking/account-unlink/index.html @@ -4,11 +4,11 @@ Unlink an Account From a KILT DID | KILT Protocol - - + + -

    Unlink an Account From a KILT DID

    Similar to the way a new account to DID link is created, removing a link can happen in one of three ways:

    +

    Unlink an Account From a KILT DID

    Similar to the way a new account to DID link is created, removing a link can happen in one of three ways:

    1. The DID owner submits a transaction indicating which account to unlink:
    @@ -20,6 +20,6 @@
    1. 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:
    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimLinkDeposit(
    submitterAddress: Kilt.KeyringPair,
    linkedAccountAddress: Kilt.KiltAddress
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // The tx does not need to be authorized by a DID, but the deposit payer's account claims the deposit and removes the link.
    const accountUnlinkTx = api.tx.didLookup.reclaimDeposit({
    AccountId32: linkedAccountAddress
    })

    await Kilt.Blockchain.signAndSubmitTx(accountUnlinkTx, submitterAddress)
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimLinkDeposit(
    submitterAddress: Kilt.KeyringPair,
    linkedAccountAddress: Kilt.KiltAddress
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // The tx does not need to be authorized by a DID, but the deposit payer's account claims the deposit and removes the link.
    const accountUnlinkTx = api.tx.didLookup.reclaimDeposit({
    AccountId32: linkedAccountAddress
    })

    await Kilt.Blockchain.signAndSubmitTx(accountUnlinkTx, submitterAddress)
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/claiming/attestation-creation/index.html b/docs/develop/sdk/cookbook/claiming/attestation-creation/index.html index 579340257..2fbd13d1b 100644 --- a/docs/develop/sdk/cookbook/claiming/attestation-creation/index.html +++ b/docs/develop/sdk/cookbook/claiming/attestation-creation/index.html @@ -4,15 +4,15 @@ Attest a Claim (Issue a Credential) | KILT Protocol - - + + -

    Attest a Claim (Issue a Credential)

    Once an Attester has received a to-be-attested Credential from a Claimer, they will typically verify the information in the claim. +

    Attest a Claim (Issue a Credential)

    Once an Attester has received a to-be-attested Credential from a Claimer, they will typically verify the information in the claim. 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. 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.

    info

    An Attester is required to have a full DID with an attestation key. To see how to manage DIDs, please refer to the DID section.

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function createAttestation(
    attester: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback,
    credential: Kilt.ICredential
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Create an attestation object and write its root hash on the chain
    // using the provided attester's full DID.
    const { cTypeHash, claimHash, delegationId } =
    Kilt.Attestation.fromCredentialAndDid(credential, attester)

    // Write the attestation info on the chain.
    const attestationTx = api.tx.attestation.add(
    claimHash,
    cTypeHash,
    delegationId
    )
    const authorizedAttestationTx = await Kilt.Did.authorizeTx(
    attester,
    attestationTx,
    signCallback,
    submitterAccount.address
    )
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedAttestationTx,
    submitterAccount
    )
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function createAttestation(
    attester: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback,
    credential: Kilt.ICredential
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Create an attestation object and write its root hash on the chain
    // using the provided attester's full DID.
    const { cTypeHash, claimHash, delegationId } =
    Kilt.Attestation.fromCredentialAndDid(credential, attester)

    // Write the attestation info on the chain.
    const attestationTx = api.tx.attestation.add(
    claimHash,
    cTypeHash,
    delegationId
    )
    const authorizedAttestationTx = await Kilt.Did.authorizeTx(
    attester,
    attestationTx,
    signCallback,
    submitterAccount.address
    )
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedAttestationTx,
    submitterAccount
    )
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/claiming/attestation-removal/index.html b/docs/develop/sdk/cookbook/claiming/attestation-removal/index.html index 320e5fc28..95eb77c27 100644 --- a/docs/develop/sdk/cookbook/claiming/attestation-removal/index.html +++ b/docs/develop/sdk/cookbook/claiming/attestation-removal/index.html @@ -4,16 +4,16 @@ Revoke a Credential | KILT Protocol - - + + -

    Revoke a Credential

    If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain. +

    Revoke a Credential

    If the conditions that make a credential valid cease to exist, an Attester can revoke and optionally remove their attestation from the KILT blockchain. 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.

    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.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function revokeCredential(
    attester: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback,
    credential: Kilt.ICredential,
    shouldRemove = false
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    const tx = shouldRemove
    ? // If the attestation is to be removed, create a `remove` tx,
    // which revokes and removes the attestation in one go.
    api.tx.attestation.remove(credential.rootHash, null)
    : // Otherwise, simply revoke the attestation but leave it on chain.
    // Hence, the storage is not cleared and the deposit not returned.
    api.tx.attestation.revoke(credential.rootHash, null)

    const authorizedTx = await Kilt.Did.authorizeTx(
    attester,
    tx,
    signCallback,
    submitterAccount.address
    )

    // Submit the right tx to the KILT blockchain.
    await Kilt.Blockchain.signAndSubmitTx(authorizedTx, submitterAccount)
    }

    Claim Back an Attestation Deposit

    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:

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimAttestationDeposit(
    submitterAddress: Kilt.KiltKeyringPair,
    credential: Kilt.ICredential
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the tx to claim the deposit back.
    const depositReclaimTx = api.tx.attestation.reclaimDeposit(
    credential.rootHash
    )

    // Submit the revocation tx to the KILT blockchain.
    await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress)
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimAttestationDeposit(
    submitterAddress: Kilt.KiltKeyringPair,
    credential: Kilt.ICredential
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the tx to claim the deposit back.
    const depositReclaimTx = api.tx.attestation.reclaimDeposit(
    credential.rootHash
    )

    // Submit the revocation tx to the KILT blockchain.
    await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress)
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/claiming/attestation-request/index.html b/docs/develop/sdk/cookbook/claiming/attestation-request/index.html index 8ab5d1332..ae1fff10e 100644 --- a/docs/develop/sdk/cookbook/claiming/attestation-request/index.html +++ b/docs/develop/sdk/cookbook/claiming/attestation-request/index.html @@ -4,15 +4,15 @@ Request an Attestation | KILT Protocol - - + + -

    Request an Attestation

    To obtain credentials, Claimers have to request an attestation for a set of claims from an Attester. +

    Request an Attestation

    To obtain credentials, Claimers have to request an attestation for a set of claims from an Attester. The resulting object is a Credential, which can be created following the snippet below.

    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.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export function requestAttestation(
    claimer: Kilt.DidDocument,
    ctype: Kilt.ICType
    ): Kilt.ICredential {
    // The claimer generates the claim they would like to get attested.
    const claim = Kilt.Claim.fromCTypeAndClaimContents(
    ctype,
    {
    name: 'Alice',
    age: 29,
    id: '123456789987654321'
    },
    claimer.uri
    )

    const credential = Kilt.Credential.fromClaim(claim)
    return credential
    }
    note

    The structure of the claims must respect the schema defined in the specified CType. -Attesters (and Verifiers) will reject claims that fail to verify correctly.

    +Attesters (and Verifiers) will reject claims that fail to verify correctly.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/claiming/ctype-creation/index.html b/docs/develop/sdk/cookbook/claiming/ctype-creation/index.html index 10a2842e6..0f5d5ba6d 100644 --- a/docs/develop/sdk/cookbook/claiming/ctype-creation/index.html +++ b/docs/develop/sdk/cookbook/claiming/ctype-creation/index.html @@ -4,11 +4,11 @@ Create a CType | KILT Protocol - - + + -

    Create a CType

    Every KILT credential has to conform to a CType. +

    Create a CType

    Every KILT credential has to conform to a CType. A CType describes which properties a credential has and what type these properties have. CTypes must be registered on the Spiritnet blockchain. To learn more about CTypes, see the CType concept section.

    @@ -22,6 +22,6 @@

    Retrieve a CType from its ID

    CTypes can be queried directly from any KILT archive nodes. The following example shows how to query a CType using the SDK:

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function fetchCType(
    ctypeId: Kilt.ICType['$id']
    ): Promise<Kilt.CType.ICTypeDetails> {
    // Example CType ID: kilt:ctype:0x329a2a5861ea63c250763e5e4c4d4a18fe4470a31e541365c7fb831e5432b940
    return Kilt.CType.fetchFromChain(ctypeId)
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function fetchCType(
    ctypeId: Kilt.ICType['$id']
    ): Promise<Kilt.CType.ICTypeDetails> {
    // Example CType ID: kilt:ctype:0x329a2a5861ea63c250763e5e4c4d4a18fe4470a31e541365c7fb831e5432b940
    return Kilt.CType.fetchFromChain(ctypeId)
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/claiming/presentation-creation/index.html b/docs/develop/sdk/cookbook/claiming/presentation-creation/index.html index 0b6a37d8d..ea8e71ee7 100644 --- a/docs/develop/sdk/cookbook/claiming/presentation-creation/index.html +++ b/docs/develop/sdk/cookbook/claiming/presentation-creation/index.html @@ -4,11 +4,11 @@ Present a Credential | KILT Protocol - - + + -

    Present a Credential

    With a valid credential, Claimers can now go to Verifiers to request some service upon providing proof of validity of a certain credential. +

    Present a Credential

    With a valid credential, Claimers can now go to Verifiers to request some service upon providing proof of validity of a certain credential. The process of presenting one or more credentials to a Verifier is called Presentation.

    This step, similar to the attestation request, requires that a communication channel exist between the Claimer and the Verifier so that information about the presentation can be shared. To verify the revocation status of the presented credential(s), a Verifier must be able to interact with a KILT full node.

    @@ -16,6 +16,6 @@ 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. Check the snippet below to see how that is done using the KILT SDK.

    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.

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function createPresentation(
    credential: Kilt.ICredential,
    signCallback: Kilt.SignCallback,
    selectedAttributes?: string[],
    challenge?: string
    ): Promise<Kilt.ICredentialPresentation> {
    // Create a presentation with only the specified fields revealed, if specified.
    return Kilt.Credential.createPresentation({
    credential,
    signCallback,
    selectedAttributes,
    challenge
    })
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function createPresentation(
    credential: Kilt.ICredential,
    signCallback: Kilt.SignCallback,
    selectedAttributes?: string[],
    challenge?: string
    ): Promise<Kilt.ICredentialPresentation> {
    // Create a presentation with only the specified fields revealed, if specified.
    return Kilt.Credential.createPresentation({
    credential,
    signCallback,
    selectedAttributes,
    challenge
    })
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/claiming/presentation-verification/index.html b/docs/develop/sdk/cookbook/claiming/presentation-verification/index.html index 10bb985f8..57567a18b 100644 --- a/docs/develop/sdk/cookbook/claiming/presentation-verification/index.html +++ b/docs/develop/sdk/cookbook/claiming/presentation-verification/index.html @@ -4,11 +4,11 @@ Verify a Credential or a Presentation | KILT Protocol - - + + -

    Verify a Credential or a Presentation

    Whether a presentation involves selective disclosure or a whole credential is not technically relevant to Verifiers. +

    Verify a Credential or a Presentation

    Whether a presentation involves selective disclosure or a whole credential is not technically relevant to Verifiers. This is because in KILT a presentation is a credential. 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:

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function verifyPresentation(
    presentation: Kilt.ICredentialPresentation,
    {
    challenge,
    trustedAttesterUris = []
    }: {
    challenge?: string
    trustedAttesterUris?: Kilt.DidUri[]
    } = {}
    ): Promise<void> {
    // Verify the presentation with the provided challenge.
    const { revoked, attester } = await Kilt.Credential.verifyPresentation(
    presentation,
    { challenge }
    )

    if (revoked) {
    throw new Error("Credential has been revoked and hence it's not valid.")
    }
    if (!trustedAttesterUris.includes(attester)) {
    throw `Credential was issued by ${attester} which is not in the provided list of trusted attesters: ${trustedAttesterUris}.`
    }
    }
    @@ -16,6 +16,6 @@ Verifiers still need to match the subject of the credential to the entity that is presenting it. One way of achieving this is by asking the Claimer to include a challenge in the presentation signature, as shown in the snippet above. Without a challenge, Verifiers must implement other measures to be certain about the identity of the presenter.

    -
    Evaluation of the attester's trust is up to the Verifiers

    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.

    +
    Evaluation of the attester's trust is up to the Verifiers

    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.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/did-export/index.html b/docs/develop/sdk/cookbook/dids/did-export/index.html index df21ec39e..0323e1278 100644 --- a/docs/develop/sdk/cookbook/dids/did-export/index.html +++ b/docs/develop/sdk/cookbook/dids/did-export/index.html @@ -4,16 +4,16 @@ Exporting a KILT DID | KILT Protocol - - + + -

    Exporting a KILT DID

    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. +

    Exporting a KILT DID

    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. This component is required for the KILT plugin for the DIF Universal Resolver.

    How to use the exporter

    The exporter interface and used types are part of the @kiltprotocol/types package, while the actual DidDocumentExporter is part of the @kiltprotocol/did package. Both types and DID packages are accessible via the top-level @kiltprotocol/sdk-js import. 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.

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function exportDid(
    did: Kilt.DidDocument,
    exportType: 'application/json' | 'application/ld+json'
    ) {
    const conformingDidDocument = Kilt.Did.exportToDidDocument(did, exportType)

    // Will print the DID URI.
    console.log(conformingDidDocument.id)

    // Will print all the public keys associated with the DID.
    console.log(conformingDidDocument.verificationMethod)

    // Will print all the assertion keys IDs.
    console.log(conformingDidDocument.assertionMethod)

    // Will print all the encryption keys IDs.
    console.log(conformingDidDocument.keyAgreement)

    // Will print all the delegation keys IDs.
    console.log(conformingDidDocument.capabilityDelegation)

    // Will print all the external services referenced inside the `DidDocument` instance.
    console.log(conformingDidDocument.service)

    return conformingDidDocument
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function exportDid(
    did: Kilt.DidDocument,
    exportType: 'application/json' | 'application/ld+json'
    ) {
    const conformingDidDocument = Kilt.Did.exportToDidDocument(did, exportType)

    // Will print the DID URI.
    console.log(conformingDidDocument.id)

    // Will print all the public keys associated with the DID.
    console.log(conformingDidDocument.verificationMethod)

    // Will print all the assertion keys IDs.
    console.log(conformingDidDocument.assertionMethod)

    // Will print all the encryption keys IDs.
    console.log(conformingDidDocument.keyAgreement)

    // Will print all the delegation keys IDs.
    console.log(conformingDidDocument.capabilityDelegation)

    // Will print all the external services referenced inside the `DidDocument` instance.
    console.log(conformingDidDocument.service)

    return conformingDidDocument
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/did-query/index.html b/docs/develop/sdk/cookbook/dids/did-query/index.html index 5bd7c6c74..b69456963 100644 --- a/docs/develop/sdk/cookbook/dids/did-query/index.html +++ b/docs/develop/sdk/cookbook/dids/did-query/index.html @@ -4,15 +4,15 @@ Resolve a DID | KILT Protocol - - + + -

    Resolve a DID

    Querying the state of a DID is called resolution. +

    Resolve a DID

    Querying the state of a DID is called resolution. The entity that queries the DID Document for a given DID, i.e., resolves it, is called a resolver.

    The KILT SDK provides such a resolver to use with KILT DIDs, as the snippet below shows:

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryFullDid(
    didUri: Kilt.DidUri
    ): Promise<Kilt.DidDocument | null> {
    const { metadata, document } = await Kilt.Did.resolve(didUri)
    if (metadata.deactivated) {
    console.log(`DID ${didUri} has been deleted.`)
    return null
    } else if (document === undefined) {
    console.log(`DID ${didUri} does not exist.`)
    return null
    } else {
    return document
    }
    }
    note

    The DID resolver can resolve both light and full DIDs. -For a more in-depth explanation about the KILT DID method and resolution, refer to our specification.

    +For a more in-depth explanation about the KILT DID method and resolution, refer to our specification.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/did-signature/index.html b/docs/develop/sdk/cookbook/dids/did-signature/index.html index 84bcc26ab..f4afe04bd 100644 --- a/docs/develop/sdk/cookbook/dids/did-signature/index.html +++ b/docs/develop/sdk/cookbook/dids/did-signature/index.html @@ -4,17 +4,17 @@ Generate and Verify a DID Signature | KILT Protocol - - + + -

    Generate and Verify a DID Signature

    In addition to being used to authorize chain operations, both light and full DIDs have off-chain applications.

    +

    Generate and Verify a DID Signature

    In addition to being used to authorize chain operations, both light and full DIDs have off-chain applications.

    One such applications is generating digital signatures. As a DID can have multiple keys, in addition to the signature data itself, a DID signature contains information about the signer's DID and key used, so that Verifiers have all the information needed to resolve the DID from the KILT blockchain and use the right key to verify the generated signature.

    The snippet below shows how to generate and verify a DID signature using the KILT SDK.

    import * as Kilt from '@kiltprotocol/sdk-js'

    type KeyLookup = (parameter: {
    didUri: Kilt.DidUri
    keyRelationship: Kilt.VerificationKeyRelationship
    }) => Promise<{
    key: Kilt.KiltKeyringPair
    keyType: Kilt.VerificationKeyType
    keyUri: Kilt.DidResourceUri
    }>

    export async function generateAndVerifyDidAuthenticationSignature(
    did: Kilt.DidDocument,
    payload: Uint8Array,
    keyLookup: KeyLookup
    ): Promise<void> {
    // How the key is looked up depends on where the key is stored (e.g. memory, hardware wallet, browser extension)
    const { key, keyUri } = await keyLookup({
    didUri: did.uri,
    keyRelationship: 'authentication'
    })

    // Generate a signature using the key that we just looked up.
    const signature = key.sign(payload)

    // Print the generated signature object.
    console.log('Generated signature:')
    console.log(Kilt.Utils.Crypto.u8aToHex(signature))

    // Verify the validity of the signature using the DID's authentication public key.
    // It throws if the signature cannot be verified.
    await Kilt.Did.verifyDidSignature({
    message: payload,
    signature,
    keyUri,
    expectedVerificationMethod: 'authentication'
    })
    }
    note

    Notice that the snippet above takes a DidDocument instance to generate the signature. A DidDocument can represent either a light or a full DID. -This means that both light and full DIDs can generate signatures, and the KILT SDK implements the right verification logic depending on whether the signer is a light or a full DID.

    +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.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/full-did-batch/index.html b/docs/develop/sdk/cookbook/dids/full-did-batch/index.html index 17d558a3a..319cdc94e 100644 --- a/docs/develop/sdk/cookbook/dids/full-did-batch/index.html +++ b/docs/develop/sdk/cookbook/dids/full-did-batch/index.html @@ -4,11 +4,11 @@ Build DID Extrinsics | KILT Protocol - - + + -

    Build DID Extrinsics

    DID keys can be used to sign extrinsic. +

    Build DID Extrinsics

    DID keys can be used to sign extrinsic. But not every extrinsic can be signed using a DID. The Spiritnet blockchain offers two types of extrinsics.

    The first type can only be called using an account. @@ -43,6 +43,6 @@

    Ba
    import * as Kilt from '@kiltprotocol/sdk-js'
    // Just a helper to get an extrinsic
    import getExtrinsic from '../utils/getExtrinsic'

    export async function signAndSubmitDidExtrinsicBatch(
    submitterAccount: Kilt.KiltKeyringPair,
    fullDid: Kilt.DidUri,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Build two extrinsics
    const extrinsic1 = getExtrinsic()
    const extrinsic2 = getExtrinsic()

    // Create the DID-signed batch.
    const authorizedBatch = await Kilt.Did.authorizeBatch({
    batchFunction: api.tx.utility.batchAll,
    did: fullDid,
    extrinsics: [extrinsic1, extrinsic2],
    sign: signCallback,
    submitter: submitterAccount.address
    })

    // Wrap the DID extrinsic in an account extrinsic.
    await Kilt.Blockchain.signAndSubmitTx(authorizedBatch, submitterAccount)
    }

    DIDs have different keys that posses different capabilities. Each key can only be used to authorize a specific subset of extrinsics. -If extrinsics are batched together that require different DID keys, the authorizeBatch function will call the sign callback multiple times.

    +If extrinsics are batched together that require different DID keys, the authorizeBatch function will call the sign callback multiple times.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/full-did-creation/index.html b/docs/develop/sdk/cookbook/dids/full-did-creation/index.html index ed8720507..7b82f35d2 100644 --- a/docs/develop/sdk/cookbook/dids/full-did-creation/index.html +++ b/docs/develop/sdk/cookbook/dids/full-did-creation/index.html @@ -4,11 +4,11 @@ Create a Full DID | KILT Protocol - - + + -

    Create a Full DID

    The following is an example of how to create and write on the blockchain a full DID that specifies only an authentication key.

    +

    Create a Full DID

    The following is an example of how to create and write on the blockchain a full DID that specifies only an authentication key.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function createSimpleFullDid(
    submitterAccount: Kilt.KiltKeyringPair,
    {
    authentication
    }: {
    authentication: Kilt.NewDidVerificationKey
    },
    signCallback: Kilt.Did.GetStoreTxSignCallback
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    // Generate the DID-signed creation tx and submit it to the blockchain with the specified account.
    // The submitter account parameter, ensures that only an entity authorized by the DID subject
    // can submit the tx to the KILT blockchain.
    const fullDidCreationTx = await Kilt.Did.getStoreTx(
    {
    authentication: [authentication]
    },
    submitterAccount.address,
    signCallback
    )

    await Kilt.Blockchain.signAndSubmitTx(fullDidCreationTx, submitterAccount)

    // The new information is fetched from the blockchain and returned.
    const fullDid = Kilt.Did.getFullDidUriFromKey(authentication)
    const encodedUpdatedDidDetails = await api.call.did.query(
    Kilt.Did.toChain(fullDid)
    )
    return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
    }

    If additional keys or services are to be specified, they can be passed as parameters to the creation transaction.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function createCompleteFullDid(
    submitterAccount: Kilt.KiltKeyringPair,
    {
    authentication,
    keyAgreement,
    assertionMethod,
    capabilityDelegation
    }: {
    authentication: Kilt.NewDidVerificationKey
    keyAgreement: Kilt.NewDidEncryptionKey
    assertionMethod: Kilt.NewDidVerificationKey
    capabilityDelegation: Kilt.NewDidVerificationKey
    },
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    const fullDidCreationTx = await Kilt.Did.getStoreTx(
    {
    authentication: [authentication],
    keyAgreement: [keyAgreement],
    assertionMethod: [assertionMethod],
    capabilityDelegation: [capabilityDelegation],
    // Example service.
    service: [
    {
    id: '#my-service',
    type: ['service-type'],
    serviceEndpoint: ['https://www.example.com']
    }
    ]
    },
    submitterAccount.address,
    signCallback
    )

    await Kilt.Blockchain.signAndSubmitTx(fullDidCreationTx, submitterAccount)

    // The new information is fetched from the blockchain and returned.
    const fullDid = Kilt.Did.getFullDidUriFromKey(authentication)
    const encodedUpdatedDidDetails = await api.call.did.query(
    Kilt.Did.toChain(fullDid)
    )
    return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
    }
    @@ -17,6 +17,6 @@

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function migrateLightDid(
    lightDid: Kilt.DidDocument,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    // Generate the DID migration tx.
    const migrationTx = await Kilt.Did.getStoreTx(
    lightDid,
    submitterAccount.address,
    signCallback
    )

    // The tx can then be submitted by the authorized account as usual.
    await Kilt.Blockchain.signAndSubmitTx(migrationTx, submitterAccount)

    // The new information is fetched from the blockchain and returned.
    const migratedFullDidUri = Kilt.Did.getFullDidUri(lightDid.uri)
    const encodedUpdatedDidDetails = await api.call.did.query(
    Kilt.Did.toChain(migratedFullDidUri)
    )
    return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
    }

    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function migrateLightDid(
    lightDid: Kilt.DidDocument,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    // Generate the DID migration tx.
    const migrationTx = await Kilt.Did.getStoreTx(
    lightDid,
    submitterAccount.address,
    signCallback
    )

    // The tx can then be submitted by the authorized account as usual.
    await Kilt.Blockchain.signAndSubmitTx(migrationTx, submitterAccount)

    // The new information is fetched from the blockchain and returned.
    const migratedFullDidUri = Kilt.Did.getFullDidUri(lightDid.uri)
    const encodedUpdatedDidDetails = await api.call.did.query(
    Kilt.Did.toChain(migratedFullDidUri)
    )
    return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/full-did-delete/index.html b/docs/develop/sdk/cookbook/dids/full-did-delete/index.html index d2c6cf8e3..81dd548e0 100644 --- a/docs/develop/sdk/cookbook/dids/full-did-delete/index.html +++ b/docs/develop/sdk/cookbook/dids/full-did-delete/index.html @@ -4,17 +4,17 @@ Delete a Full DID | KILT Protocol - - + + -

    Delete a Full DID

    Once a DID is no longer needed, it is recommended to deactivate it by removing it from the KILT blockchain. +

    Delete a Full DID

    Once a DID is no longer needed, it is recommended to deactivate it by removing it from the KILT blockchain. The following snippet shows how to do it:

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function deleteFullDid(
    submitterAccount: Kilt.KiltKeyringPair,
    fullDid: Kilt.DidUri,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Create a DID deletion tx. We specify the number of endpoints currently stored under the DID because
    // of the upper computation limit required by the blockchain runtime.
    const didIdentifier = Kilt.Did.toChain(fullDid)
    const endpointsCountForDid =
    await api.query.did.didEndpointsCount(didIdentifier)
    const didDeletionExtrinsic = api.tx.did.delete(endpointsCountForDid)

    // Sign the DID deletion tx using the DID authentication key.
    // This results in a DID-signed tx that can be then signed and submitted to the KILT blockchain by the account
    // authorized in this operation, Alice in this case.
    const didSignedDeletionExtrinsic = await Kilt.Did.authorizeTx(
    fullDid,
    didDeletionExtrinsic,
    signCallback,
    submitterAccount.address
    )

    await Kilt.Blockchain.signAndSubmitTx(
    didSignedDeletionExtrinsic,
    submitterAccount
    )
    }
    warning

    Please note that once deleted, a full DID becomes unusable and cannot be re-created anymore. This means that all credentials obtained with that DID are no longer valid and must be obtained with a different DID if needed.

    Claim back a DID deposit

    Claiming back the deposit of a DID is semantically equivalent to deactivating and deleting the DID, with the difference that the extrinsic to claim the deposit can only be called by the deposit owner and does not require a signature by the DID subject:

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimFullDidDeposit(
    submitterAddress: Kilt.KiltKeyringPair,
    fullDid: Kilt.DidUri
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the tx to claim the deposit back.
    // It includes the DID identifier for which the deposit needs to be returned
    // and the count of services to provide an upper bound to the computation of the tx execution.
    const identifier = Kilt.Did.toChain(fullDid)
    const endpointsCountForDid = await api.query.did.didEndpointsCount(identifier)
    const depositClaimExtrinsic = api.tx.did.reclaimDeposit(
    identifier,
    endpointsCountForDid
    )

    // The submission will fail if `submitterAddress` is not the owner of the deposit associated with the given DID identifier.
    await Kilt.Blockchain.signAndSubmitTx(depositClaimExtrinsic, submitterAddress)
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimFullDidDeposit(
    submitterAddress: Kilt.KiltKeyringPair,
    fullDid: Kilt.DidUri
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the tx to claim the deposit back.
    // It includes the DID identifier for which the deposit needs to be returned
    // and the count of services to provide an upper bound to the computation of the tx execution.
    const identifier = Kilt.Did.toChain(fullDid)
    const endpointsCountForDid = await api.query.did.didEndpointsCount(identifier)
    const depositClaimExtrinsic = api.tx.did.reclaimDeposit(
    identifier,
    endpointsCountForDid
    )

    // The submission will fail if `submitterAddress` is not the owner of the deposit associated with the given DID identifier.
    await Kilt.Blockchain.signAndSubmitTx(depositClaimExtrinsic, submitterAddress)
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/full-did-update/index.html b/docs/develop/sdk/cookbook/dids/full-did-update/index.html index d89334227..9d23611b0 100644 --- a/docs/develop/sdk/cookbook/dids/full-did-update/index.html +++ b/docs/develop/sdk/cookbook/dids/full-did-update/index.html @@ -4,12 +4,12 @@ Update a Full DID keys and service endpoints | KILT Protocol - - + + -

    Update a Full DID keys and service endpoints

    Once anchored to the KILT blockchain, a full DID can be updated. +

    Update a Full DID keys and service endpoints

    Once anchored to the KILT blockchain, a full DID can be updated. 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.

    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function updateFullDid(
    newAuthKeypair: Kilt.KiltKeyringPair,
    fullDid: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    // Create the tx to update the authentication key.
    const didKeyUpdateTx = api.tx.did.setAuthenticationKey(
    Kilt.Did.publicKeyToChain(newAuthKeypair)
    )
    // Create the tx to remove the service with ID `#my-service`.
    const didServiceRemoveTx = api.tx.did.removeServiceEndpoint(
    Kilt.Did.resourceIdToChain('#my-service')
    )

    // Create the tx to add a new service with ID `#my-new-service`.
    const newServiceEndpointTx = api.tx.did.addServiceEndpoint({
    id: Kilt.Did.resourceIdToChain('#my-new-service'),
    serviceTypes: [Kilt.KiltPublishedCredentialCollectionV1Type],
    urls: ['https://www.new-example.com']
    })

    // Create and sign the DID operation that contains the two (unsigned) txs.
    // This results in a DID-signed tx that can be then signed and submitted to the KILT blockchain by the account
    // authorized in this operation, Alice in this case.
    const authorizedBatchedTxs = await Kilt.Did.authorizeBatch({
    batchFunction: api.tx.utility.batchAll,
    did: fullDid,
    extrinsics: [didKeyUpdateTx, didServiceRemoveTx, newServiceEndpointTx],
    sign: signCallback,
    submitter: submitterAccount.address
    })

    // Submit the DID update tx to the KILT blockchain after signing it with the authorized KILT account.
    await Kilt.Blockchain.signAndSubmitTx(authorizedBatchedTxs, submitterAccount)

    // Get the updated DID Document.
    const encodedUpdatedDidDetails = await api.call.did.query(
    Kilt.Did.toChain(fullDid)
    )
    return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function updateFullDid(
    newAuthKeypair: Kilt.KiltKeyringPair,
    fullDid: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    // Create the tx to update the authentication key.
    const didKeyUpdateTx = api.tx.did.setAuthenticationKey(
    Kilt.Did.publicKeyToChain(newAuthKeypair)
    )
    // Create the tx to remove the service with ID `#my-service`.
    const didServiceRemoveTx = api.tx.did.removeServiceEndpoint(
    Kilt.Did.resourceIdToChain('#my-service')
    )

    // Create the tx to add a new service with ID `#my-new-service`.
    const newServiceEndpointTx = api.tx.did.addServiceEndpoint({
    id: Kilt.Did.resourceIdToChain('#my-new-service'),
    serviceTypes: [Kilt.KiltPublishedCredentialCollectionV1Type],
    urls: ['https://www.new-example.com']
    })

    // Create and sign the DID operation that contains the two (unsigned) txs.
    // This results in a DID-signed tx that can be then signed and submitted to the KILT blockchain by the account
    // authorized in this operation, Alice in this case.
    const authorizedBatchedTxs = await Kilt.Did.authorizeBatch({
    batchFunction: api.tx.utility.batchAll,
    did: fullDid,
    extrinsics: [didKeyUpdateTx, didServiceRemoveTx, newServiceEndpointTx],
    sign: signCallback,
    submitter: submitterAccount.address
    })

    // Submit the DID update tx to the KILT blockchain after signing it with the authorized KILT account.
    await Kilt.Blockchain.signAndSubmitTx(authorizedBatchedTxs, submitterAccount)

    // Get the updated DID Document.
    const encodedUpdatedDidDetails = await api.call.did.query(
    Kilt.Did.toChain(fullDid)
    )
    return Kilt.Did.linkedInfoFromChain(encodedUpdatedDidDetails).document
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/key-generation/index.html b/docs/develop/sdk/cookbook/dids/key-generation/index.html index a07d0b48d..0a8aeb6dc 100644 --- a/docs/develop/sdk/cookbook/dids/key-generation/index.html +++ b/docs/develop/sdk/cookbook/dids/key-generation/index.html @@ -4,11 +4,11 @@ Generate DID keys | KILT Protocol - - + + -

    Generate DID keys

    Creating a Decentralized Identifier (DID) on the KILT network involves generating keying material for authentication and encryption. +

    Generate DID keys

    Creating a Decentralized Identifier (DID) on the KILT network involves generating keying material for authentication and encryption. This guide shows how to create a set of key pairs suitable for generating a KILT DID.

    Before proceeding, it's important to note that this example assumes the usage of the @kiltprotocol/sdk-js library along with the @polkadot/util-crypto library for cryptographic operations.

    Additionally, it's important to securely store keys and the mnemonic seed phrase. @@ -38,6 +38,6 @@

    import * as Kilt from '@kiltprotocol/sdk-js'

    import { mnemonicGenerate } from '@polkadot/util-crypto'

    export function generateKeypairs(mnemonic = mnemonicGenerate()): {
    authentication: Kilt.KiltKeyringPair
    keyAgreement: Kilt.KiltEncryptionKeypair
    assertionMethod: Kilt.KiltKeyringPair
    capabilityDelegation: Kilt.KiltKeyringPair
    } {
    const authentication = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic)

    const assertionMethod = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic)

    const capabilityDelegation = Kilt.Utils.Crypto.makeKeypairFromUri(mnemonic)

    const keyAgreement = Kilt.Utils.Crypto.makeEncryptionKeypairFromSeed(
    Kilt.Utils.Crypto.mnemonicToMiniSecret(mnemonic)
    )

    return {
    authentication: authentication,
    keyAgreement: keyAgreement,
    assertionMethod: assertionMethod,
    capabilityDelegation: capabilityDelegation
    }
    }

    info

    This example doesn't show how to store the keys. It is recommended to store the keys in a secure manner, e.g. only storing the private keys encrypted on disk. -The mnemonic seed phrase can be used to regenerate the keys, so it is recommended to also store the mnemonic in a secure manner and create a backup of it.

    +The mnemonic seed phrase can be used to regenerate the keys, so it is recommended to also store the mnemonic in a secure manner and create a backup of it.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/dids/light-did-creation/index.html b/docs/develop/sdk/cookbook/dids/light-did-creation/index.html index f9dfbe62e..d854ccd78 100644 --- a/docs/develop/sdk/cookbook/dids/light-did-creation/index.html +++ b/docs/develop/sdk/cookbook/dids/light-did-creation/index.html @@ -4,11 +4,11 @@ Create a Light DID | KILT Protocol - - + + -

    Create a Light DID

    The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption. +

    Create a Light DID

    The creation of a light DID requires the generation of some keying material for keys that are to be used for authentication and encryption. 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.

    The following is an example of how to create a light DID after creating an authentication keypair.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export function createSimpleLightDid({
    authentication
    }: {
    authentication: Kilt.NewLightDidVerificationKey
    }): Kilt.DidDocument {
    // Create a light DID from the generated authentication key.
    const lightDID = Kilt.Did.createLightDidDocument({
    authentication: [authentication]
    })
    console.log(lightDID.uri)

    return lightDID
    }
    @@ -20,6 +20,6 @@

    As such, light DIDs do not support updates of any sort, but they retain the same identifier until they are upgraded to full DIDs. They are not intended for use in complex and/or high-security use cases. In those situations, a full DID should be used. -Visit the next section to see how to create and manage full DIDs.

    +Visit the next section to see how to create and manage full DIDs.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/messaging/messaging_book/index.html b/docs/develop/sdk/cookbook/messaging/messaging_book/index.html index 3878939ec..a80d08972 100644 --- a/docs/develop/sdk/cookbook/messaging/messaging_book/index.html +++ b/docs/develop/sdk/cookbook/messaging/messaging_book/index.html @@ -4,11 +4,11 @@ Generate a Message | KILT Protocol - - + + -

    Generate a Message

    KILT defines a unicast messaging protocol

    +

    Generate a Message

    KILT defines a unicast messaging protocol

    Each of the messages sent is encrypted using the DID key agreement key. A message consists of the sender's DID URI, the receiver's DID URI, the message type and the body. There are multiple different message types, each of them with a different structure and containing different information. @@ -33,6 +33,6 @@

    Decryption -
    import * as Kilt from '@kiltprotocol/sdk-js'
    import { useDecryptionCallback } from '../signCallback/useDecryptionCallback'

    export async function decryptMessage(
    encryptedMessage: Kilt.IEncryptedMessage,
    keyAgreement: Kilt.KiltEncryptionKeypair
    ): Promise<Kilt.IMessage> {
    // Decrypting the message to retrieve the content
    const decryptedMessage = await Kilt.Message.decrypt(
    encryptedMessage,
    useDecryptionCallback(keyAgreement)
    )

    // Verifying this is a properly-formatted message
    Kilt.Message.verify(decryptedMessage)

    console.log(`Decrypted Message: ${JSON.stringify(decryptedMessage, null, 4)}`)

    // Checking if the message type matches the expected checks
    if (decryptedMessage.body.type !== 'request-credential') {
    throw new Error('Not the correct body type')
    }

    // Destructing the message to receive the cTypes array to see what credentials
    // Are valid for the given request
    const { cTypes } = decryptedMessage.body.content

    const { cTypeHash, trustedAttesters } = cTypes[0]

    // The receiver can check if they have a valid credential that matches the cTypeHash
    console.log('The sent cType hash :', cTypeHash)

    // The trusted attesters is an array that includes the list of trusted entities
    // The receiver can check if they have a given credential from the trusted list
    console.log(`A list of trusted attesters DID :${trustedAttesters}`)

    return decryptedMessage
    }

    +
    import * as Kilt from '@kiltprotocol/sdk-js'
    import { useDecryptionCallback } from '../signCallback/useDecryptionCallback'

    export async function decryptMessage(
    encryptedMessage: Kilt.IEncryptedMessage,
    keyAgreement: Kilt.KiltEncryptionKeypair
    ): Promise<Kilt.IMessage> {
    // Decrypting the message to retrieve the content
    const decryptedMessage = await Kilt.Message.decrypt(
    encryptedMessage,
    useDecryptionCallback(keyAgreement)
    )

    // Verifying this is a properly-formatted message
    Kilt.Message.verify(decryptedMessage)

    console.log(`Decrypted Message: ${JSON.stringify(decryptedMessage, null, 4)}`)

    // Checking if the message type matches the expected checks
    if (decryptedMessage.body.type !== 'request-credential') {
    throw new Error('Not the correct body type')
    }

    // Destructing the message to receive the cTypes array to see what credentials
    // Are valid for the given request
    const { cTypes } = decryptedMessage.body.content

    const { cTypeHash, trustedAttesters } = cTypes[0]

    // The receiver can check if they have a valid credential that matches the cTypeHash
    console.log('The sent cType hash :', cTypeHash)

    // The trusted attesters is an array that includes the list of trusted entities
    // The receiver can check if they have a given credential from the trusted list
    console.log(`A list of trusted attesters DID :${trustedAttesters}`)

    return decryptedMessage
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/messaging/replay_protection/index.html b/docs/develop/sdk/cookbook/messaging/replay_protection/index.html index d572376da..099939266 100644 --- a/docs/develop/sdk/cookbook/messaging/replay_protection/index.html +++ b/docs/develop/sdk/cookbook/messaging/replay_protection/index.html @@ -4,11 +4,11 @@ Protect Against Replay Attacks | KILT Protocol - - + + -

    Protect Against Replay Attacks

    Whenever data travels on a public network, even when encrypted or signed, the communicating parties need to make sure they never accept and process a message more than once to protect against exploits by malicious third parties (so-called replay attacks). +

    Protect Against Replay Attacks

    Whenever data travels on a public network, even when encrypted or signed, the communicating parties need to make sure they never accept and process a message more than once to protect against exploits by malicious third parties (so-called replay attacks). When requesting and submitting credential presentations, vulnerabilities for replay attacks can be prevented by requesting that the Claimer sign a unique piece of data as part of the presentation, as shown in the Verification Cookbook section.

    However, protection against replay attacks can also happen on the message layer. To help prevent these types of attacks, KILT messages are timestamped and expose a unique identifier as part of their encrypted content, which therefore cannot be tampered with. @@ -26,6 +26,6 @@

    1. Purge at regular intervals:
    -
    export function main(
    submissions: Map<string, number>,
    MAX_ACCEPTED_AGE: number
    ) {
    setInterval(() => {
    const outdatedTimestamp = Date.now() - MAX_ACCEPTED_AGE
    submissions.forEach((timestamp, hash) => {
    if (timestamp < outdatedTimestamp) submissions.delete(hash)
    })
    }, 1000)
    }
    +
    export function main(
    submissions: Map<string, number>,
    MAX_ACCEPTED_AGE: number
    ) {
    setInterval(() => {
    const outdatedTimestamp = Date.now() - MAX_ACCEPTED_AGE
    submissions.forEach((timestamp, hash) => {
    if (timestamp < outdatedTimestamp) submissions.delete(hash)
    })
    }, 1000)
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/public_credentials/public-credential-issuance/index.html b/docs/develop/sdk/cookbook/public_credentials/public-credential-issuance/index.html index ba202134c..23de52316 100644 --- a/docs/develop/sdk/cookbook/public_credentials/public-credential-issuance/index.html +++ b/docs/develop/sdk/cookbook/public_credentials/public-credential-issuance/index.html @@ -4,11 +4,11 @@ Credential Issuance | KILT Protocol - - + + -

    Credential Issuance

    As for traditional KILT credentials, public credentials also have their structure defined by a CType, although CTypes that can be used to represent information about assets would probably differ from the ones used to represent information about people.

    +

    Credential Issuance

    As for traditional KILT credentials, public credentials also have their structure defined by a CType, although CTypes that can be used to represent information about assets would probably differ from the ones used to represent information about people.

    As mentioned in the section about credentials, 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.

    We will not cover the creation of a CType, please refer to the CType creation

    Create and Issue the Credential

    @@ -21,6 +21,6 @@

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function issueCredential(
    attester: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback,
    credential: Kilt.IPublicCredentialInput
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    const credentialCreationTx = api.tx.publicCredentials.add(
    Kilt.PublicCredential.toChain(credential)
    )

    // Same as for traditional KILT credentials
    const authorizedAttestationTx = await Kilt.Did.authorizeTx(
    attester,
    credentialCreationTx,
    signCallback,
    submitterAccount.address
    )
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedAttestationTx,
    submitterAccount
    )
    }

    Credential has to be CBOR-encoded!

    Given a public credential object, the SDK internally CBOR-encodes it before firing the extrinsic to the blockchain! This is to save space on credentials that actually benefit from CBOR compression (e.g., if they contain a lot of binary information). -Hence, creating public credentials without the SDK requires the credential to be CBOR-encoded!

    +Hence, creating public credentials without the SDK requires the credential to be CBOR-encoded!

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/public_credentials/public-credential-retrieval/index.html b/docs/develop/sdk/cookbook/public_credentials/public-credential-retrieval/index.html index 32053298a..ea2ea7bc3 100644 --- a/docs/develop/sdk/cookbook/public_credentials/public-credential-retrieval/index.html +++ b/docs/develop/sdk/cookbook/public_credentials/public-credential-retrieval/index.html @@ -4,11 +4,11 @@ Retrieve Public Credentials | KILT Protocol - - + + -

    Retrieve Public Credentials

    Public credentials have their best capability in the fact that they are, indeed, public by design. +

    Retrieve Public Credentials

    Public credentials have their best capability in the fact that they are, indeed, public by design. This means that once issued, anyone who has access to an archive or full node for the KILT blockchain can retrieve them, making them very decentralized in nature.

    The KILT SDK exposes different ways to fetch public credentials.

    Retrieve a Credential by its Identifier

    @@ -37,6 +37,6 @@

    V
    How are public credentials stored on the blockchain?

    Because public credentials need to be public and accessible by everyone, their full content needs to be somehow stored on the blockchain. Nevertheless, the credential itself is not stored as part of the blockchain database. Rather, the block number in which the extrinsic is submitted is stored inside the blockchain database, and serves as a "pointer" to the block containing the whole information, that clients (including the SDK) can use. -This represents a very good tradeoff between security - because the blockchain itself dictates what the creation block number is for any given public credential - and storage efficiency - since the full credential is stored off-chain, accessible via any KILT archive node or indexing service.

    +This represents a very good tradeoff between security - because the blockchain itself dictates what the creation block number is for any given public credential - and storage efficiency - since the full credential is stored off-chain, accessible via any KILT archive node or indexing service.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/public_credentials/public-credential-revocation/index.html b/docs/develop/sdk/cookbook/public_credentials/public-credential-revocation/index.html index 7d6ab5e2f..bd346ff99 100644 --- a/docs/develop/sdk/cookbook/public_credentials/public-credential-revocation/index.html +++ b/docs/develop/sdk/cookbook/public_credentials/public-credential-revocation/index.html @@ -4,11 +4,11 @@ Revoke (and remove) Public Credentials | KILT Protocol - - + + -

    Revoke (and remove) Public Credentials

    Depending on the use cases, some credentials, as with any other type of credential, might need to be temporarily or permanently revoked.

    +

    Revoke (and remove) Public Credentials

    Depending on the use cases, some credentials, as with any other type of credential, might need to be temporarily or permanently revoked.

    The KILT SDK provides different features depending on the needs of the use case.

    Revoke and Remove a Credential

    As we have seen for public credential retrieval, a credential identifier is sufficient to perform most operations on public credentials. @@ -30,6 +30,6 @@

    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function reclaimDeposit(
    submitterAddress: Kilt.KiltKeyringPair,
    credential: Kilt.IPublicCredential
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    // Generate the tx to claim the deposit back.
    const credentialId = Kilt.PublicCredential.getIdForCredential(
    credential,
    credential.attester
    )
    const depositReclaimTx = api.tx.publicCredentials.reclaimDeposit(credentialId)

    // Submit the revocation tx to the KILT blockchain.
    await Kilt.Blockchain.signAndSubmitTx(depositReclaimTx, submitterAddress)
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/signCallback/index.html b/docs/develop/sdk/cookbook/signCallback/index.html index 3baaec067..52eb5b829 100644 --- a/docs/develop/sdk/cookbook/signCallback/index.html +++ b/docs/develop/sdk/cookbook/signCallback/index.html @@ -4,11 +4,11 @@ SignCallback | KILT Protocol - - + + -

    SignCallback

    Signing data involves using the private key and therefore needs to be secure. +

    SignCallback

    Signing data involves using the private key and therefore needs to be secure. There are many different options how data could be signed. You might have the private key stored in memory and are therefore able to simply sign the data. This is the easiest option but also comes with higher security risk. @@ -61,6 +61,6 @@

    GetSt Therefore the keyUri cannot point to a valid DID key and is not included in the return data.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function useStoreTxSignCallback(
    submitterAddress: Kilt.KiltAddress
    ): Promise<Kilt.SubmittableExtrinsic> {
    // Here we create a new key pair for the DID that will be created later.
    // This step might happen in an extension or else where, depending on your application.
    const authenticationKey: Kilt.KiltKeyringPair =
    Kilt.Utils.Crypto.makeKeypairFromSeed()

    // This is the sign callback. We use the just created key to sign arbitrary data
    // and return the signature together with the key type.
    const getStoreTxSignCallback: Kilt.Did.GetStoreTxSignCallback = async ({
    data
    }) => ({
    signature: authenticationKey.sign(data),
    keyType: authenticationKey.type
    })

    // Here we use the call back
    return await Kilt.Did.getStoreTx(
    {
    authentication: [authenticationKey]
    },
    submitterAddress,
    getStoreTxSignCallback
    )
    }

    Signing using an extension

    -

    🚧 This section is work in progress 🚧

    +

    🚧 This section is work in progress 🚧

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/upgrading_to_v0_29/index.html b/docs/develop/sdk/cookbook/upgrading_to_v0_29/index.html index f59649cdc..3a0d69aaf 100644 --- a/docs/develop/sdk/cookbook/upgrading_to_v0_29/index.html +++ b/docs/develop/sdk/cookbook/upgrading_to_v0_29/index.html @@ -4,14 +4,14 @@ Upgrading to v0.29 | KILT Protocol - - + + -

    Upgrading to v0.29

    Version 0.29.0 is the result of our efforts to make the SDK easier to understand and to use.

    +

    Upgrading to v0.29

    Version 0.29.0 is the result of our efforts to make the SDK easier to understand and to use.

    As a consequence, quite a few things have changed relative to previous versions. These pages serve as a reference point for what to consider when upgrading to make your transition as smooth as possible.

    Find out what has changed and how to upgrade in the release notes.

    -

    Also make sure to read up on how to remain interoperable with previous versions of the SDK.

    +

    Also make sure to read up on how to remain interoperable with previous versions of the SDK.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility/index.html b/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility/index.html index 8f461cb3c..f7f4662d7 100644 --- a/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility/index.html +++ b/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibility/index.html @@ -4,11 +4,11 @@ Backward Compatibility with Pre-0.29.x Versions | KILT Protocol - - + + -

    Backward Compatibility with Pre-0.29.x Versions

    Depending on how exactly your application interacts with other applications, changes to some data formats and interfaces might mean that conversions are required for them to remain compatible.

    +

    Backward Compatibility with Pre-0.29.x Versions

    Depending on how exactly your application interacts with other applications, changes to some data formats and interfaces might mean that conversions are required for them to remain compatible.

    To align with breaking changes to data structures in messaging, credentials, and CTypes, we published version 3.0 of the Credentials API specification that specifies how browser extensions like the Sporran credential wallet interact with web applications that produce or consume credentials.

    When upgrading to a 0.29.x version of the SDK and to the Credentials API version 3.0, we recommend backward support of Credentials API version 2.0, as supporting only the latest version may result in poor user experience. In what follows, we outline an upgrade strategy for implementers of the Credentials API specification.

    These instructions will also help with translating from and to data types of pre-0.29 SDK versions in other scenarios, such as when sending messages between clients, or when importing older data (e.g. credentials).

    @@ -36,6 +36,6 @@

    re Attesters can instead require claimers to sign a quote agreement for the purpose of bookkeeping, which contains the credential hash and thus represents a commitment to any claims made.

    submit-credential

    Before encrypting a submit-credential message for the older application, replace every item with an object having the property request with the value of item itself, and the property attestation with the attestation for this credential.

    -
    interface New extends Array<{ claim, ..., claimerSignature }> {}

    interface Old extends Array<{
    attestation: { claimHash, owner, ... }
    request: { claim, ..., claimerSignature }
    }> {}
    +
    interface New extends Array<{ claim, ..., claimerSignature }> {}

    interface Old extends Array<{
    attestation: { claimHash, owner, ... }
    request: { claim, ..., claimerSignature }
    }> {}
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/web3names/credential-query/index.html b/docs/develop/sdk/cookbook/web3names/credential-query/index.html index 4e3f53092..dd21eed6b 100644 --- a/docs/develop/sdk/cookbook/web3names/credential-query/index.html +++ b/docs/develop/sdk/cookbook/web3names/credential-query/index.html @@ -4,15 +4,15 @@ Query Public Credentials for a web3name | KILT Protocol - - + + -

    Query Public Credentials for a web3name

    web3names are linked to KILT DIDs, and KILT DIDs can define services to expose additional service/information. +

    Query Public Credentials for a web3name

    web3names are linked to KILT DIDs, and KILT DIDs can define services to expose additional service/information. One of the possible endpoint types is the KiltPublishedCredentialCollectionV1 type. The type defines the structure to make KILT credentials public and accessible to anyone.

    Because of the relationship between web3names and DIDs, it is possible, given a certain web3name, to retrieve all public credentials that the DID subject identified by that web3name has made available. Below is a code snippet showing how to do that using the KILT SDK, and how to perform the needed security checks/validation as recommended by the specification.

    -
    import fetch from 'node-fetch'

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryPublishedCredentials(
    web3Name: Kilt.Did.Web3Name
    ): Promise<Kilt.KiltPublishedCredentialCollectionV1> {
    const api = Kilt.ConfigService.get('api')

    const encodedDidForWeb3Name = await api.call.did.queryByWeb3Name(web3Name)
    const {
    document: { uri }
    } = Kilt.Did.linkedInfoFromChain(encodedDidForWeb3Name)

    console.log(`DID for "${web3Name}": ${uri}`)

    const resolutionResult = await Kilt.Did.resolve(uri)
    if (!resolutionResult) {
    throw new Error('The DID does not exist on the KILT blockchain.')
    }

    const { document } = resolutionResult
    // If no details are returned but resolutionResult is not null, the DID has been deleted.
    // This information is present in `resolutionResult.metadata.deactivated`.
    if (!document) {
    throw new Error('The DID has already been deleted.')
    }

    // Filter the endpoints by their type.
    const credentialEndpoints = document.service?.filter((service) =>
    service.type.includes(Kilt.KiltPublishedCredentialCollectionV1Type)
    )

    console.log(
    `Endpoints of type "${Kilt.KiltPublishedCredentialCollectionV1Type}" for the retrieved DID:`
    )
    console.log(JSON.stringify(credentialEndpoints, null, 2))

    // For demonstration, only the first endpoint and its first URL are considered.
    const firstCredentialCollectionEndpointUrl =
    credentialEndpoints?.[0]?.serviceEndpoint[0]
    if (!firstCredentialCollectionEndpointUrl) {
    console.log(
    `The DID has no services of type "${Kilt.KiltPublishedCredentialCollectionV1Type}".`
    )
    }

    // Retrieve the credentials pointed at by the endpoint.
    // Being an IPFS endpoint, the fetching can take an arbitrarily long time or even fail if the timeout is reached.
    // In production settings, error cases including those where the result is not a correct JSON should be handled accordingly.
    const response = await fetch(firstCredentialCollectionEndpointUrl as string)
    const credentialCollection: Kilt.KiltPublishedCredentialCollectionV1 =
    await response.json()
    console.log(`Credential collection behind the endpoint:`)
    console.log(JSON.stringify(credentialCollection, null, 2))

    // Verify that all credentials are valid and that they all refer to the same subject DID.
    await Promise.all(
    credentialCollection.map(async ({ credential }) => {
    const { revoked } = await Kilt.Credential.verifyCredential(credential)

    // Verify that the credential is not revoked.
    if (revoked) {
    throw new Error(
    'One of the credentials has been revoked, hence it is not valid.'
    )
    }

    // Verify that the credential refers to the intended subject.
    if (!Kilt.Did.isSameSubject(credential.claim.owner, uri)) {
    throw new Error(
    'One of the credentials refers to a different subject than expected.'
    )
    }
    })
    )

    // If none of the above operations throw, the credentials are valid.
    console.log('All retrieved credentials are valid! ✅!')

    return credentialCollection
    }
    +
    import fetch from 'node-fetch'

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryPublishedCredentials(
    web3Name: Kilt.Did.Web3Name
    ): Promise<Kilt.KiltPublishedCredentialCollectionV1> {
    const api = Kilt.ConfigService.get('api')

    const encodedDidForWeb3Name = await api.call.did.queryByWeb3Name(web3Name)
    const {
    document: { uri }
    } = Kilt.Did.linkedInfoFromChain(encodedDidForWeb3Name)

    console.log(`DID for "${web3Name}": ${uri}`)

    const resolutionResult = await Kilt.Did.resolve(uri)
    if (!resolutionResult) {
    throw new Error('The DID does not exist on the KILT blockchain.')
    }

    const { document } = resolutionResult
    // If no details are returned but resolutionResult is not null, the DID has been deleted.
    // This information is present in `resolutionResult.metadata.deactivated`.
    if (!document) {
    throw new Error('The DID has already been deleted.')
    }

    // Filter the endpoints by their type.
    const credentialEndpoints = document.service?.filter((service) =>
    service.type.includes(Kilt.KiltPublishedCredentialCollectionV1Type)
    )

    console.log(
    `Endpoints of type "${Kilt.KiltPublishedCredentialCollectionV1Type}" for the retrieved DID:`
    )
    console.log(JSON.stringify(credentialEndpoints, null, 2))

    // For demonstration, only the first endpoint and its first URL are considered.
    const firstCredentialCollectionEndpointUrl =
    credentialEndpoints?.[0]?.serviceEndpoint[0]
    if (!firstCredentialCollectionEndpointUrl) {
    console.log(
    `The DID has no services of type "${Kilt.KiltPublishedCredentialCollectionV1Type}".`
    )
    }

    // Retrieve the credentials pointed at by the endpoint.
    // Being an IPFS endpoint, the fetching can take an arbitrarily long time or even fail if the timeout is reached.
    // In production settings, error cases including those where the result is not a correct JSON should be handled accordingly.
    const response = await fetch(firstCredentialCollectionEndpointUrl as string)
    const credentialCollection: Kilt.KiltPublishedCredentialCollectionV1 =
    await response.json()
    console.log(`Credential collection behind the endpoint:`)
    console.log(JSON.stringify(credentialCollection, null, 2))

    // Verify that all credentials are valid and that they all refer to the same subject DID.
    await Promise.all(
    credentialCollection.map(async ({ credential }) => {
    const { revoked } = await Kilt.Credential.verifyCredential(credential)

    // Verify that the credential is not revoked.
    if (revoked) {
    throw new Error(
    'One of the credentials has been revoked, hence it is not valid.'
    )
    }

    // Verify that the credential refers to the intended subject.
    if (!Kilt.Did.isSameSubject(credential.claim.owner, uri)) {
    throw new Error(
    'One of the credentials refers to a different subject than expected.'
    )
    }
    })
    )

    // If none of the above operations throw, the credentials are valid.
    console.log('All retrieved credentials are valid! ✅!')

    return credentialCollection
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/web3names/web3name-claim/index.html b/docs/develop/sdk/cookbook/web3names/web3name-claim/index.html index 4dbbc4684..3f343aa28 100644 --- a/docs/develop/sdk/cookbook/web3names/web3name-claim/index.html +++ b/docs/develop/sdk/cookbook/web3names/web3name-claim/index.html @@ -4,14 +4,14 @@ Claim a web3name | KILT Protocol - - + + -

    Claim a web3name

    A web3name can be claimed if it currently has no owner, using the following snippet as reference.

    +

    Claim a web3name

    A web3name can be claimed if it currently has no owner, using the following snippet as reference.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function claimWeb3Name(
    did: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    name: Kilt.Did.Web3Name,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    const web3NameClaimTx = api.tx.web3Names.claim(name)
    const authorizedWeb3NameClaimTx = await Kilt.Did.authorizeTx(
    did,
    web3NameClaimTx,
    signCallback,
    submitterAccount.address
    )
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedWeb3NameClaimTx,
    submitterAccount
    )
    }

    The claiming process requires the reservation of a deposit that is freed upon web3name release.

    Once claimed, the web3name will start appearing whenever the DID of its owner is resolved, for instance via the Universal Resolver. -For more information about web3names and DIDs, see the official KILT DID Specification.

    +For more information about web3names and DIDs, see the official KILT DID Specification.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/web3names/web3name-query/index.html b/docs/develop/sdk/cookbook/web3names/web3name-query/index.html index 45e4c221b..a62db0b6a 100644 --- a/docs/develop/sdk/cookbook/web3names/web3name-query/index.html +++ b/docs/develop/sdk/cookbook/web3names/web3name-query/index.html @@ -4,16 +4,16 @@ Resolve a web3name | KILT Protocol - - + + -

    Resolve a web3name

    A web3name can be resolved in a similar manner to how a DID is resolved. +

    Resolve a web3name

    A web3name can be resolved in a similar manner to how a DID is resolved. Resolving the web3name will provide the same information as resolving a DID does.

    To query and retrieve the DID document associated with a web3name, you can use the following code example:

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryDidDocument(
    web3Name: Kilt.Did.Web3Name
    ): Promise<Kilt.DidDocument> {
    const api = Kilt.ConfigService.get('api')

    console.log(`Querying the blockchain for the web3name "${web3Name}"`)
    // Query the owner of the provided web3name.
    const encodedWeb3NameOwner = await api.call.did.queryByWeb3Name(web3Name)

    // Extract the DidDocument and other linked information from the encodedWeb3NameOwner.
    const { document } = Kilt.Did.linkedInfoFromChain(encodedWeb3NameOwner)

    return document
    }

    In the code example above, the queryDidDocument function takes a web3Name parameter, which represents the web3name to be resolved. It internally uses the api.call.did.queryByWeb3Name method to query the information of the provided web3name from the blockchain.

    -

    The function then decodes the result using Kilt.Did.linkedInfoFromChain to extract the associated DID document and any other linked blockchain accounts. Finally, it returns the resolved DID document.

    +

    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.

    \ No newline at end of file diff --git a/docs/develop/sdk/cookbook/web3names/web3name-release/index.html b/docs/develop/sdk/cookbook/web3names/web3name-release/index.html index 270fd097e..4a45ce015 100644 --- a/docs/develop/sdk/cookbook/web3names/web3name-release/index.html +++ b/docs/develop/sdk/cookbook/web3names/web3name-release/index.html @@ -4,11 +4,11 @@ Release a web3name | KILT Protocol - - + + -

    Release a web3name

    If a web3name is no longer needed, either the DID owner or the deposit payer can release it, with deposit being released and returned to the original payer.

    +

    Release a web3name

    If a web3name is no longer needed, either the DID owner or the deposit payer can release it, with deposit being released and returned to the original payer.

    Releasing a Web3name by the DID Owner

    In the case of the DID owner willing to release the web3name, the following snippet provides a reference implementation on how to achieve that.

    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function releaseWeb3Name(
    did: Kilt.DidUri,
    submitterAccount: Kilt.KiltKeyringPair,
    signCallback: Kilt.SignExtrinsicCallback
    ): Promise<void> {
    const api = Kilt.ConfigService.get('api')

    const web3NameReleaseTx = api.tx.web3Names.releaseByOwner()
    const authorizedWeb3NameReleaseTx = await Kilt.Did.authorizeTx(
    did,
    web3NameReleaseTx,
    signCallback,
    submitterAccount.address
    )
    await Kilt.Blockchain.signAndSubmitTx(
    authorizedWeb3NameReleaseTx,
    submitterAccount
    )
    }
    @@ -31,6 +31,6 @@

    +

    By using these code examples, you can easily release or reclaim the deposit of a web3name, depending on the scenario and the role of the entity initiating the release.

    \ No newline at end of file diff --git a/docs/develop/sdk/integrate/howto-integrate-browser/index.html b/docs/develop/sdk/integrate/howto-integrate-browser/index.html index eb2196a1d..e824697d1 100644 --- a/docs/develop/sdk/integrate/howto-integrate-browser/index.html +++ b/docs/develop/sdk/integrate/howto-integrate-browser/index.html @@ -4,15 +4,15 @@ Browser | KILT Protocol - - + + -

    Browser

    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:

    +

    Browser

    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:

    <script src="https://unpkg.com/@kiltprotocol/sdk-js@0.35.0/dist/sdk-js.min.umd.js"></script>

    The SDK's functions then become available via a new kilt property on the global window object.

    To get started with your first React application using KILT, we recommend using either the KILT Distillery CLI tool for bootstrapping or a framework like Vite or Next.js 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.

    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!

    -
    info

    You should of course familiarize yourself with the tool of your choice, but these commands have served us well in the past:

    yarn create vite my-kilt-app --template react-ts
    cd my-kilt-app
    yarn add @kiltprotocol/sdk-js
    +
    info

    You should of course familiarize yourself with the tool of your choice, but these commands have served us well in the past:

    yarn create vite my-kilt-app --template react-ts
    cd my-kilt-app
    yarn add @kiltprotocol/sdk-js
    \ No newline at end of file diff --git a/docs/develop/sdk/integrate/howto-integrate-distillery/index.html b/docs/develop/sdk/integrate/howto-integrate-distillery/index.html index 9350b7371..0fd7c8865 100644 --- a/docs/develop/sdk/integrate/howto-integrate-distillery/index.html +++ b/docs/develop/sdk/integrate/howto-integrate-distillery/index.html @@ -4,12 +4,12 @@ KILT Distillery | KILT Protocol - - + + -

    KILT Distillery

    Different types of projects can be bootstrapped using our KILT distillery CLI.

    +

    KILT Distillery

    Different types of projects can be bootstrapped using our KILT distillery CLI.

    Please read the README.md file for more information, but if you are impatient you can execute this command and follow the instructions:

    -
    npx git+https://github.com/KILTprotocol/kilt-distillery-cli
    +
    npx git+https://github.com/KILTprotocol/kilt-distillery-cli
    \ No newline at end of file diff --git a/docs/develop/sdk/integrate/howto-integrate-nodejs/index.html b/docs/develop/sdk/integrate/howto-integrate-nodejs/index.html index 5f7a03a0b..ed659e405 100644 --- a/docs/develop/sdk/integrate/howto-integrate-nodejs/index.html +++ b/docs/develop/sdk/integrate/howto-integrate-nodejs/index.html @@ -4,13 +4,13 @@ NodeJS | KILT Protocol - - + + -

    NodeJS

    NodeJS is natively supported and doesn't require any additional setup.

    +

    NodeJS

    NodeJS is natively supported and doesn't require any additional setup.

    Have a look at these example package.json and index.js files for reference:

    {
    "name": "kilt-sdk-node-test",
    "type": "module",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "dependencies": {
    "@kiltprotocol/sdk-js": "0.35.0"
    }
    }
    -
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryAccountWeb3Name(
    lookupAccountAddress: Kilt.KiltAddress
    ): Promise<Kilt.Did.Web3Name | null> {
    const api = Kilt.ConfigService.get('api')

    const encodedLinkedDetails = await api.call.did.queryByAccount(
    Kilt.Did.accountToChain(lookupAccountAddress)
    )
    const { web3Name } = Kilt.Did.linkedInfoFromChain(encodedLinkedDetails)
    if (web3Name) {
    console.log(
    `web3name for account "${lookupAccountAddress}" -> "${web3Name}"`
    )
    } else {
    console.log(
    `Account "${lookupAccountAddress}" does not have a linked web3name.`
    )
    }

    return web3Name
    }
    +
    import * as Kilt from '@kiltprotocol/sdk-js'

    export async function queryAccountWeb3Name(
    lookupAccountAddress: Kilt.KiltAddress
    ): Promise<Kilt.Did.Web3Name | null> {
    const api = Kilt.ConfigService.get('api')

    const encodedLinkedDetails = await api.call.did.queryByAccount(
    Kilt.Did.accountToChain(lookupAccountAddress)
    )
    const { web3Name } = Kilt.Did.linkedInfoFromChain(encodedLinkedDetails)
    if (web3Name) {
    console.log(
    `web3name for account "${lookupAccountAddress}" -> "${web3Name}"`
    )
    } else {
    console.log(
    `Account "${lookupAccountAddress}" does not have a linked web3name.`
    )
    }

    return web3Name
    }
    \ No newline at end of file diff --git a/docs/develop/sdk/integrate/index.html b/docs/develop/sdk/integrate/index.html index fdd5084c1..5faee22d3 100644 --- a/docs/develop/sdk/integrate/index.html +++ b/docs/develop/sdk/integrate/index.html @@ -4,13 +4,13 @@ How to Integrate | KILT Protocol - - + + -

    How to Integrate

    Integrating with KILT is easy. +

    How to Integrate

    Integrating with KILT is easy. If your project needs to integrate KILT in a frontend and/or a backend application, we've got you covered!

    These pages are dedicated to helping you set up a NodeJS application or web app.

    -

    We also introduce the KILT distillery CLI tool which helps you quickly spin up your first KILT-based project.

    +

    We also introduce the KILT distillery CLI tool which helps you quickly spin up your first KILT-based project.

    \ No newline at end of file diff --git a/docs/develop/sdk/quickstart/index.html b/docs/develop/sdk/quickstart/index.html index b595162c6..ef6e81674 100644 --- a/docs/develop/sdk/quickstart/index.html +++ b/docs/develop/sdk/quickstart/index.html @@ -4,11 +4,11 @@ Quickstart | KILT Protocol - - + + -

    Quickstart

    Get started with KILT by following this guide, which teaches you to:

    +

    Quickstart

    Get started with KILT by following this guide, which teaches you to:

    1. Import the KILT SDK into your project
    2. Connect to the KILT blockchain
    3. @@ -74,6 +74,6 @@

      Next steps

    + \ No newline at end of file diff --git a/docs/develop/sdk/troubleshoot-sdk/index.html b/docs/develop/sdk/troubleshoot-sdk/index.html index 5e91b5bef..a42f60529 100644 --- a/docs/develop/sdk/troubleshoot-sdk/index.html +++ b/docs/develop/sdk/troubleshoot-sdk/index.html @@ -4,11 +4,11 @@ Troubleshoot | KILT Protocol - - + + -

    Troubleshoot

    Solutions and workarounds for common or unresolved issues.

    +

    Troubleshoot

    Solutions and workarounds for common or unresolved issues.

    Webpack < 5 used to include polyfills

    ERROR in ./node_modules/cbor/lib/commented.js 3:15-32
    Module not found: Error: Can't resolve 'stream' in 'node_modules/cbor/lib'

    BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
    This is no longer the case.
    Verify if you need this module and configure a polyfill for it.

    Solution

    @@ -19,6 +19,6 @@

    Solutionredeclaration of import Buffer

    Uncaught SyntaxError: redeclaration of import Buffer

    Solution

    -

    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.

    +

    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.

    \ No newline at end of file diff --git a/docs/develop/specifications/index.html b/docs/develop/specifications/index.html index a3a4ef8fc..970d3f2d8 100644 --- a/docs/develop/specifications/index.html +++ b/docs/develop/specifications/index.html @@ -4,11 +4,11 @@ Technical Specifications | KILT Protocol - - + + -

    Technical Specifications

    note

    This section is a WIP. +

    +
    \ No newline at end of file diff --git a/docs/develop/workshop/attestation/index.html b/docs/develop/workshop/attestation/index.html index 6ef79eefe..96587526a 100644 --- a/docs/develop/workshop/attestation/index.html +++ b/docs/develop/workshop/attestation/index.html @@ -4,11 +4,11 @@ 🧾 Attestation | KILT Protocol - - + + -

    🧾 Attestation

    This section covers how the Attester receives and processes a Credential and how you can:

    +
    +

    Let's move on to set up the Verifier!

    \ No newline at end of file diff --git a/docs/develop/workshop/attester/account/index.html b/docs/develop/workshop/attester/account/index.html index 1b1aa0c1d..6e0f8a399 100644 --- a/docs/develop/workshop/attester/account/index.html +++ b/docs/develop/workshop/attester/account/index.html @@ -4,11 +4,11 @@ Account | KILT Protocol - - + + -

    Account

    With the project structure setup in the last step, you can create your Attester account.

    +

    Account

    With the project structure setup in the last step, you can create your Attester account.

    With KILT, an account is an object that interacts with the blockchain.

    KILT Account

    A KILT account is a set of cryptographic elements:

    +If you haven't already requested PILT, go to the faucet and request tokens for your <address>.

    \ No newline at end of file diff --git a/docs/develop/workshop/attester/ctype/index.html b/docs/develop/workshop/attester/ctype/index.html index c5be96dce..21f909fe2 100644 --- a/docs/develop/workshop/attester/ctype/index.html +++ b/docs/develop/workshop/attester/ctype/index.html @@ -4,11 +4,11 @@ CType | KILT Protocol - - + + -

    CType

    A claim type (CType) is a KILT-specific term, but the concept is simple: +

    CType

    A claim type (CType) is a KILT-specific term, but the concept is simple: A CType is a JSON schema that defines the structure of a claim, and you can think of it as the data model for your claim.

    CType

    A CType ensures that a credential contains all required attributes, e.g., a driver's license has to contain a name, date of birth, and the vehicle types that the claimer can drive. The CType is important since a Verifier requests credentials for a specific CType. @@ -43,6 +43,6 @@

    Get CType
    warning

    Remember, an account must have the required amount of tokens to pay the transaction fee and deposit.

    Run

    Run the attester/generateCtype.ts file.

    yarn ts-node attester/generateCtype.ts
    -

    Before you can attest Credentials, you need a Claimer to request it

    +

    Before you can attest Credentials, you need a Claimer to request it

    \ No newline at end of file diff --git a/docs/develop/workshop/attester/did/index.html b/docs/develop/workshop/attester/did/index.html index 9ec082301..d970f1999 100644 --- a/docs/develop/workshop/attester/did/index.html +++ b/docs/develop/workshop/attester/did/index.html @@ -4,11 +4,11 @@ DID | KILT Protocol - - + + -

    DID

    The next step is to generate a KILT decentralized identifier (DID) using the account you created for the Attester in the previous step.

    +
    +

    Well done - You've generated a full DID! The next step is to create a CType!

    \ No newline at end of file diff --git a/docs/develop/workshop/attester/index.html b/docs/develop/workshop/attester/index.html index 6f877bfc7..410d83307 100644 --- a/docs/develop/workshop/attester/index.html +++ b/docs/develop/workshop/attester/index.html @@ -4,11 +4,11 @@ 🏢 Attester | KILT Protocol - - + + -

    🏢 Attester

    This section of the workshop covers creating the Attester code. The steps are the following:

    +

    🏢 Attester

    This section of the workshop covers creating the Attester code. The steps are the following:

    1. Create an account to pay for all transactions and storage deposits.
    2. Create a DID, which is the identity used to create attestations.
    3. @@ -21,6 +21,6 @@

      Folder Structure

      Create the following files in the attester folder. These folders mimic an Attester service.

      -
      └─ kilt-rocks/ # project
      └─ attester/ # all attester code
      ├─ attestCredential.ts # issues attestations
      ├─ ctypeSchema.ts # create a local CType definition
      ├─ generateAccount.ts # functions for setting up and loading the attester's account
      ├─ generateCtype.ts # register the CType on chain
      ├─ generateDid.ts # registers the attester's on-chain DID
      └─ generateKeypairs.ts # setup the keys for the attester's DID
    +
    └─ kilt-rocks/ # project
    └─ attester/ # all attester code
    ├─ attestCredential.ts # issues attestations
    ├─ ctypeSchema.ts # create a local CType definition
    ├─ generateAccount.ts # functions for setting up and loading the attester's account
    ├─ generateCtype.ts # register the CType on chain
    ├─ generateDid.ts # registers the attester's on-chain DID
    └─ generateKeypairs.ts # setup the keys for the attester's DID
    \ No newline at end of file diff --git a/docs/develop/workshop/claimer/did/index.html b/docs/develop/workshop/claimer/did/index.html index 72e3a3e91..08d6ddef5 100644 --- a/docs/develop/workshop/claimer/did/index.html +++ b/docs/develop/workshop/claimer/did/index.html @@ -4,11 +4,11 @@ DID | KILT Protocol - - + + -

    DID

    This section covers creating a light DID using the account you created for the Claimer.

    +

    DID

    This section covers creating a light DID using the account you created for the Claimer.

    Since a light DID is not registered on the blockchain, you don't need funds to create one.

    info

    Remember, light DIDs can do the following:

    • Sign attestation requests and presentation with the authentication keys
    • @@ -28,6 +28,6 @@

      Generate

      The createLightDidDocument method takes these two values and generates the light DID.

      Run

      yarn ts-node ./claimer/generateLightDid.ts
      -

      Well done - You successfully generated a light DID!

    +

    Well done - You successfully generated a light DID!

    \ No newline at end of file diff --git a/docs/develop/workshop/claimer/index.html b/docs/develop/workshop/claimer/index.html index 9efdb3387..23ea229e2 100644 --- a/docs/develop/workshop/claimer/index.html +++ b/docs/develop/workshop/claimer/index.html @@ -4,11 +4,11 @@ 👤 Claimer | KILT Protocol - - + + -

    👤 Claimer

    This section covers the steps undertaken by the Claimer.

    +

    👤 Claimer

    This section covers the steps undertaken by the Claimer.

    Here's an overview:

    1. Create a DID, which is the identity used to interact with Attesters and Verifiers.
    2. @@ -29,6 +29,6 @@

      What is a

      Folder Structure

      Create the following files in the Claimer folder. This folders serves to mimic a Claimer's perspective.

      -
      └─ kilt-rocks/ # project
      └─ claimer/ # all claimer code
      ├─ createClaim.ts # creates a claim
      ├─ createPresentation.ts # creates a presentation for verifiers
      ├─ generateCredential.ts # create the credential object that is sent to the attester for attestation
      ├─ generateKeypairs.ts # create keypairs for the light DID
      └─ generateLightDid.ts # create the light DID for the claimer
      mkdir claimer && touch claimer/createClaim.ts && touch claimer/createPresentation.ts && touch claimer/generateCredential.ts && touch claimer/generateKeypairs.ts && touch claimer/generateLightDid.ts
    +
    └─ kilt-rocks/ # project
    └─ claimer/ # all claimer code
    ├─ createClaim.ts # creates a claim
    ├─ createPresentation.ts # creates a presentation for verifiers
    ├─ generateCredential.ts # create the credential object that is sent to the attester for attestation
    ├─ generateKeypairs.ts # create keypairs for the light DID
    └─ generateLightDid.ts # create the light DID for the claimer
    mkdir claimer && touch claimer/createClaim.ts && touch claimer/createPresentation.ts && touch claimer/generateCredential.ts && touch claimer/generateKeypairs.ts && touch claimer/generateLightDid.ts
    \ No newline at end of file diff --git a/docs/develop/workshop/claimer/request/index.html b/docs/develop/workshop/claimer/request/index.html index 284fdc2ec..9423b447a 100644 --- a/docs/develop/workshop/claimer/request/index.html +++ b/docs/develop/workshop/claimer/request/index.html @@ -4,11 +4,11 @@ Request an Attestation | KILT Protocol - - + + -

    Request an Attestation

    This section covers creating a Claim and a Credential.

    +

    Request an Attestation

    This section covers creating a Claim and a Credential.

    KILT is a premissionless system. Anyone or anything can claim something and attest to it. But an attested credential only has value if the Verifier of the credential trusts the Attester of the credential.

    @@ -31,6 +31,6 @@

    Run

    yarn ts-node claimer/generateCredential.ts

    OK, you've made a claim as a Claimer and created a credential from it. -The next step is to finish the Attester and get the credential attested!

    +The next step is to finish the Attester and get the credential attested!

    \ No newline at end of file diff --git a/docs/develop/workshop/done/index.html b/docs/develop/workshop/done/index.html index 27a4f42fd..bab883629 100644 --- a/docs/develop/workshop/done/index.html +++ b/docs/develop/workshop/done/index.html @@ -4,11 +4,11 @@ 🚀 Done | KILT Protocol - - + + -

    🚀 Done

    Congrats!

    +

    🚀 Done

    Congrats!

    Well done! You now understand the main actors in KILT, the Claimers, Attesters and Verifiers.

    You have also learned how to:

    @@ -25,6 +25,6 @@

    ResourcesDiscord - DAO-inspired, outcome-focused community
  • Element - Technical, Governance, Treasury discussion
  • -

    +
    \ No newline at end of file diff --git a/docs/develop/workshop/overview/index.html b/docs/develop/workshop/overview/index.html index f746e8807..38479c9cf 100644 --- a/docs/develop/workshop/overview/index.html +++ b/docs/develop/workshop/overview/index.html @@ -4,11 +4,11 @@ 👓 Overview | KILT Protocol - - + + -

    👓 Overview

    This tutorial runs through the full story of a claim.

    +

    👓 Overview

    This tutorial runs through the full story of a claim.

    It involves three actors which work together to create distributed trust:

    • A Claimer is an actor who claims to possess certain credentials, abilities, or other attributes.
    • @@ -55,6 +55,6 @@

    +Privacy was achieved with distributed trust.

    \ No newline at end of file diff --git a/docs/develop/workshop/setup/index.html b/docs/develop/workshop/setup/index.html index 5028f2d6c..66a14c11b 100644 --- a/docs/develop/workshop/setup/index.html +++ b/docs/develop/workshop/setup/index.html @@ -4,11 +4,11 @@ 🎒 Setup | KILT Protocol - - + + -

    🎒 Setup

    Project setup

    +

    🎒 Setup

    Project setup

    Create a new project in a fresh directory and navigate into it by running mkdir kilt-rocks && cd kilt-rocks.

    The dependencies needed are the following:

      @@ -30,6 +30,6 @@

      Blockc

      Where address is the address of the full node you want to connect to, which for this workshop, is wss://peregrine.kilt.io.

      For convenience, add the address to the .env file.

      .env
      WSS_ADDRESS=wss://peregrine.kilt.io
      -

      That's it for the basic setup - You're good to go!

    +

    That's it for the basic setup - You're good to go!

    \ No newline at end of file diff --git a/docs/develop/workshop/verification/index.html b/docs/develop/workshop/verification/index.html index ea0c32518..cc7575d81 100644 --- a/docs/develop/workshop/verification/index.html +++ b/docs/develop/workshop/verification/index.html @@ -4,11 +4,11 @@ 🤝 Verification | KILT Protocol - - + + -

    🤝 Verification

    In this section, you play the role of a Verifier that does the following:

    +

    🤝 Verification

    In this section, you play the role of a Verifier that does the following:

    1. Take a Presentation object supplied by a Claimer
    2. Verify that its data is correct
    3. @@ -31,6 +31,6 @@

      VerifyRun

      Run the code from the command line:

      yarn ts-node verify.ts
      -

      That's it! All done :-)

    +

    That's it! All done :-)

    \ No newline at end of file diff --git a/docs/develop/workshop/welcome/index.html b/docs/develop/workshop/welcome/index.html index 4e17b55ed..ade32d44c 100644 --- a/docs/develop/workshop/welcome/index.html +++ b/docs/develop/workshop/welcome/index.html @@ -4,11 +4,11 @@ 👋🏻 Welcome | KILT Protocol - - + + -

    👋🏻 Welcome

    SDK version 0.35.0.

    +

    👋🏻 Welcome

    SDK version 0.35.0.

    What you can expect to learn

    📦 Topics: KILT SDK essentials, basic credential workflow. This includes creating a CType and a claim, attesting a claim, and finally verifying the credential.

    Duration: 15-45 minutes.

    🤓 Prerequisites:

    • Basic JavaScript or TypeScript knowledge.
    • @@ -20,6 +20,6 @@

      Welcome

      ✔ Use the KILT SDK to implement the basic flow of a KILT claim, from creation until verification. You'll create a claim as a Claimer, attest it as an Attester and verify it as a Verifier.

      ✔ Use the KILT SDK to write onto and read from the KILT blockchain.

      -

      Ready? Let's go!

    +

    Ready? Let's go!

    \ No newline at end of file diff --git a/docs/participate/content-creation-guidelines/index.html b/docs/participate/content-creation-guidelines/index.html index ae60eda48..982047f90 100644 --- a/docs/participate/content-creation-guidelines/index.html +++ b/docs/participate/content-creation-guidelines/index.html @@ -4,11 +4,11 @@ Content Creation Guidelines | KILT Protocol - - + + -

    Content Creation Guidelines

    Content created should be unique in substance, reach, or delivery. +

    Content Creation Guidelines

    Content created should be unique in substance, reach, or delivery. Copying or quickly iterating existing works are less likely to result in a successful proposal. If providing translations, they must be done accurately by a native or expert speaker (i.e. no translation tools). Content must be accessible and open source. @@ -33,6 +33,6 @@

    Financial

    +Note the beneficiary address here.

    \ No newline at end of file diff --git a/docs/participate/governance/remove_vote/index.html b/docs/participate/governance/remove_vote/index.html index f263c8057..a9bc8e0c8 100644 --- a/docs/participate/governance/remove_vote/index.html +++ b/docs/participate/governance/remove_vote/index.html @@ -4,11 +4,11 @@ Remove a Vote | KILT Protocol - - + + -

    Remove a Vote

    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.

    +

    Remove a Vote

    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.

    Find the Referendum Index

    1. Go to the Democracy tab in Polkadot.JS Apps
    2. @@ -26,6 +26,6 @@

      Remove the V

    Unlock Expired Voting Locks

    -

    Please refer to the "Unlock coins after lockup expires" guide.

    +

    Please refer to the "Unlock coins after lockup expires" guide.

    \ No newline at end of file diff --git a/docs/participate/governance/unlock_coins/index.html b/docs/participate/governance/unlock_coins/index.html index c9ccfca84..5bb8d8b5f 100644 --- a/docs/participate/governance/unlock_coins/index.html +++ b/docs/participate/governance/unlock_coins/index.html @@ -4,11 +4,11 @@ Remove Expired Voting Locks | KILT Protocol - - + + -

    Remove Expired Voting Locks

    After the lockup time has been reached, a transaction is needed to clear the lock. +

    Remove Expired Voting Locks

    After the lockup time has been reached, a transaction is needed to clear the lock. Of note: this will also require a transaction fee.

    1. Go to KILT Spiritnet on Polkadot.JS
    2. @@ -17,6 +17,6 @@

    Confirm the transaction. -This will clear the lock.

    +This will clear the lock.

    \ No newline at end of file diff --git a/docs/participate/governance/vote/index.html b/docs/participate/governance/vote/index.html index 1719407c4..006c370af 100644 --- a/docs/participate/governance/vote/index.html +++ b/docs/participate/governance/vote/index.html @@ -4,11 +4,11 @@ Cast a Vote | KILT Protocol - - + + -

    Cast a Vote

      +

      Cast a Vote

      1. Go to KILT Spiritnet on Polkadot.JS

      2. @@ -82,6 +82,6 @@

        Example

        KILT also uses an algorithm to adapt the amount of “aye” (yes/agree) votes needed to pass depending on voter turnout: the greater the number of voters, the lower the threshold required to pass. Therefore, when voter turnout is low a supermajority is generally required; with a high turnout a simple majority is sufficient.

        Before voting on any referendum, you can read more about it and join the discussion in Polkassembly (under “Democracy” → “Referenda”). -Polkassembly is an open source platform for providing information, context and a discussion forum for proposals and referenda in the Polkadot ecosystem.

      +Polkassembly is an open source platform for providing information, context and a discussion forum for proposals and referenda in the Polkadot ecosystem.

    \ No newline at end of file diff --git a/docs/participate/staking/advanced_collator_section/adjust-stake/index.html b/docs/participate/staking/advanced_collator_section/adjust-stake/index.html index b1e449fc3..61d5f3e06 100644 --- a/docs/participate/staking/advanced_collator_section/adjust-stake/index.html +++ b/docs/participate/staking/advanced_collator_section/adjust-stake/index.html @@ -4,11 +4,11 @@ Adjust Your Own Stake | KILT Protocol - - + + -

    Adjust Your Own Stake

    A collator can increase or decrease their stake, always within the limits of the minimum and maximum allowed stake amounts. +

    Adjust Your Own Stake

    A collator can increase or decrease their stake, always within the limits of the minimum and maximum allowed stake amounts. The corresponding extrinsics for these operations are parachainStaking -> candidateStakeMore(more) and parachainStaking -> candidateStakeLess(less).

    info

    You can either execute this transaction in Polkadot JS Apps or the KILT Stakeboard, which serves as an in-house developed Frontend for all KILT staking activity. Below, we outline the steps for Polkadot JS Apps. @@ -26,6 +26,6 @@

  • Choose the desired stake amount which you want to remove from your current stake (the less field). 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.
  • Sign and submit the extrinsic (the Submit Transaction button)
  • -
    + \ No newline at end of file diff --git a/docs/participate/staking/advanced_collator_section/benchmarking/index.html b/docs/participate/staking/advanced_collator_section/benchmarking/index.html index 008ab881a..5c4ce599f 100644 --- a/docs/participate/staking/advanced_collator_section/benchmarking/index.html +++ b/docs/participate/staking/advanced_collator_section/benchmarking/index.html @@ -4,11 +4,11 @@ Benchmark Your Collator | KILT Protocol - - + + -

    Benchmark Your Collator

    To enable benchmarking, the collator must enable the benchmarking feature from a new build of the kilt-parachain.

    +

    Benchmark Your Collator

    To enable benchmarking, the collator must enable the benchmarking feature from a new build of the kilt-parachain.

    Don't use this binary for running the Collator!
    cargo build --release -p kilt-parachain --features=runtime-benchmarks

    The benchmarks can be run to compare the server's hardware capabilities against the referenced hardware. At the moment, we have benchmarked the Spiritnet and Peregrine runtimes on an AMD Ryzen 7 1700X with 64GB RAM and an NVMe SSD. @@ -16,6 +16,6 @@ Your weight results should at least be similar to the official ones and the lower yours are, the better.

    The commands executed to benchmark the KILT runtimes can be found in the official benchmark files for both Spiritnet and Peregrine.

    Below is an example of benchmarking for the the balances pallet.

    -
    ./target/release/kilt-parachain \
    benchmark \
    --chain=spiritnet-dev \
    --execution=wasm \
    --wasm-execution=Compiled \
    --heap-pages=4096 \
    --extrinsic=* \
    --pallet=pallet-balances \
    --steps=50 \
    --repeat=20 \
    --output \
    ./runtimes/spiritnet/src/weights/pallet_balances.rs \
    --template \
    ./.maintain/weight-template.hbs
    +
    ./target/release/kilt-parachain \
    benchmark \
    --chain=spiritnet-dev \
    --execution=wasm \
    --wasm-execution=Compiled \
    --heap-pages=4096 \
    --extrinsic=* \
    --pallet=pallet-balances \
    --steps=50 \
    --repeat=20 \
    --output \
    ./runtimes/spiritnet/src/weights/pallet_balances.rs \
    --template \
    ./.maintain/weight-template.hbs
    \ No newline at end of file diff --git a/docs/participate/staking/advanced_collator_section/bootnodes/index.html b/docs/participate/staking/advanced_collator_section/bootnodes/index.html index fa9038783..fa22eae72 100644 --- a/docs/participate/staking/advanced_collator_section/bootnodes/index.html +++ b/docs/participate/staking/advanced_collator_section/bootnodes/index.html @@ -4,13 +4,13 @@ Bootnodes | KILT Protocol - - + + -

    Bootnodes

    The bootnodes are required to connect to the peer-to-peer network and discover additional peers. +

    Bootnodes

    The bootnodes are required to connect to the peer-to-peer network and discover additional peers. The addresses are included in the chain spec, so there is no need to add them as a parameter to the start command. For the sake of completeness, the bootnodes are listed below:

    -

    For Spiritnet, the parachain bootnodes are:

    --bootnodes=/dns4/hetzner-1.kilt.io/tcp/30333/p2p/12D3KooWKU8ehzuKAzHEMCy4i4kpJtgCFBCYYhqcub4Y1HR8FRoT \
    --bootnodes=/dns4/hetzner-2.kilt.io/tcp/30333/p2p/12D3KooWDJzJ7TRNKvE2DWXMSSsoKR5TgxsnNy3W1eCBPveX6g9i \
    --bootnodes=/dns4/node-6840569230186737664-0.p2p.onfinality.io/tcp/11578/ws/p2p/12D3KooWQapPfoSDxLBnsVZmpRA1yNApXEAEuhexPcFa7fECqpHa \
    --bootnodes=/dns4/node-6840781141641752576-0.p2p.onfinality.io/tcp/28779/ws/p2p/12D3KooWKMCaxjsvaNkYkdQGnPQnkYFouHFdJ3S36aBhV6QTXzaE \
    --bootnodes=/dns4/node-6840781099853901824-0.p2p.onfinality.io/tcp/15360/ws/p2p/12D3KooWLWSE85c5PSsgo62Dy5UM68Sx8p3vnJvtvDVC8QHXFpR
    +

    For Spiritnet, the parachain bootnodes are:

    --bootnodes=/dns4/hetzner-1.kilt.io/tcp/30333/p2p/12D3KooWKU8ehzuKAzHEMCy4i4kpJtgCFBCYYhqcub4Y1HR8FRoT \
    --bootnodes=/dns4/hetzner-2.kilt.io/tcp/30333/p2p/12D3KooWDJzJ7TRNKvE2DWXMSSsoKR5TgxsnNy3W1eCBPveX6g9i \
    --bootnodes=/dns4/node-6840569230186737664-0.p2p.onfinality.io/tcp/11578/ws/p2p/12D3KooWQapPfoSDxLBnsVZmpRA1yNApXEAEuhexPcFa7fECqpHa \
    --bootnodes=/dns4/node-6840781141641752576-0.p2p.onfinality.io/tcp/28779/ws/p2p/12D3KooWKMCaxjsvaNkYkdQGnPQnkYFouHFdJ3S36aBhV6QTXzaE \
    --bootnodes=/dns4/node-6840781099853901824-0.p2p.onfinality.io/tcp/15360/ws/p2p/12D3KooWLWSE85c5PSsgo62Dy5UM68Sx8p3vnJvtvDVC8QHXFpR
    \ No newline at end of file diff --git a/docs/participate/staking/advanced_collator_section/exit/index.html b/docs/participate/staking/advanced_collator_section/exit/index.html index dd231286f..77c6f7520 100644 --- a/docs/participate/staking/advanced_collator_section/exit/index.html +++ b/docs/participate/staking/advanced_collator_section/exit/index.html @@ -4,11 +4,11 @@ Leave the Collator Candidate Pool | KILT Protocol - - + + -

    Leave the Collator Candidate Pool

    If you intend to stop collating or stop being a collator candidate, you have to go through three stages until your staked tokens are unlocked and your collator state is purged from the chain.

    +

    Leave the Collator Candidate Pool

    If you intend to stop collating or stop being a collator candidate, you have to go through three stages until your staked tokens are unlocked and your collator state is purged from the chain.

    info

    Unfortunately, exiting is not a simple process for security reasons. Since a picture paints a thousand words, you can find a visualization of this process in the following lifecycle section.

    Initiate the Exit Request

    @@ -56,6 +56,6 @@

    Canc

    Unlock Your Stake

    If you have executed the exit request you cannot immediately unlock your previously staked tokens. There is a delay of 7 days in block time before you can free them by calling unlockUnstaked. -See here for a step-by-step tutorial.

    +See here for a step-by-step tutorial.

    \ No newline at end of file diff --git a/docs/participate/staking/advanced_collator_section/lifecycle/index.html b/docs/participate/staking/advanced_collator_section/lifecycle/index.html index e3cb676b2..6dbd5416d 100644 --- a/docs/participate/staking/advanced_collator_section/lifecycle/index.html +++ b/docs/participate/staking/advanced_collator_section/lifecycle/index.html @@ -4,12 +4,12 @@ Lifecycle of a Collator | KILT Protocol - - + + -

    Lifecycle of a Collator

    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. +

    Lifecycle of a Collator

    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. It summarizes the previous exit section.

    -
    +
    \ No newline at end of file diff --git a/docs/participate/staking/advanced_collator_section/monitoring/index.html b/docs/participate/staking/advanced_collator_section/monitoring/index.html index 5431a57d9..1a83dc611 100644 --- a/docs/participate/staking/advanced_collator_section/monitoring/index.html +++ b/docs/participate/staking/advanced_collator_section/monitoring/index.html @@ -4,11 +4,11 @@ Set Up Node Monitoring | KILT Protocol - - + + -

    Set Up Node Monitoring

    It would be ideal if the host being monitored is not the host monitoring, i.e., if the monitoring process does not run on the same host as the collator process. +

    Set Up Node Monitoring

    It would be ideal if the host being monitored is not the host monitoring, i.e., if the monitoring process does not run on the same host as the collator process. However, in cases of limited resources, the two can also co-exist on the same host.

    The monitoring process collects two types of metrics: Node Exporter metrics and blockchain metrics. The monitoring infrastructure can either be run as a local grafana cluster or as a cloud-based solution.

    @@ -59,6 +59,6 @@

    +
    \ No newline at end of file diff --git a/docs/participate/staking/become_a_collator/hardware-requirements/index.html b/docs/participate/staking/become_a_collator/hardware-requirements/index.html index 8fea2d8b7..c55dc2ad2 100644 --- a/docs/participate/staking/become_a_collator/hardware-requirements/index.html +++ b/docs/participate/staking/become_a_collator/hardware-requirements/index.html @@ -4,11 +4,11 @@ Minimum Hardware Requirements | KILT Protocol - - + + -

    Minimum Hardware Requirements

    The KILT blockchain extrinsic weights were calculated using the following hardware:

    +

    Minimum Hardware Requirements

    The KILT blockchain extrinsic weights were calculated using the following hardware:

    • OS - Ubuntu 20.04.2
    • CPU - AMD Ryzen 7 1700X
    • @@ -17,6 +17,6 @@

    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. 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.

    -

    You can measure the performance of the new hardware by benchmarking it using the steps described in the benchmarking section.

    +

    You can measure the performance of the new hardware by benchmarking it using the steps described in the benchmarking section.

    \ No newline at end of file diff --git a/docs/participate/staking/become_a_collator/join/index.html b/docs/participate/staking/become_a_collator/join/index.html index fb33eea49..6a8db0be7 100644 --- a/docs/participate/staking/become_a_collator/join/index.html +++ b/docs/participate/staking/become_a_collator/join/index.html @@ -4,11 +4,11 @@ Join the Collator Candidate Pool | KILT Protocol - - + + -

    Join the Collator Candidate Pool

    Before a collator can author blocks, the node needs to fully sync up with both the KILT parachain and the Polkadot Relay Chain. +

    Join the Collator Candidate Pool

    Before a collator can author blocks, the node needs to fully sync up with both the KILT parachain and the Polkadot Relay Chain. Depending on the size of the blockchain states, it may take from a number of hours to few days for the node to fully synchronize. More details can be found on the Polkadot network docs.

    After you have finished with the setup, you can finally tell the chain that you are ready to collate and join the pool of candidates.

    @@ -48,6 +48,6 @@

    If a collator has enough self-stake and delegator stake it will be selected to collate. The last address in the list will be the least staked candidate. -A time period of two sessions must pass before the selected collator will be authoring blocks, e.g., after the remainder of the current session and the entire next one.

    +A time period of two sessions must pass before the selected collator will be authoring blocks, e.g., after the remainder of the current session and the entire next one.

    \ No newline at end of file diff --git a/docs/participate/staking/become_a_collator/overview/index.html b/docs/participate/staking/become_a_collator/overview/index.html index 5807689cf..e1a617303 100644 --- a/docs/participate/staking/become_a_collator/overview/index.html +++ b/docs/participate/staking/become_a_collator/overview/index.html @@ -4,11 +4,11 @@ Overview | KILT Protocol - - + + -

    Overview

    Collators are the most important members of the network as they not only maintain the state by running a KILT full node, but are also allowed to change it by building state transition proofs and sharing them with the Relay Chain validators. +

    Overview

    Collators are the most important members of the network as they not only maintain the state by running a KILT full node, but are also allowed to change it by building state transition proofs and sharing them with the Relay Chain validators. Generally speaking, the latter finalize the proposed block if and only if it represents a valid state transition.

    It is important to note that elusive collators can never get invalid blocks finalized thanks to the design security umbrella provided by the Relay Chain. Thus, the most harm dishonest collators can do is to slow down or halt the network. @@ -35,6 +35,6 @@

    Join the Moreover, the channels serve as a discussion hub for collators and delegators.

    After joining Discord, feel free to send a DM to Dudley | KILT protocol#6222 or William | KILT Protocol#4433 to introduce yourself. Of course, you can also directly announce yourself in one of the two channels mentioned above. -This way, the community knows who to contact in case there are any issues with your node.

    +This way, the community knows who to contact in case there are any issues with your node.

    \ No newline at end of file diff --git a/docs/participate/staking/become_a_collator/session-keys/index.html b/docs/participate/staking/become_a_collator/session-keys/index.html index 9b651c04a..98bc66c1f 100644 --- a/docs/participate/staking/become_a_collator/session-keys/index.html +++ b/docs/participate/staking/become_a_collator/session-keys/index.html @@ -4,11 +4,11 @@ Set and Rotate Session Keys | KILT Protocol - - + + -

    Set and Rotate Session Keys

    As a collator, you need to link your session keys to your collator account. +

    Set and Rotate Session Keys

    As a collator, you need to link your session keys to your collator account. Once linked, the keys are used to identify your collator node. Your collator address will receive the permit to build blocks, but the session keys pass this permit to your node. To check whether the account has already some session keys set, the RPC functions author > hasKey(publicKey, keyType) and author > hasSessionKeys(sessionKeys) can be called.

    @@ -47,6 +47,6 @@

    Gene

    Once the extrinsic is executed, you will have linked the new session key to your account and can start receiving rewards for producing new blocks. -However, the new session key does not become effective immediately but with the start of the next session.

    +However, the new session key does not become effective immediately but with the start of the next session.

    \ No newline at end of file diff --git a/docs/participate/staking/become_a_collator/setup-node/index.html b/docs/participate/staking/become_a_collator/setup-node/index.html index e24f5b0b1..f5910a490 100644 --- a/docs/participate/staking/become_a_collator/setup-node/index.html +++ b/docs/participate/staking/become_a_collator/setup-node/index.html @@ -4,11 +4,11 @@ Set Up a Node | KILT Protocol - - + + -

    Set Up a Node

    There are several ways to build and run a collator node. +

    Set Up a Node

    There are several ways to build and run a collator node. Here, we show both how to use a Docker image and how to compile the source code directly from our chain repository.

    There are currently two different runtimes (i.e., two different parachain environments) that a KILT collator can be part of:

      @@ -71,6 +71,6 @@

      Sy

      Before a collator can author blocks, the node needs to fully sync up with both the parachain and the Relay Chain. Depending on the size of the blockchain states, it may take a number of hours to few days for the node to catch up. More details can be found on the Polkadot network docs.

      -
      Example of node sync:
      2021-06-17 02:34:34 🔍 Discovered new external address for our node: /ip4/100.102.231.64/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
      2021-06-17 02:34:36 ⚙️ Syncing 409.2 bps, target=#8062689 (5 peers), best: #3477 (0x63ad…e046), finalized #3072 (0x0e4c…f587), ⬇ 153.2kiB/s ⬆ 12.9kiB/s
      2021-06-17 02:34:37 🔍 Discovered new external address for our node: /ip4/100.111.175.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
      2021-06-17 02:34:38 🔍 Discovered new external address for our node: /ip4/100.100.176.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
      2021-06-17 02:34:41 ⚙️ Syncing 386.2 bps, target=#8062690 (7 peers), best: #5409 (0x1d76…8c3d), finalized #5121 (0x8ad1…b6dc), ⬇ 96.1kiB/s ⬆ 10.9kiB/s
      2021-06-17 02:34:46 ⚙️ Syncing 394.8 bps, target=#8062691 (11 peers), best: #7383 (0x0689…6f1e), finalized #7168 (0x72a9…8d8c), ⬇ 352.9kiB/s ⬆ 5.1kiB/s
      2021-06-17 02:34:51 ⚙️ Syncing 347.0 bps, target=#8062692 (12 peers), best: #9118 (0x66fc…cce3), finalized #8704 (0x14c9…705e), ⬇ 62.7kiB/s ⬆ 1.7kiB/s

    +
    Example of node sync:
    2021-06-17 02:34:34 🔍 Discovered new external address for our node: /ip4/100.102.231.64/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:36 ⚙️ Syncing 409.2 bps, target=#8062689 (5 peers), best: #3477 (0x63ad…e046), finalized #3072 (0x0e4c…f587), ⬇ 153.2kiB/s ⬆ 12.9kiB/s
    2021-06-17 02:34:37 🔍 Discovered new external address for our node: /ip4/100.111.175.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:38 🔍 Discovered new external address for our node: /ip4/100.100.176.0/tcp/30333/ws/p2p/12D3KooWLE7ivpuXJQpFVP4fuuutAqEsk8nrNEpuR3tddqnXgLPB
    2021-06-17 02:34:41 ⚙️ Syncing 386.2 bps, target=#8062690 (7 peers), best: #5409 (0x1d76…8c3d), finalized #5121 (0x8ad1…b6dc), ⬇ 96.1kiB/s ⬆ 10.9kiB/s
    2021-06-17 02:34:46 ⚙️ Syncing 394.8 bps, target=#8062691 (11 peers), best: #7383 (0x0689…6f1e), finalized #7168 (0x72a9…8d8c), ⬇ 352.9kiB/s ⬆ 5.1kiB/s
    2021-06-17 02:34:51 ⚙️ Syncing 347.0 bps, target=#8062692 (12 peers), best: #9118 (0x66fc…cce3), finalized #8704 (0x14c9…705e), ⬇ 62.7kiB/s ⬆ 1.7kiB/s
    \ No newline at end of file diff --git a/docs/participate/staking/claim-rewards/index.html b/docs/participate/staking/claim-rewards/index.html index c47b5a5ac..5eb281681 100644 --- a/docs/participate/staking/claim-rewards/index.html +++ b/docs/participate/staking/claim-rewards/index.html @@ -4,11 +4,11 @@ Claim Staking Rewards | KILT Protocol - - + + -

    Claim Staking Rewards

    Until runtime version 1.7.5 (spiritnet-10750), staking rewards were automatically minted. +

    Claim Staking Rewards

    Until runtime version 1.7.5 (spiritnet-10750), staking rewards were automatically minted. In 1.8.0 (spiritnet-10801) this will change: Hereafter, the rewards are still accounted to the collators and their delegators in each block. However, they need to be actively claimed by calling an extrinsic, similar to the pull-based approach on Polkadot. @@ -67,6 +67,6 @@

    How to claimSelect the reward increment extrinsic: parachainStaking -> incrementDelegatorRewards()
  • Press the + button and add the reward claiming extrinsic: parachainStaking -> claimRewards()
  • Sign and submit the extrinsic (the Submit Transaction button)
  • -

    +

    \ No newline at end of file diff --git a/docs/participate/staking/delegate/adjust-stake/index.html b/docs/participate/staking/delegate/adjust-stake/index.html index 3bf9e745c..cd071b8a7 100644 --- a/docs/participate/staking/delegate/adjust-stake/index.html +++ b/docs/participate/staking/delegate/adjust-stake/index.html @@ -4,11 +4,11 @@ Adjust Your Delegation Stake | KILT Protocol - - + + -

    Adjust Your Delegation Stake

    A delegator can increase and decrease their stake by calling either parachainStaking -> delegatorStakeMore(more) or parachainStaking -> delegatorStakeLess(less). +

    Adjust Your Delegation Stake

    A delegator can increase and decrease their stake by calling either parachainStaking -> delegatorStakeMore(more) or parachainStaking -> delegatorStakeLess(less). Your adjustment becomes effective immediately! If you increase your stake, you will instantly receive higher rewards for any blocks produced by your collator; if you decreased your delegation amount, the reverse applies and you receive less rewards.

    info

    You can either execute this transaction in Polkadot JS Apps or the KILT Stakeboard, which serves as an in-house developed Frontend for all KILT staking activity. @@ -33,6 +33,6 @@

  • Sign and submit the extrinsic (the Submit Transaction button)
  • caution

    You cannot adjust your stake if your Collator candidate is in the leaving state, e.g., they want to stop collating. -However, you can still remove your delegation.

    +However, you can still remove your delegation.

    \ No newline at end of file diff --git a/docs/participate/staking/delegate/exit/index.html b/docs/participate/staking/delegate/exit/index.html index de3134fd4..f72028347 100644 --- a/docs/participate/staking/delegate/exit/index.html +++ b/docs/participate/staking/delegate/exit/index.html @@ -4,11 +4,11 @@ Leave the Set of Delegators | KILT Protocol - - + + -

    Leave the Set of Delegators

    A Delegator can revoke their delegation by calling parachainStaking -> leaveDelegators. +

    Leave the Set of Delegators

    A Delegator can revoke their delegation by calling parachainStaking -> leaveDelegators. As a result, you won't receive any rewards immediately after the transaction is successfully executed.

    • Your previously delegated amount will be prepared for unstaking.
    • @@ -24,6 +24,6 @@
    • Select the KILT address you delegated from as the extrinsic submitter (the using the selected account field)
    • Select the appropriate extrinsic: parachainStaking -> leaveDelegators.
    • Sign and submit the extrinsic (the Submit Transaction button)
    • -
    +
    \ No newline at end of file diff --git a/docs/participate/staking/delegate/join/index.html b/docs/participate/staking/delegate/join/index.html index 32f061690..c855ed73e 100644 --- a/docs/participate/staking/delegate/join/index.html +++ b/docs/participate/staking/delegate/join/index.html @@ -4,11 +4,11 @@ Become a Delegator | KILT Protocol - - + + -

    Become a Delegator

    In contrast to the rather difficult path to become a collator candidate, joining the delegator pool is rather simple. +

    Become a Delegator

    In contrast to the rather difficult path to become a collator candidate, joining the delegator pool is rather simple. Anyone can delegate to a collator candidate by staking a minimum of 20 KILT and calling parachainStaking -> joinDelegators.

    info

    You can either execute this transaction in Polkadot JS Apps or the KILT Stakeboard, which serves as an in-house developed Frontend for all KILT staking activity. Below, we outline the steps for Polkadot JS Apps. @@ -42,6 +42,6 @@

    Unhappy Path
    info

    For now, an account can only delegate to one collator at any time! -Moreover, you can only (re-) delegate, e.g., call parachainStaking -> {joinDelegators, delegateAnotherCandidate}, once per staking round.

    +Moreover, you can only (re-) delegate, e.g., call parachainStaking -> {joinDelegators, delegateAnotherCandidate}, once per staking round.

    \ No newline at end of file diff --git a/docs/participate/staking/delegate/lifecycle/index.html b/docs/participate/staking/delegate/lifecycle/index.html index f19b58e5a..213b42313 100644 --- a/docs/participate/staking/delegate/lifecycle/index.html +++ b/docs/participate/staking/delegate/lifecycle/index.html @@ -4,12 +4,12 @@ Lifecycle of a Delegator | KILT Protocol - - + + -

    Lifecycle of a Delegator

    The following diagram depicts the full lifecycle of a delegator from owning free KILT to delegating, losing a delegation seat, re-delegating and finally unlocking their stake.

    +

    Lifecycle of a Delegator

    The following diagram depicts the full lifecycle of a delegator from owning free KILT to delegating, losing a delegation seat, re-delegating and finally unlocking their stake.

    It provides a summary of the detailed information provided in the preceding sections.

    -
    +
    \ No newline at end of file diff --git a/docs/participate/staking/delegate/overview/index.html b/docs/participate/staking/delegate/overview/index.html index 91d19522a..15261f24f 100644 --- a/docs/participate/staking/delegate/overview/index.html +++ b/docs/participate/staking/delegate/overview/index.html @@ -4,16 +4,16 @@ Overview | KILT Protocol - - + + -

    Overview

    In the KILT Limited Delegated Proof of Stake (LDPoS) 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.

    +

    Overview

    In the KILT Limited Delegated Proof of Stake (LDPoS) 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.

    The requirements to become a delegator are much less than those for collators. You only need to stake a relatively low number of tokens and decide on a collator candidate. 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.

    The following sections will guide you through the process of becoming a delegator, adjusting your stake, revoking a delegation and unstaking your tokens.

    info

    The amount of delegators per collator is limited. -Currently, each delegator can only stake to one collator per account; this may change if the community decides to enable multiple delegations per account.

    +Currently, each delegator can only stake to one collator per account; this may change if the community decides to enable multiple delegations per account.

    \ No newline at end of file diff --git a/docs/participate/staking/troubleshooting/index.html b/docs/participate/staking/troubleshooting/index.html index 0a74609b1..73743c642 100644 --- a/docs/participate/staking/troubleshooting/index.html +++ b/docs/participate/staking/troubleshooting/index.html @@ -4,11 +4,11 @@ Troubleshooting | KILT Protocol - - + + -

    Troubleshooting

    There are a few things that can be checked to make sure everything is set up correctly.

    If the collator's account is shown next to some of the blocks on any network explorer, e.g., the one offered by PolkadotJS Apps, then the collator is correctly producing blocks and getting rewarded for it. +

    Troubleshooting

    There are a few things that can be checked to make sure everything is set up correctly.

    If the collator's account is shown next to some of the blocks on any network explorer, e.g., the one offered by PolkadotJS Apps, then the collator is correctly producing blocks and getting rewarded for it. If the logs print the message that starts with a 🎁 emoji, it indicates that the collator setup is correct but that the blocks produced are not included by the Relay Chain. This typically signals some issues about the node hardware or connectivity. If not, it might be that the node does not produce and send blocks fast enough. @@ -44,6 +44,6 @@

    Why Can't I Transfer Unstaked Tokens?

    Staking puts a lock on your tokens which blocks them from being transferred. You can still use them for participating in Governance. -If your funds are unstaked, you still need to wait 7 days (in block time) to unlock tokens after unstaking them.

    +If your funds are unstaked, you still need to wait 7 days (in block time) to unlock tokens after unstaking them.

    \ No newline at end of file diff --git a/docs/participate/staking/unlock-unstaked/index.html b/docs/participate/staking/unlock-unstaked/index.html index 9dd276bc6..542562f8a 100644 --- a/docs/participate/staking/unlock-unstaked/index.html +++ b/docs/participate/staking/unlock-unstaked/index.html @@ -4,11 +4,11 @@ Unlock Unstaked Tokens | KILT Protocol - - + + -

    Unlock Unstaked Tokens

    Before you can unlock your previously staked tokens, you have to wait 7 days (in block time).

    +

    Unlock Unstaked Tokens

    Before you can unlock your previously staked tokens, you have to wait 7 days (in block time).

    info

    You can either execute this transaction in Polkadot JS Apps or the KILT Stakeboard, which serves as an in-house developed Frontend for all KILT staking activity. Below, we outline the steps for Polkadot JS Apps. The process for KILT Stakeboard is described in detail in the BOTLabs Trusted Entity support hub.

    @@ -30,6 +30,6 @@ This can happen if either of the following events occurred

    • You were kicked out of your collator candidate's delegation pool because all current delegators have a higher stake
    • Your collator candidate intentionally left the collator pool.
    • -
    + \ No newline at end of file diff --git a/docs/participate/treasury-proposal/index.html b/docs/participate/treasury-proposal/index.html index b365fc54b..e815086a6 100644 --- a/docs/participate/treasury-proposal/index.html +++ b/docs/participate/treasury-proposal/index.html @@ -4,11 +4,11 @@ Open a Treasury Proposal | KILT Protocol - - + + -

    Open a Treasury Proposal

    Complete these steps to create a well-formed Treasury proposal.

    +

    Open a Treasury Proposal

    Complete these steps to create a well-formed Treasury proposal.

    Discuss

    The first step in applying for a Treasury grant is either to join the community in the Discord Treasury Channel to brainstorm the scope of your proposal intention or immediately open a discussion on Polkassembly. This will help you get valuable community feedback throughout the process. @@ -91,6 +91,6 @@

    Polkass

    Illustration

    The following diagram depicts the flow of a Treasury proposal from having an idea to receiving the funds in the beneficiary address. While all nodes with yellow background represent off-chain processes, the remaining ones involve on-chain activity.

    -
    +
    \ No newline at end of file diff --git a/docs/participate/treasury-tip/index.html b/docs/participate/treasury-tip/index.html index cc89a4b60..896760175 100644 --- a/docs/participate/treasury-tip/index.html +++ b/docs/participate/treasury-tip/index.html @@ -4,11 +4,11 @@ Treasury Tips | KILT Protocol - - + + -

    Treasury Tips

    Similar to opening a Treasury proposal, anyone can start a tipping process.

    +

    Treasury Tips

    Similar to opening a Treasury proposal, anyone can start a tipping process.

    You can expect success if the tip is based on a meaningful contribution. The variety of potential contributions is vast, read the KILT Contribution guide for a high level description of tips and the differences to Treasury proposals.

    This document covers the necessary steps from requesting a tip to receiving it.

    @@ -37,6 +37,6 @@

    Proposing a
  • Provide the address to receive the tip in the beneficiary field
  • Provide a reason in the tip reason field. This can either be some descriptive words or a URL. The tip reason field should point to the contribution(s), e.g., the GitHub pull request, blog posts, translations or videos among other things. The tipping process will fail if the reason is not recognizable.
  • Sign and submit the extrinsic with the Propose tip button
  • -

    +
    \ No newline at end of file diff --git a/index.html b/index.html index de5fd5d5b..6c524461d 100644 --- a/index.html +++ b/index.html @@ -4,10 +4,10 @@ Docs | KILT Protocol - - + + - + \ No newline at end of file diff --git a/search/index.html b/search/index.html index d2122a2a8..090c53763 100644 --- a/search/index.html +++ b/search/index.html @@ -4,10 +4,10 @@ Search the documentation | KILT Protocol - - + + - + \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index fa851d78c..cc6a201a0 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://docs.kilt.io/searchweekly0.5https://docs.kilt.io/docs/concepts/advanced_concepts/nested-ctypesweekly0.5https://docs.kilt.io/docs/concepts/advanced_concepts/terms-and-quotesweekly0.5https://docs.kilt.io/docs/concepts/asset-didsweekly0.5https://docs.kilt.io/docs/concepts/credentials/attestationweekly0.5https://docs.kilt.io/docs/concepts/credentials/claimingweekly0.5https://docs.kilt.io/docs/concepts/credentials/ctypesweekly0.5https://docs.kilt.io/docs/concepts/credentials/overviewweekly0.5https://docs.kilt.io/docs/concepts/credentials/public-credentialsweekly0.5https://docs.kilt.io/docs/concepts/credentials/verificationweekly0.5https://docs.kilt.io/docs/concepts/didweekly0.5https://docs.kilt.io/docs/concepts/dip/consumerweekly0.5https://docs.kilt.io/docs/concepts/dip/dapp-developerweekly0.5https://docs.kilt.io/docs/concepts/dip/dip-accounts-kiltweekly0.5https://docs.kilt.io/docs/concepts/dip/providerweekly0.5https://docs.kilt.io/docs/concepts/dip/what-is-dipweekly0.5https://docs.kilt.io/docs/concepts/distributed_trustweekly0.5https://docs.kilt.io/docs/concepts/glossaryweekly0.5https://docs.kilt.io/docs/concepts/messagingweekly0.5https://docs.kilt.io/docs/concepts/web3namesweekly0.5https://docs.kilt.io/docs/concepts/what-is-kiltweekly0.5https://docs.kilt.io/docs/develop/builtonkiltweekly0.5https://docs.kilt.io/docs/develop/chain/deploymentsweekly0.5https://docs.kilt.io/docs/develop/chain/fullnode-setupweekly0.5https://docs.kilt.io/docs/develop/chain/introductionweekly0.5https://docs.kilt.io/docs/develop/chain/pallets/pallet-didweekly0.5https://docs.kilt.io/docs/develop/contributeweekly0.5https://docs.kilt.io/docs/develop/dApp/dapp-verifierweekly0.5https://docs.kilt.io/docs/develop/dApp/sessionweekly0.5https://docs.kilt.io/docs/develop/dApp/welcomeweekly0.5https://docs.kilt.io/docs/develop/dApp/well-known-did-configweekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/weekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/peregrine-chain-setupweekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/prod-chain-setupweekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/standalone-chain-setupweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/account_linking/account-linkweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/account_linking/account-nameweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/account_linking/account-unlinkweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/attestation-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/attestation-removalweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/attestation-requestweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/ctype-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/presentation-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/presentation-verificationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/did-exportweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/did-queryweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/did-signatureweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-batchweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-deleteweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-updateweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/key-generationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/light-did-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/messaging/messaging_bookweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/messaging/replay_protectionweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/public_credentials/public-credential-issuanceweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/public_credentials/public-credential-retrievalweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/public_credentials/public-credential-revocationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/signCallbackweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/upgrading_to_v0_29/weekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibilityweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/credential-queryweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/web3name-claimweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/web3name-queryweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/web3name-releaseweekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/weekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/howto-integrate-browserweekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/howto-integrate-distilleryweekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/howto-integrate-nodejsweekly0.5https://docs.kilt.io/docs/develop/sdk/quickstartweekly0.5https://docs.kilt.io/docs/develop/sdk/troubleshoot-sdkweekly0.5https://docs.kilt.io/docs/develop/specificationsweekly0.5https://docs.kilt.io/docs/develop/workshop/attestationweekly0.5https://docs.kilt.io/docs/develop/workshop/attester/weekly0.5https://docs.kilt.io/docs/develop/workshop/attester/accountweekly0.5https://docs.kilt.io/docs/develop/workshop/attester/ctypeweekly0.5https://docs.kilt.io/docs/develop/workshop/attester/didweekly0.5https://docs.kilt.io/docs/develop/workshop/claimer/weekly0.5https://docs.kilt.io/docs/develop/workshop/claimer/didweekly0.5https://docs.kilt.io/docs/develop/workshop/claimer/requestweekly0.5https://docs.kilt.io/docs/develop/workshop/doneweekly0.5https://docs.kilt.io/docs/develop/workshop/overviewweekly0.5https://docs.kilt.io/docs/develop/workshop/setupweekly0.5https://docs.kilt.io/docs/develop/workshop/verificationweekly0.5https://docs.kilt.io/docs/develop/workshop/welcomeweekly0.5https://docs.kilt.io/docs/participate/content-creation-guidelinesweekly0.5https://docs.kilt.io/docs/participate/governance/remove_voteweekly0.5https://docs.kilt.io/docs/participate/governance/unlock_coinsweekly0.5https://docs.kilt.io/docs/participate/governance/voteweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/adjust-stakeweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/benchmarkingweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/bootnodesweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/exitweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/lifecycleweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/monitoringweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/hardware-requirementsweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/joinweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/overviewweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/session-keysweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/setup-nodeweekly0.5https://docs.kilt.io/docs/participate/staking/claim-rewardsweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/adjust-stakeweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/exitweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/joinweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/lifecycleweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/overviewweekly0.5https://docs.kilt.io/docs/participate/staking/troubleshootingweekly0.5https://docs.kilt.io/docs/participate/staking/unlock-unstakedweekly0.5https://docs.kilt.io/docs/participate/treasury-proposalweekly0.5https://docs.kilt.io/docs/participate/treasury-tipweekly0.5https://docs.kilt.io/weekly0.5 \ No newline at end of file +https://docs.kilt.io/searchweekly0.5https://docs.kilt.io/docs/concepts/advanced_concepts/nested-ctypesweekly0.5https://docs.kilt.io/docs/concepts/advanced_concepts/terms-and-quotesweekly0.5https://docs.kilt.io/docs/concepts/asset-didsweekly0.5https://docs.kilt.io/docs/concepts/credentials/attestationweekly0.5https://docs.kilt.io/docs/concepts/credentials/claimingweekly0.5https://docs.kilt.io/docs/concepts/credentials/ctypesweekly0.5https://docs.kilt.io/docs/concepts/credentials/overviewweekly0.5https://docs.kilt.io/docs/concepts/credentials/public-credentialsweekly0.5https://docs.kilt.io/docs/concepts/credentials/verificationweekly0.5https://docs.kilt.io/docs/concepts/didweekly0.5https://docs.kilt.io/docs/concepts/dip/consumerweekly0.5https://docs.kilt.io/docs/concepts/dip/dapp-developerweekly0.5https://docs.kilt.io/docs/concepts/dip/dip-accounts-kiltweekly0.5https://docs.kilt.io/docs/concepts/dip/providerweekly0.5https://docs.kilt.io/docs/concepts/dip/what-is-dipweekly0.5https://docs.kilt.io/docs/concepts/distributed_trustweekly0.5https://docs.kilt.io/docs/concepts/glossaryweekly0.5https://docs.kilt.io/docs/concepts/messagingweekly0.5https://docs.kilt.io/docs/concepts/web3namesweekly0.5https://docs.kilt.io/docs/concepts/what-is-kiltweekly0.5https://docs.kilt.io/docs/develop/builtonkiltweekly0.5https://docs.kilt.io/docs/develop/chain/deploymentsweekly0.5https://docs.kilt.io/docs/develop/chain/fullnode-setupweekly0.5https://docs.kilt.io/docs/develop/chain/introductionweekly0.5https://docs.kilt.io/docs/develop/chain/pallets/pallet-didweekly0.5https://docs.kilt.io/docs/develop/contributeweekly0.5https://docs.kilt.io/docs/develop/dApp/dapp-verifierweekly0.5https://docs.kilt.io/docs/develop/dApp/sessionweekly0.5https://docs.kilt.io/docs/develop/dApp/welcomeweekly0.5https://docs.kilt.io/docs/develop/dApp/well-known-did-configweekly0.5https://docs.kilt.io/docs/develop/opendid/advancedweekly0.5https://docs.kilt.io/docs/develop/opendid/demo_projectweekly0.5https://docs.kilt.io/docs/develop/opendid/flowweekly0.5https://docs.kilt.io/docs/develop/opendid/integrate_opendidweekly0.5https://docs.kilt.io/docs/develop/opendid/opendid_serviceweekly0.5https://docs.kilt.io/docs/develop/opendid/what-is-opendidweekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/weekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/peregrine-chain-setupweekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/prod-chain-setupweekly0.5https://docs.kilt.io/docs/develop/sdk/chain_setup/standalone-chain-setupweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/account_linking/account-linkweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/account_linking/account-nameweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/account_linking/account-unlinkweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/attestation-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/attestation-removalweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/attestation-requestweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/ctype-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/presentation-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/claiming/presentation-verificationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/did-exportweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/did-queryweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/did-signatureweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-batchweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-deleteweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/full-did-updateweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/key-generationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/dids/light-did-creationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/messaging/messaging_bookweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/messaging/replay_protectionweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/public_credentials/public-credential-issuanceweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/public_credentials/public-credential-retrievalweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/public_credentials/public-credential-revocationweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/signCallbackweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/upgrading_to_v0_29/weekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/upgrading_to_v0_29/v29-backward-compatibilityweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/credential-queryweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/web3name-claimweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/web3name-queryweekly0.5https://docs.kilt.io/docs/develop/sdk/cookbook/web3names/web3name-releaseweekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/weekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/howto-integrate-browserweekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/howto-integrate-distilleryweekly0.5https://docs.kilt.io/docs/develop/sdk/integrate/howto-integrate-nodejsweekly0.5https://docs.kilt.io/docs/develop/sdk/quickstartweekly0.5https://docs.kilt.io/docs/develop/sdk/troubleshoot-sdkweekly0.5https://docs.kilt.io/docs/develop/specificationsweekly0.5https://docs.kilt.io/docs/develop/workshop/attestationweekly0.5https://docs.kilt.io/docs/develop/workshop/attester/weekly0.5https://docs.kilt.io/docs/develop/workshop/attester/accountweekly0.5https://docs.kilt.io/docs/develop/workshop/attester/ctypeweekly0.5https://docs.kilt.io/docs/develop/workshop/attester/didweekly0.5https://docs.kilt.io/docs/develop/workshop/claimer/weekly0.5https://docs.kilt.io/docs/develop/workshop/claimer/didweekly0.5https://docs.kilt.io/docs/develop/workshop/claimer/requestweekly0.5https://docs.kilt.io/docs/develop/workshop/doneweekly0.5https://docs.kilt.io/docs/develop/workshop/overviewweekly0.5https://docs.kilt.io/docs/develop/workshop/setupweekly0.5https://docs.kilt.io/docs/develop/workshop/verificationweekly0.5https://docs.kilt.io/docs/develop/workshop/welcomeweekly0.5https://docs.kilt.io/docs/participate/content-creation-guidelinesweekly0.5https://docs.kilt.io/docs/participate/governance/remove_voteweekly0.5https://docs.kilt.io/docs/participate/governance/unlock_coinsweekly0.5https://docs.kilt.io/docs/participate/governance/voteweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/adjust-stakeweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/benchmarkingweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/bootnodesweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/exitweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/lifecycleweekly0.5https://docs.kilt.io/docs/participate/staking/advanced_collator_section/monitoringweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/hardware-requirementsweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/joinweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/overviewweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/session-keysweekly0.5https://docs.kilt.io/docs/participate/staking/become_a_collator/setup-nodeweekly0.5https://docs.kilt.io/docs/participate/staking/claim-rewardsweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/adjust-stakeweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/exitweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/joinweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/lifecycleweekly0.5https://docs.kilt.io/docs/participate/staking/delegate/overviewweekly0.5https://docs.kilt.io/docs/participate/staking/troubleshootingweekly0.5https://docs.kilt.io/docs/participate/staking/unlock-unstakedweekly0.5https://docs.kilt.io/docs/participate/treasury-proposalweekly0.5https://docs.kilt.io/docs/participate/treasury-tipweekly0.5https://docs.kilt.io/weekly0.5 \ No newline at end of file